fix: wyr votes never counted — reactions arrive as ReactionEvent not UnknownEvent
nio has a dedicated ReactionEvent type with .reacts_to and .key attributes. The callback was registered for UnknownEvent so reaction events were silently dropped. Register for ReactionEvent and use its native attributes; keep the UnknownEvent fallback for edge cases. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+3
-1
@@ -9,6 +9,7 @@ from nio import (
|
|||||||
AsyncClientConfig,
|
AsyncClientConfig,
|
||||||
InviteMemberEvent,
|
InviteMemberEvent,
|
||||||
LoginResponse,
|
LoginResponse,
|
||||||
|
ReactionEvent,
|
||||||
RoomMemberEvent,
|
RoomMemberEvent,
|
||||||
RoomMessageText,
|
RoomMessageText,
|
||||||
UnknownEvent,
|
UnknownEvent,
|
||||||
@@ -143,7 +144,8 @@ async def main():
|
|||||||
|
|
||||||
callbacks = Callbacks(client)
|
callbacks = Callbacks(client)
|
||||||
client.add_event_callback(callbacks.message, RoomMessageText)
|
client.add_event_callback(callbacks.message, RoomMessageText)
|
||||||
client.add_event_callback(callbacks.reaction, UnknownEvent)
|
client.add_event_callback(callbacks.reaction, ReactionEvent)
|
||||||
|
client.add_event_callback(callbacks.unknown_event, UnknownEvent)
|
||||||
client.add_event_callback(callbacks.member, RoomMemberEvent)
|
client.add_event_callback(callbacks.member, RoomMemberEvent)
|
||||||
|
|
||||||
# Auto-accept room invites
|
# Auto-accept room invites
|
||||||
|
|||||||
+20
-22
@@ -70,40 +70,38 @@ class Callbacks:
|
|||||||
await wrapped(self.client, room.room_id, event.sender, args)
|
await wrapped(self.client, room.room_id, event.sender, args)
|
||||||
|
|
||||||
async def reaction(self, room, event):
|
async def reaction(self, room, event):
|
||||||
"""Handle m.reaction events (sent as UnknownEvent by matrix-nio)."""
|
"""Handle ReactionEvent (nio's native reaction type)."""
|
||||||
# Ignore events from before startup
|
|
||||||
if self.startup_sync_token is None:
|
if self.startup_sync_token is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Ignore our own reactions
|
|
||||||
if event.sender == MATRIX_USER_ID:
|
if event.sender == MATRIX_USER_ID:
|
||||||
return
|
return
|
||||||
|
|
||||||
# m.reaction events come as UnknownEvent with type "m.reaction"
|
reacted_event_id = event.reacts_to
|
||||||
|
key = event.key
|
||||||
|
logger.info("reaction: key=%r target=%s sender=%s", key, reacted_event_id[:16], event.sender)
|
||||||
|
|
||||||
|
await handle_welcome_reaction(self.client, room.room_id, event.sender, reacted_event_id, key)
|
||||||
|
record_wyr_vote(reacted_event_id, event.sender, key)
|
||||||
|
|
||||||
|
async def unknown_event(self, room, event):
|
||||||
|
"""Fallback handler for UnknownEvent — catches any m.reaction not parsed by nio."""
|
||||||
|
if self.startup_sync_token is None:
|
||||||
|
return
|
||||||
|
if event.sender == MATRIX_USER_ID:
|
||||||
|
return
|
||||||
if not hasattr(event, "source"):
|
if not hasattr(event, "source"):
|
||||||
logger.info("reaction: event has no source attr, type=%s sender=%s", type(event).__name__, event.sender)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
event_type = event.source.get("type", "")
|
|
||||||
content = event.source.get("content", {})
|
content = event.source.get("content", {})
|
||||||
relates_to = content.get("m.relates_to", {})
|
relates_to = content.get("m.relates_to", {})
|
||||||
rel_type = relates_to.get("rel_type", "")
|
if relates_to.get("rel_type") != "m.annotation":
|
||||||
reacted_event_id = relates_to.get("event_id", "")
|
|
||||||
key = relates_to.get("key", "")
|
|
||||||
|
|
||||||
logger.info(
|
|
||||||
"reaction: type=%s rel_type=%s key=%r target=%s sender=%s",
|
|
||||||
event_type, rel_type, key, reacted_event_id[:16] if reacted_event_id else "", event.sender,
|
|
||||||
)
|
|
||||||
|
|
||||||
if rel_type != "m.annotation":
|
|
||||||
return
|
return
|
||||||
|
|
||||||
await handle_welcome_reaction(
|
reacted_event_id = relates_to.get("event_id", "")
|
||||||
self.client, room.room_id, event.sender, reacted_event_id, key
|
key = relates_to.get("key", "")
|
||||||
)
|
logger.info("unknown_event reaction: key=%r target=%s sender=%s", key, reacted_event_id[:16], event.sender)
|
||||||
from commands import _WYR_POLLS
|
|
||||||
logger.info("reaction: wyr polls active=%s matched=%s", list(_WYR_POLLS.keys()), reacted_event_id in _WYR_POLLS)
|
await handle_welcome_reaction(self.client, room.room_id, event.sender, reacted_event_id, key)
|
||||||
record_wyr_vote(reacted_event_id, event.sender, key)
|
record_wyr_vote(reacted_event_id, event.sender, key)
|
||||||
|
|
||||||
async def member(self, room, event):
|
async def member(self, room, event):
|
||||||
|
|||||||
Reference in New Issue
Block a user