Skip to content

Commit f33b06c

Browse files
committed
support to edit and delete plain reply messages
1 parent 6e094af commit f33b06c

File tree

2 files changed

+89
-26
lines changed

2 files changed

+89
-26
lines changed

cogs/modmail.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1724,11 +1724,11 @@ async def edit(self, ctx, message_id: Optional[int] = None, *, message: str):
17241724

17251725
try:
17261726
await thread.edit_message(message_id, message)
1727-
except ValueError:
1727+
except ValueError as e:
17281728
return await ctx.send(
17291729
embed=discord.Embed(
17301730
title="Failed",
1731-
description="Cannot find a message to edit. Plain messages are not supported.",
1731+
description=str(e),
17321732
color=self.bot.error_color,
17331733
)
17341734
)
@@ -2274,7 +2274,7 @@ async def delete(self, ctx, message_id: int = None):
22742274
return await ctx.send(
22752275
embed=discord.Embed(
22762276
title="Failed",
2277-
description="Cannot find a message to delete. Plain messages are not supported.",
2277+
description=str(e),
22782278
color=self.bot.error_color,
22792279
)
22802280
)

core/thread.py

Lines changed: 86 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -224,16 +224,12 @@ async def snooze(self, moderator=None, command_used=None, snooze_for=None):
224224
"author_name": (
225225
getattr(m.embeds[0].author, "name", "").split(" (")[0]
226226
if m.embeds and m.embeds[0].author and m.author == self.bot.user
227-
else getattr(m.author, "name", None)
228-
if m.author != self.bot.user
229-
else None
227+
else getattr(m.author, "name", None) if m.author != self.bot.user else None
230228
),
231229
"author_avatar": (
232230
getattr(m.embeds[0].author, "icon_url", None)
233231
if m.embeds and m.embeds[0].author and m.author == self.bot.user
234-
else m.author.display_avatar.url
235-
if m.author != self.bot.user
236-
else None
232+
else m.author.display_avatar.url if m.author != self.bot.user else None
237233
),
238234
}
239235
async for m in channel.history(limit=None, oldest_first=True)
@@ -1345,11 +1341,17 @@ async def find_linked_messages(
13451341
or not message1.embeds[0].author.url
13461342
or message1.author != self.bot.user
13471343
):
1348-
logger.debug(
1349-
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}"
1350-
)
1351-
# Keep original error string to avoid extra failure embeds in on_message_delete
1352-
raise ValueError("Malformed thread message.")
1344+
is_plain = False
1345+
if message1.embeds and message1.embeds[0].footer and message1.embeds[0].footer.text:
1346+
if message1.embeds[0].footer.text.startswith("[PLAIN]"):
1347+
is_plain = True
1348+
1349+
if not is_plain:
1350+
logger.debug(
1351+
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}"
1352+
)
1353+
# Keep original error string to avoid extra failure embeds in on_message_delete
1354+
raise ValueError("Malformed thread message.")
13531355

