fix: use ReactionEvent instead of UnknownEvent for approval reactions

matrix-nio parses m.reaction as ReactionEvent with .reacts_to and .key
fields. UnknownEvent handler never fired for reactions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Christian Gick
2026-03-18 18:24:47 +02:00
parent 89aa46aeb2
commit c6ccacee9e

17
bot.py
View File

@@ -25,6 +25,7 @@ from nio import (
LoginResponse, LoginResponse,
InviteMemberEvent, InviteMemberEvent,
MegolmEvent, MegolmEvent,
ReactionEvent,
RoomEncryptedFile, RoomEncryptedFile,
RoomEncryptedImage, RoomEncryptedImage,
RoomMessageFile, RoomMessageFile,
@@ -1268,7 +1269,7 @@ class Bot:
self.client.add_event_callback(self.on_file_message, RoomMessageFile) self.client.add_event_callback(self.on_file_message, RoomMessageFile)
self.client.add_event_callback(self.on_encrypted_file_message, RoomEncryptedFile) self.client.add_event_callback(self.on_encrypted_file_message, RoomEncryptedFile)
self.client.add_event_callback(self.on_room_unknown, RoomMessageUnknown) self.client.add_event_callback(self.on_room_unknown, RoomMessageUnknown)
self.client.add_event_callback(self.on_reaction, UnknownEvent) self.client.add_event_callback(self.on_reaction, ReactionEvent)
self.client.add_response_callback(self.on_sync, SyncResponse) self.client.add_response_callback(self.on_sync, SyncResponse)
self.client.add_to_device_callback(self.on_key_verification, KeyVerificationStart) self.client.add_to_device_callback(self.on_key_verification, KeyVerificationStart)
self.client.add_to_device_callback(self.on_key_verification, KeyVerificationKey) self.client.add_to_device_callback(self.on_key_verification, KeyVerificationKey)
@@ -1464,23 +1465,15 @@ class Bot:
self.client.verify_device(device) self.client.verify_device(device)
logger.info("Auto-trusted device %s of %s", device.device_id, user_id) logger.info("Auto-trusted device %s of %s", device.device_id, user_id)
async def on_reaction(self, room, event: UnknownEvent): async def on_reaction(self, room, event: ReactionEvent):
"""Handle reaction events for pipeline approval flow.""" """Handle reaction events for pipeline approval flow."""
if event.sender == BOT_USER: if event.sender == BOT_USER:
return return
if not self._sync_token_received: if not self._sync_token_received:
return return
source = event.source or {}
if source.get("type") != "m.reaction":
return
content = source.get("content", {}) event_id = event.reacts_to
relates_to = content.get("m.relates_to", {}) reaction_key = event.key
if relates_to.get("rel_type") != "m.annotation":
return
event_id = relates_to.get("event_id", "")
reaction_key = relates_to.get("key", "")
# Check if this reaction is for a pipeline approval # Check if this reaction is for a pipeline approval
if not self.cron_scheduler: if not self.cron_scheduler: