Add DM support, friend identification, and target pruning
React in 1:1 DMs alongside servers/groups, surface the resolved friend username at startup and in the stats panel, verify reactions actually stick after adding them (with jump links for manual spot-checking), and prune stale targets from stats on each run so only the currently mutual set is shown.
This commit is contained in:
28
main.py
28
main.py
@@ -10,7 +10,7 @@ from rich.logging import RichHandler
|
||||
from bot.backlog import scan_channel_backlog
|
||||
from bot.channels import get_scannable_channels
|
||||
from bot.config import load_config
|
||||
from bot.discovery import Target, discover_targets
|
||||
from bot.discovery import Target, discover_targets, resolve_friend
|
||||
from bot.display import StatsDisplay
|
||||
from bot.reactor import react_to_message
|
||||
from bot.storage import Storage
|
||||
@@ -44,11 +44,27 @@ class ReactorClient(discord.Client):
|
||||
await self.close()
|
||||
|
||||
async def _run_backlog_then_watch(self):
|
||||
targets = await discover_targets(self, self.cfg.friend_id, self.cfg.manual_guild_ids)
|
||||
try:
|
||||
friend = await resolve_friend(self, self.cfg.friend_id)
|
||||
except discord.NotFound:
|
||||
log.error(
|
||||
"friend_id %s does not resolve to any Discord user. Check config.json and fix it.",
|
||||
self.cfg.friend_id,
|
||||
)
|
||||
return
|
||||
|
||||
log.info("Targeting friend: %s (%s)", friend, friend.id)
|
||||
self.display.set_friend(str(friend))
|
||||
await self.display.refresh()
|
||||
|
||||
targets = await discover_targets(self, friend, self.cfg.manual_guild_ids)
|
||||
log.info("Discovered %d mutual target(s): %s", len(targets), [t.name for t in targets])
|
||||
|
||||
for t in targets:
|
||||
await asyncio.to_thread(self.storage.upsert_target, t.target_id, t.target_type, t.name)
|
||||
pruned = await asyncio.to_thread(self.storage.prune_targets, [t.target_id for t in targets])
|
||||
if pruned:
|
||||
log.info("Pruned %d stale target(s) no longer mutual/discovered", pruned)
|
||||
await self.display.refresh()
|
||||
|
||||
cutoff = datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(days=self.cfg.days_back)
|
||||
@@ -56,14 +72,14 @@ class ReactorClient(discord.Client):
|
||||
async def react_fn(message: discord.Message, target: Target) -> bool:
|
||||
return await react_to_message(
|
||||
self.storage, message, target, self.cfg.friend_id, self.cfg.emoji,
|
||||
source="backlog", display=self.display,
|
||||
source="backlog", display=self.display, verify=self.cfg.verify_reactions,
|
||||
)
|
||||
|
||||
for target in targets:
|
||||
if target.target_type == "group_dm":
|
||||
if target.target_type in ("group_dm", "dm"):
|
||||
channel = self.get_channel(target.target_id)
|
||||
if channel is None:
|
||||
log.warning("Group DM %s not found in cache, skipping", target.target_id)
|
||||
log.warning("Channel %s (%s) not found in cache, skipping", target.target_id, target.name)
|
||||
continue
|
||||
self.known_channel_targets[channel.id] = target
|
||||
await scan_channel_backlog(self.storage, channel, target, self.cfg.friend_id, cutoff, react_fn)
|
||||
@@ -84,7 +100,7 @@ class ReactorClient(discord.Client):
|
||||
return
|
||||
await react_to_message(
|
||||
self.storage, message, target, self.cfg.friend_id, self.cfg.emoji,
|
||||
source="live", display=self.display,
|
||||
source="live", display=self.display, verify=self.cfg.verify_reactions,
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user