13541356
elif message_id is not None:
13551357
try:
@@ -1374,8 +1376,12 @@ async def find_linked_messages(
13741376
return message1, None
13751377
# else: fall through to relay checks below
13761378

1377-
# Non-note path (regular relayed messages): require author.url and colors
1378-
if not (
1379+
is_plain = False
1380+
if message1.embeds and message1.embeds[0].footer and message1.embeds[0].footer.text:
1381+
if message1.embeds[0].footer.text.startswith("[PLAIN]"):
1382+
is_plain = True
1383+
1384+
if not is_plain and not (
13791385
message1.embeds
13801386
and message1.embeds[0].author.url
13811387
and message1.embeds[0].color
@@ -1395,28 +1401,73 @@ async def find_linked_messages(
13951401
# Internal bot-only message treated similarly; keep None sentinel
13961402
return message1, None
13971403

1398-
if message1.embeds[0].color.value != self.bot.mod_color and not (
1399-
either_direction and message1.embeds[0].color.value == self.bot.recipient_color
1404+
if (
1405+
not is_plain
1406+
and message1.embeds[0].color.value != self.bot.mod_color
1407+
and not (either_direction and message1.embeds[0].color.value == self.bot.recipient_color)
14001408
):
14011409
logger.warning("Message color does not match mod/recipient colors.")
14021410
raise ValueError("Thread message not found.")
14031411
else:
14041412
async for message1 in self.channel.history():
14051413
if (
14061414
message1.embeds
1407-
and message1.embeds[0].author.url
1408-
and message1.embeds[0].color
14091415
and (
1410-
message1.embeds[0].color.value == self.bot.mod_color
1411-
or (either_direction and message1.embeds[0].color.value == self.bot.recipient_color)
1416+
(
1417+
message1.embeds[0].author.url
1418+
and message1.embeds[0].color
1419+
and (
1420+
message1.embeds[0].color.value == self.bot.mod_color
1421+
or (
1422+
either_direction
1423+
and message1.embeds[0].color.value == self.bot.recipient_color
1424+
)
1425+
)
1426+
and message1.embeds[0].author.url.split("#")[-1].isdigit()
1427+
)
1428+
or (
1429+
message1.embeds[0].footer
1430+
and message1.embeds[0].footer.text
1431+
and message1.embeds[0].footer.text.startswith("[PLAIN]")
1432+
)
14121433
)
1413-
and message1.embeds[0].author.url.split("#")[-1].isdigit()
14141434
and message1.author == self.bot.user
14151435
):
14161436
break
14171437
else:
14181438
raise ValueError("Thread message not found.")
14191439

1440+
is_plain = False
1441+
if message1.embeds and message1.embeds[0].footer and message1.embeds[0].footer.text:
1442+
if message1.embeds[0].footer.text.startswith("[PLAIN]"):
1443+
is_plain = True
1444+
1445+
if is_plain:
1446+
messages = [message1]
1447+
creation_time = message1.created_at
1448+
1449+
target_content = message1.embeds[0].description
1450+
1451+
for user in self.recipients:
1452+
async for msg in user.history(limit=50, around=creation_time):
1453+
if abs((msg.created_at - creation_time).total_seconds()) > 15:
1454+
continue
1455+
1456+
if msg.author != self.bot.user:
1457+
continue
1458+
1459+
if msg.embeds:
1460+
continue
1461+
1462+
if target_content and target_content in msg.content:
1463+
messages.append(msg)
1464+
break
1465+
1466+
if len(messages) > 1:
1467+
return messages
1468+
1469+
raise ValueError("Linked Plain DM message not found.")
1470+
14201471
try:
14211472
joint_id = int(message1.embeds[0].author.url.split("#")[-1])
14221473
except ValueError:
@@ -1453,6 +1504,10 @@ async def edit_message(self, message_id: typing.Optional[int], message: str) ->
14531504
embed1 = message1.embeds[0]
14541505
embed1.description = message
14551506

1507+
is_plain = False
1508+
if embed1.footer and embed1.footer.text and embed1.footer.text.startswith("[PLAIN]"):
1509+
is_plain = True
1510+
14561511
tasks = [
14571512
self.bot.api.edit_message(message1.id, message),
14581513
message1.edit(embed=embed1),
@@ -1462,9 +1517,17 @@ async def edit_message(self, message_id: typing.Optional[int], message: str) ->
14621517
else:
14631518
for m2 in message2:
14641519
if m2 is not None:
1465-
embed2 = m2.embeds[0]
1466-
embed2.description = message
1467-
tasks += [m2.edit(embed=embed2)]
1520+
if is_plain:
1521+
if ":** " in m2.content:
1522+
prefix = m2.content.split(":** ", 1)[0] + ":** "
1523+
new_content = f"{prefix}{message}"
1524+
tasks += [m2.edit(content=new_content)]
1525+
else:
1526+
tasks += [m2.edit(content=message)]
1527+
else:
1528+
embed2 = m2.embeds[0]
1529+
embed2.description = message
1530+
tasks += [m2.edit(embed=embed2)]
14681531

14691532
await asyncio.gather(*tasks)
14701533

0 commit comments

Comments
 (0)