Add Wordle, welcome system, integrations, and update roadmap
- Add Wordle game engine with daily puzzles, hard mode, stats, and share - Add welcome module (react-to-join onboarding, Space join DMs) - Add Ollama LLM integration (!ask), Minecraft RCON whitelist (!minecraft) - Add !trivia, !champion, !agent, !health commands - Add DM routing for Wordle (games in DMs, share to public room) - Update README: reflect Phase 4 completion, hookshot webhook setup, infrastructure migration (LXC 151/109 to large1), Spam and Stuff room, all 12 webhook connections with UUIDs and transform notes Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
54
callbacks.py
54
callbacks.py
@@ -1,10 +1,11 @@
|
||||
import logging
|
||||
from functools import wraps
|
||||
|
||||
from nio import AsyncClient, RoomMessageText
|
||||
from nio import AsyncClient, RoomMessageText, UnknownEvent
|
||||
|
||||
from config import BOT_PREFIX, MATRIX_USER_ID
|
||||
from commands import COMMANDS, metrics
|
||||
from welcome import handle_welcome_reaction, handle_space_join, SPACE_ROOM_ID
|
||||
|
||||
logger = logging.getLogger("matrixbot")
|
||||
|
||||
@@ -60,3 +61,54 @@ class Callbacks:
|
||||
metrics.record_command(cmd_name)
|
||||
wrapped = handle_command_errors(handler)
|
||||
await wrapped(self.client, room.room_id, event.sender, args)
|
||||
|
||||
async def reaction(self, room, event):
|
||||
"""Handle m.reaction events (sent as UnknownEvent by matrix-nio)."""
|
||||
# Ignore events from before startup
|
||||
if self.startup_sync_token is None:
|
||||
return
|
||||
|
||||
# Ignore our own reactions
|
||||
if event.sender == MATRIX_USER_ID:
|
||||
return
|
||||
|
||||
# m.reaction events come as UnknownEvent with type "m.reaction"
|
||||
if not hasattr(event, "source"):
|
||||
return
|
||||
|
||||
content = event.source.get("content", {})
|
||||
relates_to = content.get("m.relates_to", {})
|
||||
if relates_to.get("rel_type") != "m.annotation":
|
||||
return
|
||||
|
||||
reacted_event_id = relates_to.get("event_id", "")
|
||||
key = relates_to.get("key", "")
|
||||
|
||||
await handle_welcome_reaction(
|
||||
self.client, room.room_id, event.sender, reacted_event_id, key
|
||||
)
|
||||
|
||||
async def member(self, room, event):
|
||||
"""Handle m.room.member events — watch for Space joins."""
|
||||
# Ignore events from before startup
|
||||
if self.startup_sync_token is None:
|
||||
return
|
||||
|
||||
# Only care about the Space
|
||||
if room.room_id != SPACE_ROOM_ID:
|
||||
return
|
||||
|
||||
# Ignore our own membership changes
|
||||
if event.state_key == MATRIX_USER_ID:
|
||||
return
|
||||
|
||||
# Only trigger on joins (not leaves, bans, etc.)
|
||||
if event.membership != "join":
|
||||
return
|
||||
|
||||
# Check if this is a new join (prev was not "join")
|
||||
prev = event.prev_membership if hasattr(event, "prev_membership") else None
|
||||
if prev == "join":
|
||||
return # Already was a member, this is a profile update or similar
|
||||
|
||||
await handle_space_join(self.client, event.state_key)
|
||||
|
||||
Reference in New Issue
Block a user