fix: Switch E2EE from shared key to per-participant key mode

Element Call uses per-participant keys via MatrixKeyProvider.onSetEncryptionKey(),
not shared key mode. This was causing silence with E2EE enabled.

- Set bot's own key and caller's key separately via e2ee_manager.key_provider.set_key()
- Live-update caller key when received after connect
- Fallback to set_shared_key if per-participant API unavailable

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Christian Gick
2026-02-21 18:50:19 +02:00
parent 9aef846619
commit 533847c952
2 changed files with 89 additions and 30 deletions

16
bot.py
View File

@@ -448,12 +448,13 @@ class Bot:
model = self.room_models.get(room_id, DEFAULT_MODEL)
caller_device_id = content.get("device_id", "")
# Publish a placeholder key first to trigger Element Call
# to share its key with us. We'll republish the real shared
# key once we receive the caller's key.
# Generate bot's E2EE key and publish it so Element Call
# can decrypt our audio. This also triggers Element Call
# to share its key with us.
import secrets
placeholder_key = secrets.token_bytes(16)
await self._publish_encryption_key(room_id, placeholder_key)
bot_key = secrets.token_bytes(16)
# Publish bot's key early so Element Call can decrypt our audio
await self._publish_encryption_key(room_id, bot_key)
vs = VoiceSession(
nio_client=self.client,
@@ -461,8 +462,9 @@ class Bot:
device_id=BOT_DEVICE_ID,
lk_url=LK_URL,
model=model,
publish_key_cb=lambda key: asyncio.ensure_future(
self._publish_encryption_key(room_id, key)),
publish_key_cb=lambda key, rid=room_id: asyncio.ensure_future(
self._publish_encryption_key(rid, key)),
bot_key=bot_key,
)
# Check timeline for caller's key