Add optional Matrix thread support for per-category deal organization
When MATRIX_USE_THREADS=true, deals are posted into dedicated threads instead of the room timeline: - 🎮 Game Deals — CheapShark + ITAD type=game - 🧩 DLC Deals — ITAD type=dlc - 🆓 Epic Free Games — current and upcoming Epic free games - 📦 Non-Game Deals — ITAD non-game content (software, courses, etc.) Thread roots are created on first use and persisted in the database. When threads are disabled (default), behaviour is unchanged. Key changes: - New threads.py module with ThreadCategory enum and routing logic - ITADDeal now carries deal_type; type filter moved from fetcher to bot - MatrixDealsClient gains send_deal_in_thread() and create_thread_root() - Database gets thread_roots table for storing root event IDs - Bot routes each deal to the appropriate thread via _send_to_thread_or_room() https://claude.ai/code/session_01EfPjktyrF24DBNHWsY1KBP
This commit is contained in:
@@ -17,6 +17,12 @@ CREATE TABLE IF NOT EXISTS config (
|
||||
key TEXT PRIMARY KEY,
|
||||
value TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS thread_roots (
|
||||
category TEXT PRIMARY KEY,
|
||||
event_id TEXT NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
"""
|
||||
|
||||
|
||||
@@ -77,3 +83,33 @@ class Database:
|
||||
(key, value),
|
||||
)
|
||||
await self._db.commit()
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Thread root management
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
async def get_thread_root(self, category: str) -> str | None:
|
||||
"""Return the Matrix event ID for a thread root, or None."""
|
||||
assert self._db is not None
|
||||
cursor = await self._db.execute(
|
||||
"SELECT event_id FROM thread_roots WHERE category = ?", (category,)
|
||||
)
|
||||
row = await cursor.fetchone()
|
||||
return row[0] if row else None
|
||||
|
||||
async def set_thread_root(self, category: str, event_id: str):
|
||||
"""Store the Matrix event ID for a thread root."""
|
||||
assert self._db is not None
|
||||
await self._db.execute(
|
||||
"INSERT OR REPLACE INTO thread_roots (category, event_id) VALUES (?, ?)",
|
||||
(category, event_id),
|
||||
)
|
||||
await self._db.commit()
|
||||
|
||||
async def clear_thread_root(self, category: str):
|
||||
"""Remove a stored thread root (e.g. if the event was redacted)."""
|
||||
assert self._db is not None
|
||||
await self._db.execute(
|
||||
"DELETE FROM thread_roots WHERE category = ?", (category,)
|
||||
)
|
||||
await self._db.commit()
|
||||
|
||||
Reference in New Issue
Block a user