From 70b0b8929040b02b32372a2479831eb2358ec11c Mon Sep 17 00:00:00 2001 From: Christian Gick Date: Tue, 24 Mar 2026 09:38:32 +0200 Subject: [PATCH] fix: use actual nio device_id in call.member events, not hardcoded AIBOT Element X sends E2EE keys via encrypted to-device messages targeting the device_id from the call.member state event. Bot was advertising device_id='AIBOT' but its actual Matrix session is on device 'PEYRKFEXFP'. Keys were sent to a non-existent device. Now uses the real device_id from nio credentials so Element X's encryptAndSendToDevice reaches the correct device. Co-Authored-By: Claude Opus 4.6 (1M context) --- bot.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/bot.py b/bot.py index 5f645ff..f92be70 100644 --- a/bot.py +++ b/bot.py @@ -49,7 +49,7 @@ from cron import CronScheduler from device_trust import CrossSignedOnlyPolicy from cross_signing import CrossSigningManager -BOT_DEVICE_ID = "AIBOT" +BOT_DEVICE_ID = os.environ.get("BOT_DEVICE_ID", "AIBOT") # Overridden at login with actual nio device_id CALL_MEMBER_TYPE = "org.matrix.msc3401.call.member" ENCRYPTION_KEYS_TYPE = "io.element.call.encryption_keys" @@ -1314,6 +1314,9 @@ class Bot: ) self.client.load_store() logger.info("Restored session as %s (device %s)", creds["user_id"], creds["device_id"]) + # Use actual device ID for call.member events so to-device keys arrive correctly + global BOT_DEVICE_ID + BOT_DEVICE_ID = creds["device_id"] else: resp = await self.client.login(BOT_PASS, device_name="ai-voice-bot") if not isinstance(resp, LoginResponse): @@ -1327,6 +1330,8 @@ class Bot: "access_token": resp.access_token, }, f) logger.info("Logged in as %s (device %s) — credentials saved", resp.user_id, resp.device_id) + # Use actual device ID for call.member events + BOT_DEVICE_ID = resp.device_id if self.client.should_upload_keys: await self.client.keys_upload()