fix: activate E2E and accept room invites in Matrix channels
This commit is contained in:
@@ -1,10 +1,11 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from nio import AsyncClient, MatrixRoom, RoomMessageText
|
from nio import AsyncClient, AsyncClientConfig, InviteEvent, MatrixRoom, RoomMessageText
|
||||||
|
|
||||||
from nanobot.channels.base import BaseChannel
|
|
||||||
from nanobot.bus.events import OutboundMessage
|
from nanobot.bus.events import OutboundMessage
|
||||||
|
from nanobot.channels.base import BaseChannel
|
||||||
|
from nanobot.config.loader import get_data_dir
|
||||||
|
|
||||||
|
|
||||||
class MatrixChannel(BaseChannel):
|
class MatrixChannel(BaseChannel):
|
||||||
@@ -22,18 +23,28 @@ class MatrixChannel(BaseChannel):
|
|||||||
async def start(self) -> None:
|
async def start(self) -> None:
|
||||||
self._running = True
|
self._running = True
|
||||||
|
|
||||||
|
store_path = get_data_dir() / "matrix-store"
|
||||||
|
store_path.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
self.client = AsyncClient(
|
self.client = AsyncClient(
|
||||||
homeserver=self.config.homeserver,
|
homeserver=self.config.homeserver,
|
||||||
user=self.config.user_id,
|
user=self.config.user_id,
|
||||||
)
|
store_path=store_path, # Where tokens are saved
|
||||||
|
config=AsyncClientConfig(
|
||||||
self.client.access_token = self.config.access_token
|
store_sync_tokens=True, # Auto-persists next_batch tokens
|
||||||
|
encryption_enabled=True,
|
||||||
self.client.add_event_callback(
|
),
|
||||||
self._on_message,
|
|
||||||
RoomMessageText
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.client.user_id = self.config.user_id
|
||||||
|
self.client.access_token = self.config.access_token
|
||||||
|
self.client.device_id = self.config.device_id
|
||||||
|
|
||||||
|
self.client.add_event_callback(self._on_message, RoomMessageText)
|
||||||
|
self.client.add_event_callback(self._on_room_invite, InviteEvent)
|
||||||
|
|
||||||
|
self.client.load_store()
|
||||||
|
|
||||||
self._sync_task = asyncio.create_task(self._sync_loop())
|
self._sync_task = asyncio.create_task(self._sync_loop())
|
||||||
|
|
||||||
async def stop(self) -> None:
|
async def stop(self) -> None:
|
||||||
@@ -51,22 +62,23 @@ class MatrixChannel(BaseChannel):
|
|||||||
room_id=msg.chat_id,
|
room_id=msg.chat_id,
|
||||||
message_type="m.room.message",
|
message_type="m.room.message",
|
||||||
content={"msgtype": "m.text", "body": msg.content},
|
content={"msgtype": "m.text", "body": msg.content},
|
||||||
|
ignore_unverified_devices=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def _sync_loop(self) -> None:
|
async def _sync_loop(self) -> None:
|
||||||
while self._running:
|
while self._running:
|
||||||
try:
|
try:
|
||||||
await self.client.sync(timeout=30000)
|
await self.client.sync_forever(timeout=30000, full_state=True)
|
||||||
except asyncio.CancelledError:
|
except asyncio.CancelledError:
|
||||||
break
|
break
|
||||||
except Exception:
|
except Exception:
|
||||||
await asyncio.sleep(2)
|
await asyncio.sleep(2)
|
||||||
|
|
||||||
async def _on_message(
|
async def _on_room_invite(self, room: MatrixRoom, event: RoomMessageText) -> None:
|
||||||
self,
|
if event.sender in self.config.allow_from:
|
||||||
room: MatrixRoom,
|
await self.client.join(room.room_id)
|
||||||
event: RoomMessageText
|
|
||||||
) -> None:
|
async def _on_message(self, room: MatrixRoom, event: RoomMessageText) -> None:
|
||||||
# Ignore self messages
|
# Ignore self messages
|
||||||
if event.sender == self.config.user_id:
|
if event.sender == self.config.user_id:
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -60,6 +60,17 @@ class DiscordConfig(Base):
|
|||||||
intents: int = 37377 # GUILDS + GUILD_MESSAGES + DIRECT_MESSAGES + MESSAGE_CONTENT
|
intents: int = 37377 # GUILDS + GUILD_MESSAGES + DIRECT_MESSAGES + MESSAGE_CONTENT
|
||||||
|
|
||||||
|
|
||||||
|
class MatrixConfig(Base):
|
||||||
|
"""Matrix (Element) channel configuration."""
|
||||||
|
|
||||||
|
enabled: bool = False
|
||||||
|
homeserver: str = "https://matrix.org"
|
||||||
|
access_token: str = ""
|
||||||
|
user_id: str = "" # @bot:matrix.org
|
||||||
|
device_id: str = ""
|
||||||
|
allow_from: list[str] = Field(default_factory=list)
|
||||||
|
|
||||||
|
|
||||||
class EmailConfig(Base):
|
class EmailConfig(Base):
|
||||||
"""Email channel configuration (IMAP inbound + SMTP outbound)."""
|
"""Email channel configuration (IMAP inbound + SMTP outbound)."""
|
||||||
|
|
||||||
@@ -176,6 +187,7 @@ class ChannelsConfig(Base):
|
|||||||
email: EmailConfig = Field(default_factory=EmailConfig)
|
email: EmailConfig = Field(default_factory=EmailConfig)
|
||||||
slack: SlackConfig = Field(default_factory=SlackConfig)
|
slack: SlackConfig = Field(default_factory=SlackConfig)
|
||||||
qq: QQConfig = Field(default_factory=QQConfig)
|
qq: QQConfig = Field(default_factory=QQConfig)
|
||||||
|
matrix: MatrixConfig = Field(default_factory=MatrixConfig)
|
||||||
|
|
||||||
|
|
||||||
class AgentDefaults(Base):
|
class AgentDefaults(Base):
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ dependencies = [
|
|||||||
"prompt-toolkit>=3.0.50,<4.0.0",
|
"prompt-toolkit>=3.0.50,<4.0.0",
|
||||||
"mcp>=1.26.0,<2.0.0",
|
"mcp>=1.26.0,<2.0.0",
|
||||||
"json-repair>=0.57.0,<1.0.0",
|
"json-repair>=0.57.0,<1.0.0",
|
||||||
|
"matrix-nio[e2e]>=0.25.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.optional-dependencies]
|
[project.optional-dependencies]
|
||||||
|
|||||||
Reference in New Issue
Block a user