1
- __version__ = "3.4.0-dev6 "
1
+ __version__ = "3.4.0-dev7 "
2
2
3
3
4
4
import asyncio
@@ -78,7 +78,7 @@ def __init__(self):
78
78
"Your MONGO_URI might be copied wrong, try re-copying from the source again. "
79
79
"Otherwise noted in the following message:"
80
80
)
81
- logger.critical(str(e) )
81
+ logger.critical(e )
82
82
sys.exit(0)
83
83
84
84
self.plugin_db = PluginDatabaseClient(self)
@@ -506,7 +506,7 @@ async def convert_emoji(self, name: str) -> str:
506
506
try:
507
507
name = await converter.convert(ctx, name.strip(":"))
508
508
except commands.BadArgument as e:
509
- logger.warning("%s is not a valid emoji. %s.", str(e) )
509
+ logger.warning("%s is not a valid emoji. %s.", e )
510
510
raise
511
511
return name
512
512
@@ -697,12 +697,14 @@ async def get_thread_cooldown(self, author: discord.Member):
697
697
return
698
698
699
699
@staticmethod
700
- async def add_reaction(msg, reaction) :
700
+ async def add_reaction(msg, reaction: discord.Reaction) -> bool :
701
701
if reaction != "disable":
702
702
try:
703
703
await msg.add_reaction(reaction)
704
- except (discord.HTTPException, discord.InvalidArgument):
705
- logger.warning("Failed to add reaction %s.", reaction, exc_info=True)
704
+ except (discord.HTTPException, discord.InvalidArgument) as e:
705
+ logger.warning("Failed to add reaction %s: %s.", reaction, e)
706
+ return False
707
+ return True
706
708
707
709
async def process_dm_modmail(self, message: discord.Message) -> None:
708
710
"""Processes messages sent to the bot."""
@@ -955,26 +957,43 @@ async def on_raw_reaction_add(self, payload):
955
957
close_emoji = await self.convert_emoji(self.config["close_emoji"])
956
958
957
959
if isinstance(channel, discord.DMChannel):
958
- if str(reaction) == str(close_emoji): # closing thread
959
- if not self.config.get("recipient_thread_close"):
960
- return
961
- thread = await self.threads.find(recipient=user)
962
- ts = message.embeds[0].timestamp if message.embeds else None
960
+ thread = await self.threads.find(recipient=user)
961
+ if not thread:
962
+ return
963
+
964
+ if (
965
+ message.embeds
966
+ and str(reaction) == str(close_emoji)
967
+ and self.config.get("recipient_thread_close")
968
+ ):
969
+ ts = message.embeds[0].timestamp
963
970
if thread and ts == thread.channel.created_at:
964
971
# the reacted message is the corresponding thread creation embed
965
- await thread.close(closer=user)
972
+ # closing thread
973
+ return await thread.close(closer=user)
974
+ if not thread.recipient.dm_channel:
975
+ await thread.recipient.create_dm()
976
+ try:
977
+ linked_message = await thread.find_linked_message_from_dm(
978
+ message, either_direction=True
979
+ )
980
+ except ValueError as e:
981
+ logger.warning("Failed to find linked message for reactions: %s", e)
982
+ return
966
983
else:
967
- if not message.embeds:
984
+ thread = await self.threads.find(channel=channel)
985
+ if not thread:
986
+ return
987
+ try:
988
+ _, linked_message = await thread.find_linked_messages(
989
+ message.id, either_direction=True
990
+ )
991
+ except ValueError as e:
992
+ logger.warning("Failed to find linked message for reactions: %s", e)
968
993
return
969
- message_id = str(message.embeds[0].author.url).split("/")[-1]
970
- if message_id.isdigit():
971
- thread = await self.threads.find(channel=message.channel)
972
- channel = thread.recipient.dm_channel
973
- if not channel:
974
- channel = await thread.recipient.create_dm()
975
- async for msg in channel.history():
976
- if msg.id == int(message_id):
977
- await msg.add_reaction(reaction)
994
+
995
+ if await self.add_reaction(linked_message, reaction):
996
+ await self.add_reaction(message, reaction)
978
997
979
998
async def on_guild_channel_delete(self, channel):
980
999
if channel.guild != self.modmail_guild:
@@ -986,7 +1005,8 @@ async def on_guild_channel_delete(self, channel):
986
1005
mod = entry.user
987
1006
except AttributeError as e:
988
1007
# discord.py broken implementation with discord API
989
- logger.warning("Failed to retrieve audit log: %s.", str(e))
1008
+ # TODO: waiting for dpy
1009
+ logger.warning("Failed to retrieve audit log: %s.", e)
990
1010
return
991
1011
992
1012
if mod == self.user:
@@ -1035,35 +1055,37 @@ async def on_member_join(self, member):
1035
1055
1036
1056
async def on_message_delete(self, message):
1037
1057
"""Support for deleting linked messages"""
1058
+ # TODO: use audit log to check if modmail deleted the message
1038
1059
if message.embeds and not isinstance(message.channel, discord.DMChannel):
1039
- message_id = str(message.embeds[0].author.url).split("/")[-1]
1040
- if message_id.isdigit():
1041
- thread = await self.threads.find(channel=message.channel)
1042
-
1043
- channel = thread.recipient.dm_channel
1044
-
1045
- async for msg in channel.history():
1046
- if msg.embeds and msg.embeds[0].author:
1047
- url = str(msg.embeds[0].author.url)
1048
- if message_id == url.split("/")[-1]:
1049
- return await msg.delete()
1060
+ thread = await self.threads.find(channel=message.channel)
1061
+ try:
1062
+ await thread.delete_message(message)
1063
+ except ValueError as e:
1064
+ if str(e) not in {"DM message not found.", " Malformed thread message."}:
1065
+ logger.warning("Failed to find linked message to delete: %s", e)
1066
+ else:
1067
+ thread = await self.threads.find(recipient=message.author)
1068
+ message = await thread.find_linked_message_from_dm(message)
1069
+ embed = message.embeds[0]
1070
+ embed.set_footer(text=f"{embed.footer.text} (deleted)", icon_url=embed.footer.icon_url)
1071
+ await message.edit(embed=embed)
1050
1072
1051
1073
async def on_bulk_message_delete(self, messages):
1052
1074
await discord.utils.async_all(self.on_message_delete(msg) for msg in messages)
1053
1075
1054
1076
async def on_message_edit(self, before, after):
1055
1077
if after.author.bot:
1056
1078
return
1079
+ if before.content == after.content:
1080
+ return
1081
+
1057
1082
if isinstance(after.channel, discord.DMChannel):
1058
1083
thread = await self.threads.find(recipient=before.author)
1059
1084
try:
1060
1085
await thread.edit_dm_message(after, after.content)
1061
1086
except ValueError:
1062
1087
_, blocked_emoji = await self.retrieve_emoji()
1063
- try:
1064
- await after.add_reaction(blocked_emoji)
1065
- except (discord.HTTPException, discord.InvalidArgument):
1066
- pass
1088
+ await self.add_reaction(after, blocked_emoji)
1067
1089
else:
1068
1090
embed = discord.Embed(
1069
1091
description="Successfully Edited Message", color=self.main_color
@@ -1173,7 +1195,7 @@ async def before_post_metadata(self):
1173
1195
self.metadata_loop.cancel()
1174
1196
1175
1197
1176
- if __name__ == "__main__" :
1198
+ def main() :
1177
1199
try:
1178
1200
# noinspection PyUnresolvedReferences
1179
1201
import uvloop
@@ -1185,3 +1207,7 @@ async def before_post_metadata(self):
1185
1207
1186
1208
bot = ModmailBot()
1187
1209
bot.run()
1210
+
1211
+
1212
+ if __name__ == "__main__":
1213
+ main()
0 commit comments