Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions cogs/modmail.py
Original file line number Diff line number Diff line change
Expand Up @@ -1724,11 +1724,11 @@ async def edit(self, ctx, message_id: Optional[int] = None, *, message: str):

try:
await thread.edit_message(message_id, message)
except ValueError:
except ValueError as e:
return await ctx.send(
embed=discord.Embed(
title="Failed",
description="Cannot find a message to edit. Plain messages are not supported.",
description=str(e),
color=self.bot.error_color,
)
)
Expand Down Expand Up @@ -2274,7 +2274,7 @@ async def delete(self, ctx, message_id: int = None):
return await ctx.send(
embed=discord.Embed(
title="Failed",
description="Cannot find a message to delete. Plain messages are not supported.",
description=str(e),
color=self.bot.error_color,
)
)
Expand Down
101 changes: 84 additions & 17 deletions core/thread.py
Original file line number Diff line number Diff line change
Expand Up @@ -1345,11 +1345,17 @@ async def find_linked_messages(
or not message1.embeds[0].author.url
or message1.author != self.bot.user
):
logger.debug(
f"Malformed thread message for deletion: embeds={bool(message1.embeds)}, author_url={getattr(message1.embeds[0], 'author', None) and message1.embeds[0].author.url}, author={message1.author}"
)
# Keep original error string to avoid extra failure embeds in on_message_delete
raise ValueError("Malformed thread message.")
is_plain = False
if message1.embeds and message1.embeds[0].footer and message1.embeds[0].footer.text:
if message1.embeds[0].footer.text.startswith("[PLAIN]"):
is_plain = True

if not is_plain:
logger.debug(
f"Malformed thread message for deletion: embeds={bool(message1.embeds)}, author_url={getattr(message1.embeds[0], 'author', None) and message1.embeds[0].author.url}, author={message1.author}"
)
# Keep original error string to avoid extra failure embeds in on_message_delete
raise ValueError("Malformed thread message.")

elif message_id is not None:
try:
Expand All @@ -1374,8 +1380,12 @@ async def find_linked_messages(
return message1, None
# else: fall through to relay checks below

# Non-note path (regular relayed messages): require author.url and colors
if not (
is_plain = False
if message1.embeds and message1.embeds[0].footer and message1.embeds[0].footer.text:
if message1.embeds[0].footer.text.startswith("[PLAIN]"):
is_plain = True

if not is_plain and not (
message1.embeds
and message1.embeds[0].author.url
and message1.embeds[0].color
Expand All @@ -1395,28 +1405,73 @@ async def find_linked_messages(
# Internal bot-only message treated similarly; keep None sentinel
return message1, None

if message1.embeds[0].color.value != self.bot.mod_color and not (
either_direction and message1.embeds[0].color.value == self.bot.recipient_color
if (
not is_plain
and message1.embeds[0].color.value != self.bot.mod_color
and not (either_direction and message1.embeds[0].color.value == self.bot.recipient_color)
):
logger.warning("Message color does not match mod/recipient colors.")
raise ValueError("Thread message not found.")
else:
async for message1 in self.channel.history():
if (
message1.embeds
and message1.embeds[0].author.url
and message1.embeds[0].color
and (
message1.embeds[0].color.value == self.bot.mod_color
or (either_direction and message1.embeds[0].color.value == self.bot.recipient_color)
(
message1.embeds[0].author.url
and message1.embeds[0].color
and (
message1.embeds[0].color.value == self.bot.mod_color
or (
either_direction
and message1.embeds[0].color.value == self.bot.recipient_color
)
)
and message1.embeds[0].author.url.split("#")[-1].isdigit()
)
or (
message1.embeds[0].footer
and message1.embeds[0].footer.text
and message1.embeds[0].footer.text.startswith("[PLAIN]")
)
)
and message1.embeds[0].author.url.split("#")[-1].isdigit()
and message1.author == self.bot.user
):
break
else:
raise ValueError("Thread message not found.")

is_plain = False
if message1.embeds and message1.embeds[0].footer and message1.embeds[0].footer.text:
if message1.embeds[0].footer.text.startswith("[PLAIN]"):
is_plain = True

if is_plain:
messages = [message1]
creation_time = message1.created_at

target_content = message1.embeds[0].description

for user in self.recipients:
async for msg in user.history(limit=50, around=creation_time):
if abs((msg.created_at - creation_time).total_seconds()) > 15:
continue

if msg.author != self.bot.user:
continue

if msg.embeds:
continue

if target_content and target_content in msg.content:
messages.append(msg)
break

if len(messages) > 1:
return messages

raise ValueError("Linked Plain DM message not found.")

try:
joint_id = int(message1.embeds[0].author.url.split("#")[-1])
except ValueError:
Expand Down Expand Up @@ -1453,6 +1508,10 @@ async def edit_message(self, message_id: typing.Optional[int], message: str) ->
embed1 = message1.embeds[0]
embed1.description = message

is_plain = False
if embed1.footer and embed1.footer.text and embed1.footer.text.startswith("[PLAIN]"):
is_plain = True

tasks = [
self.bot.api.edit_message(message1.id, message),
message1.edit(embed=embed1),
Expand All @@ -1462,9 +1521,17 @@ async def edit_message(self, message_id: typing.Optional[int], message: str) ->
else:
for m2 in message2:
if m2 is not None:
embed2 = m2.embeds[0]
embed2.description = message
tasks += [m2.edit(embed=embed2)]
if is_plain:
if ":** " in m2.content:
prefix = m2.content.split(":** ", 1)[0] + ":** "
new_content = f"{prefix}{message}"
tasks += [m2.edit(content=new_content)]
else:
tasks += [m2.edit(content=message)]
else:
embed2 = m2.embeds[0]
embed2.description = message
tasks += [m2.edit(embed=embed2)]

await asyncio.gather(*tasks)

Expand Down
Loading