feat(bot): 🐛 Delete message replies on original message delete.
This commit is contained in:
+105
-15
@@ -133,6 +133,7 @@ class Calls(base.Cog):
|
||||
constants.CALL_MESSAGE_CONTENTS_TEMPLATE % call_id,
|
||||
constants.CALL_MESSAGE_FROM_PROPAGATION_TEMPLATE % call_id,
|
||||
constants.CALL_MESSAGES_TEMPLATE % call_id,
|
||||
constants.CALL_MESSAGE_REPLIES_TEMPLATE % call_id,
|
||||
)
|
||||
|
||||
await pipe.execute()
|
||||
@@ -870,6 +871,25 @@ class Calls(base.Cog):
|
||||
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()
|
||||
|
||||
@commands.Cog.listener()
|
||||
@@ -899,7 +919,17 @@ class Calls(base.Cog):
|
||||
if message_json is None:
|
||||
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)
|
||||
|
||||
@@ -916,6 +946,21 @@ class Calls(base.Cog):
|
||||
# This message was already deleted.
|
||||
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.guild_only()
|
||||
@transactions.atomic()
|
||||
@@ -939,33 +984,80 @@ class Calls(base.Cog):
|
||||
channel_id = payload.channel_id
|
||||
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
|
||||
|
||||
is_on_call = await redis.sismember(
|
||||
constants.CHANNELS_ONCALL_SET, str(channel_id)
|
||||
message_json = await redis.hget(
|
||||
constants.CALL_MESSAGES_TEMPLATE % channel.call_id, message_id
|
||||
)
|
||||
|
||||
if not is_on_call:
|
||||
if message_json is None:
|
||||
return
|
||||
|
||||
message = await models.Message.get_or_none(id=message_id).select_related(
|
||||
"propagation_channel"
|
||||
)
|
||||
message = models.Message(**orjson.loads(message_json))
|
||||
|
||||
if message is None:
|
||||
return
|
||||
|
||||
other_channel = message.propagation_channel
|
||||
other_channel = await models.Channel.get(id=message.propagation_channel_id)
|
||||
|
||||
if other_channel.call_id != message.call_id:
|
||||
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:
|
||||
webhook = other_channel.webhook(session)
|
||||
|
||||
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:
|
||||
# This message was deleted.
|
||||
@@ -973,8 +1065,6 @@ class Calls(base.Cog):
|
||||
|
||||
# TODO: Edit replies.
|
||||
|
||||
await models.MessageContent.create(message=message, content=content)
|
||||
|
||||
|
||||
def setup(b: bot.Payphone) -> None:
|
||||
"""Load the cog into the bot.
|
||||
|
||||
@@ -175,19 +175,40 @@ MESSAGE_CONTENTS_QUEUE = "message-contents"
|
||||
MESSAGES_PROPAGATION_MAP = "messages-propagation"
|
||||
|
||||
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"
|
||||
"""`%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"
|
||||
"""`%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"
|
||||
"""`%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"
|
||||
"""`%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"
|
||||
"""A set of IDs of calls to flush to the DB."""
|
||||
|
||||
Reference in New Issue
Block a user