diff --git a/bot/pluralkit/bot.py b/bot/pluralkit/bot.py index 6107310d..c9ab6237 100644 --- a/bot/pluralkit/bot.py +++ b/bot/pluralkit/bot.py @@ -1,4 +1,5 @@ import logging +import json import os import discord @@ -63,15 +64,25 @@ async def on_message(message): async with client.pool.acquire() as conn: await proxy.handle_proxying(conn, message) - @client.event -async def on_reaction_add(reaction, user): - from pluralkit import proxy - - # Pass reactions to proxy system - async with client.pool.acquire() as conn: - await proxy.handle_reaction(conn, reaction, user) +async def on_socket_raw_receive(msg): + # Since on_reaction_add is buggy (only works for messages the bot's already cached, ie. no old messages) + # we parse socket data manually for the reaction add event + if isinstance(msg, str): + try: + msg_data = json.loads(msg) + if msg_data.get("t") == "MESSAGE_REACTION_ADD": + evt_data = msg_data.get("d") + if evt_data: + user_id = evt_data["user_id"] + message_id = evt_data["message_id"] + emoji = evt_data["emoji"]["name"] + async with client.pool.acquire() as conn: + from pluralkit import proxy + await proxy.handle_reaction(conn, user_id, message_id, emoji) + except ValueError: + pass async def run(): from pluralkit import db diff --git a/bot/pluralkit/db.py b/bot/pluralkit/db.py index 2e60f34b..88c4ae3f 100644 --- a/bot/pluralkit/db.py +++ b/bot/pluralkit/db.py @@ -161,7 +161,7 @@ async def get_members_by_account(conn, account_id: str): @db_wrap async def get_message_by_sender_and_id(conn, message_id: str, sender_id: str): - await conn.fetchrow("select * from messages where mid = $1 and sender = $2", int(message_id), int(sender_id)) + return await conn.fetchrow("select * from messages where mid = $1 and sender = $2", int(message_id), int(sender_id)) @db_wrap diff --git a/bot/pluralkit/proxy.py b/bot/pluralkit/proxy.py index 68179d50..a91815be 100644 --- a/bot/pluralkit/proxy.py +++ b/bot/pluralkit/proxy.py @@ -75,7 +75,11 @@ async def send_hook_message(member, hook_id, hook_token, text=None, image_url=No if resp.status == 200: resp_data = await resp.json() # Make a fake message object for passing on - this is slightly broken but works for most things - return discord.Message(reactions=[], **resp_data) + msg = discord.Message(reactions=[], **resp_data) + + # Make sure it's added to the client's message cache - otherwise events r + #client.messages.append(msg) + return msg else: # Fake a Discord exception, also because #yolo raise discord.HTTPException(resp, await resp.text()) @@ -142,13 +146,18 @@ async def handle_proxying(conn, message): break -async def handle_reaction(conn, reaction, user): - if reaction.emoji == "❌": +async def handle_reaction(conn, user_id, message_id, emoji): + if emoji == "❌": async with conn.transaction(): # Find the message in the DB, and make sure it's sent by the user who reacted - message = await db.get_message_by_sender_and_id(conn, message_id=reaction.message.id, sender_id=user.id) + db_message = await db.get_message_by_sender_and_id(conn, message_id=message_id, sender_id=user_id) + if db_message: + logger.debug("Deleting message {} by reaction from {}".format(message_id, user_id)) + + # If so, remove it from the DB + await db.delete_message(conn, message_id) - if message: - # If so, delete the message and remove it from the DB - await db.delete_message(conn, message["mid"]) - await client.delete_message(reaction.message) + # And look up the message and then delete it + channel = client.get_channel(str(db_message["channel"])) + message = await client.get_message(channel, message_id) + await client.delete_message(message)