Initial commit
This commit is contained in:
63
bot/reactor.py
Normal file
63
bot/reactor.py
Normal file
@@ -0,0 +1,63 @@
|
||||
import asyncio
|
||||
import logging
|
||||
import random
|
||||
from typing import Optional
|
||||
|
||||
import discord
|
||||
|
||||
from bot.discovery import Target
|
||||
from bot.display import StatsDisplay
|
||||
from bot.storage import Storage
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def human_jitter() -> float:
|
||||
"""Gaussian delay centered a few seconds in, clamped to a natural-looking range."""
|
||||
delay = random.gauss(4.0, 1.5)
|
||||
return max(1.5, min(delay, 8.0))
|
||||
|
||||
|
||||
async def react_to_message(
|
||||
storage: Storage,
|
||||
message: discord.Message,
|
||||
target: Target,
|
||||
friend_id: int,
|
||||
emoji: str,
|
||||
source: str,
|
||||
display: Optional[StatsDisplay] = None,
|
||||
) -> bool:
|
||||
if message.author.id != friend_id:
|
||||
return False
|
||||
|
||||
already_reacted = any(
|
||||
reaction.me and str(reaction.emoji) == emoji for reaction in message.reactions
|
||||
)
|
||||
if not already_reacted:
|
||||
already_reacted = await asyncio.to_thread(storage.has_reacted, message.id, emoji)
|
||||
if already_reacted:
|
||||
return False
|
||||
|
||||
await asyncio.sleep(human_jitter())
|
||||
|
||||
try:
|
||||
await message.add_reaction(emoji)
|
||||
except discord.HTTPException:
|
||||
log.exception("Failed to react to message %s in channel %s", message.id, message.channel.id)
|
||||
return False
|
||||
|
||||
inserted = await asyncio.to_thread(
|
||||
storage.record_reaction,
|
||||
message.id,
|
||||
message.channel.id,
|
||||
target.target_id,
|
||||
friend_id,
|
||||
emoji,
|
||||
source,
|
||||
message.created_at,
|
||||
)
|
||||
if inserted:
|
||||
log.info("Reacted to message %s in %s [%s] (%s)", message.id, target.name, target.target_type, source)
|
||||
if display is not None:
|
||||
await display.refresh()
|
||||
return inserted
|
||||
Reference in New Issue
Block a user