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_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.
|
||||||
|
|||||||
@@ -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."""
|
||||||
|
|||||||
Reference in New Issue
Block a user