fix: activate E2E and accept room invites in Matrix channels

This commit is contained in:
djmaze
2026-02-10 02:01:15 +01:00
committed by Alexander Minges
parent 0d3dc57a65
commit d3ddeb3067
3 changed files with 43 additions and 18 deletions

View File

@@ -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,17 +23,27 @@ 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(
store_sync_tokens=True, # Auto-persists next_batch tokens
encryption_enabled=True,
),
) )
self.client.user_id = self.config.user_id
self.client.access_token = self.config.access_token self.client.access_token = self.config.access_token
self.client.device_id = self.config.device_id
self.client.add_event_callback( self.client.add_event_callback(self._on_message, RoomMessageText)
self._on_message, self.client.add_event_callback(self._on_room_invite, InviteEvent)
RoomMessageText
) self.client.load_store()
self._sync_task = asyncio.create_task(self._sync_loop()) self._sync_task = asyncio.create_task(self._sync_loop())
@@ -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

View File

@@ -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):

View File

@@ -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]