feat(bot): 🐛 Delete message replies on original message delete.

This commit is contained in:
Nyeki.py
2024-10-20 23:00:58 -03:00
parent 9e81978fba
commit 0f7618875c
2 changed files with 131 additions and 20 deletions
+105 -15
View File
@@ -133,6 +133,7 @@ class Calls(base.Cog):
constants.CALL_MESSAGE_CONTENTS_TEMPLATE % call_id, constants.CALL_MESSAGE_CONTENTS_TEMPLATE % call_id,
constants.CALL_MESSAGE_FROM_PROPAGATION_TEMPLATE % call_id, constants.CALL_MESSAGE_FROM_PROPAGATION_TEMPLATE % call_id,
constants.CALL_MESSAGES_TEMPLATE % call_id, constants.CALL_MESSAGES_TEMPLATE % call_id,
constants.CALL_MESSAGE_REPLIES_TEMPLATE % call_id,
) )
await pipe.execute() await pipe.execute()
@@ -870,6 +871,25 @@ class Calls(base.Cog):
message.id, message.id,
) )
if replying_to_id is not None:
other_replies = await redis.hget(
constants.CALL_MESSAGE_REPLIES_TEMPLATE % call.id, replying_to_id
)
if other_replies is None:
pipe.hset(
constants.CALL_MESSAGE_REPLIES_TEMPLATE % call.id,
replying_to_id,
message.id,
)
else:
pipe.hset(
constants.CALL_MESSAGE_REPLIES_TEMPLATE % call.id,
replying_to_id,
other_replies.decode() + f",{message.id}",
)
await pipe.execute() await pipe.execute()
@commands.Cog.listener() @commands.Cog.listener()
@@ -899,7 +919,17 @@ class Calls(base.Cog):
if message_json is None: if message_json is None:
return return
message = models.Message(**orjson.loads(message_json)) message_dict = orjson.loads(message_json)
message = models.Message(**message_dict)
message_dict["was_deleted"] = True
await redis.hset(
constants.CALL_MESSAGES_TEMPLATE % channel.call_id,
message.id,
orjson.dumps(message_dict),
)
other_channel = await models.Channel.get(id=message.propagation_channel_id) other_channel = await models.Channel.get(id=message.propagation_channel_id)
@@ -916,6 +946,21 @@ class Calls(base.Cog):
# This message was already deleted. # This message was already deleted.
pass pass
message_replies = await redis.hget(
constants.CALL_MESSAGE_REPLIES_TEMPLATE % channel.call_id,
message.id
)
if message_replies is None:
return
for message_id in message_replies.split(","):
try:
await webhook.edit_message(message_id, embed=None)
except errors.DiscordException:
pass
@commands.Cog.listener() @commands.Cog.listener()
@commands.guild_only() @commands.guild_only()
@transactions.atomic() @transactions.atomic()
@@ -939,33 +984,80 @@ class Calls(base.Cog):
channel_id = payload.channel_id channel_id = payload.channel_id
content = payload.data["content"] content = payload.data["content"]
if censorship.moderate(content) is not None: channel = await models.Channel.get(id=channel_id)
if channel.call_id is None:
return return
is_on_call = await redis.sismember( message_json = await redis.hget(
constants.CHANNELS_ONCALL_SET, str(channel_id) constants.CALL_MESSAGES_TEMPLATE % channel.call_id, message_id
) )
if not is_on_call: if message_json is None:
return return
message = await models.Message.get_or_none(id=message_id).select_related( message = models.Message(**orjson.loads(message_json))
"propagation_channel"
)
if message is None: other_channel = await models.Channel.get(id=message.propagation_channel_id)
return
other_channel = message.propagation_channel
if other_channel.call_id != message.call_id: if other_channel.call_id != message.call_id:
return return
original_message = await self.bot.get_partial_messageable(
channel_id
).fetch_message(message.id)
if original_message is None:
return
call_rss = await models.CallUserChannelRelationship.filter(
call_id=channel.call_id
)
cleaned_content = formatting.clean(original_message, call_rss)
blocked_word = censorship.moderate(content)
iteration = int(
await redis.hget(
constants.CALL_MESSAGE_CONTENT_ITERATIONS_TEMPLATE % channel.call_id,
message.id,
)
)
pipe = redis.pipeline()
pipe.hincrby(
constants.CALL_MESSAGE_CONTENT_ITERATIONS_TEMPLATE % channel.call_id,
message.id,
)
pipe.hset(
constants.CALL_MESSAGE_CONTENTS_TEMPLATE % channel.call_id,
constants.CALL_MESSAGE_CONTENTS_HASH_TEMPLATE % (message.id, iteration + 1),
orjson.dumps(
{
"message_id": message.id,
"content": cleaned_content,
"was_propagated": not bool(blocked_word),
"created_at": datetime.now(timezone.utc),
}
),
)
await pipe.execute()
async with aiohttp.ClientSession() as session: async with aiohttp.ClientSession() as session:
webhook = other_channel.webhook(session) webhook = other_channel.webhook(session)
try: try:
await webhook.edit_message(message.propagation_id, content=content) await webhook.edit_message(
message.propagation_id,
content=(
cleaned_content
if blocked_word is None
else "*This message was edited and censored.*"
),
)
except errors.DiscordException: except errors.DiscordException:
# This message was deleted. # This message was deleted.
@@ -973,8 +1065,6 @@ class Calls(base.Cog):
# TODO: Edit replies. # TODO: Edit replies.
await models.MessageContent.create(message=message, content=content)
def setup(b: bot.Payphone) -> None: def setup(b: bot.Payphone) -> None:
"""Load the cog into the bot. """Load the cog into the bot.
+26 -5
View File
@@ -175,19 +175,40 @@ MESSAGE_CONTENTS_QUEUE = "message-contents"
MESSAGES_PROPAGATION_MAP = "messages-propagation" MESSAGES_PROPAGATION_MAP = "messages-propagation"
CALL_MESSAGES_TEMPLATE = "m:%s" CALL_MESSAGES_TEMPLATE = "m:%s"
"""`%s`: Call ID. The key template for call messages hash.""" """`%s`: Call ID.
The key template for call messages hash.
"""
CALL_MESSAGE_CONTENTS_TEMPLATE = "mc:%s" CALL_MESSAGE_CONTENTS_TEMPLATE = "mc:%s"
"""`%s`: Call ID. The key template for call message contents hash.""" """`%s`: Call ID.
The key template for call message contents hash.
"""
CALL_MESSAGE_CONTENTS_HASH_TEMPLATE = "%s-%s" CALL_MESSAGE_CONTENTS_HASH_TEMPLATE = "%s-%s"
"""`%s-%s`: Call ID - Iteration. The key template for call message contents hash keys.""" """`%s-%s`: Call ID - Iteration.
The key template for call message contents hash keys.
"""
CALL_MESSAGE_FROM_PROPAGATION_TEMPLATE = "mfp:%s" CALL_MESSAGE_FROM_PROPAGATION_TEMPLATE = "mfp:%s"
"""`%s`: Call ID. A map from propagation IDs to message IDs.""" """`%s`: Call ID.
A map from propagation IDs to message IDs.
"""
CALL_MESSAGE_CONTENT_ITERATIONS_TEMPLATE = "mci:%s" CALL_MESSAGE_CONTENT_ITERATIONS_TEMPLATE = "mci:%s"
"""`%s`: Call ID. A map of messages to amount of iterations of their message contents.""" """`%s`: Call ID.
A map of messages to amount of iterations of their message contents.
"""
CALL_MESSAGE_REPLIES_TEMPLATE = "mr:%s"
"""`%s`: Call ID.
A map of message IDs to a `,`-delimited list of message IDs that reply to the message.
"""
CALL_IDS_TO_FLUSH = "call-ids-to-flush" CALL_IDS_TO_FLUSH = "call-ids-to-flush"
"""A set of IDs of calls to flush to the DB.""" """A set of IDs of calls to flush to the DB."""