@@ -433,7 +433,23 @@ async def on_ready(self):
433433 )
434434 logger .info (LINE )
435435
436+ async def convert_emoji (self , name ):
437+ ctx = SimpleNamespace (bot = self , guild = self .modmail_guild )
438+ converter = commands .EmojiConverter ()
439+
440+ if name not in UNICODE_EMOJI :
441+ try :
442+ return await converter .convert (
443+ ctx , sent_emoji .strip (':' )
444+ )
445+ except commands .BadArgument :
446+ pass
447+ return name
448+
436449 async def retrieve_emoji (self ):
450+
451+ # TODO: use a function to convert emojis
452+
437453 ctx = SimpleNamespace (bot = self , guild = self .modmail_guild )
438454 converter = commands .EmojiConverter ()
439455
@@ -634,6 +650,45 @@ async def on_typing(self, channel, user, _):
634650 thread = await self .threads .find (channel = channel )
635651 if thread and thread .recipient :
636652 await thread .recipient .trigger_typing ()
653+
654+ async def on_raw_reaction_add (self , payload ):
655+
656+ user = self .get_user (payload .user_id )
657+
658+ if user .bot :
659+ return
660+
661+ channel = self .get_channel (payload .channel_id )
662+
663+ if not channel : # dm channel not in internal cache
664+ _thread = await self .threads .find (recipient = user )
665+ if not _thread :
666+ return
667+ channel = await _thread .recipient .create_dm ()
668+
669+ message = await channel .get_message (payload .message_id ) # TODO: change to fetch_message (breaking change in d.py)
670+ reaction = payload .emoji
671+
672+ close_emoji = await self .convert_emoji (self .config .get ('close_emoji' , '🔒' ))
673+
674+ if isinstance (channel , discord .DMChannel ) and str (reaction ) == str (close_emoji ): # closing thread
675+ thread = await self .threads .find (recipient = user )
676+ ts = message .embeds [0 ].timestamp if message .embeds else None
677+ if thread and ts == thread .channel .created_at :
678+ # the reacted message is the corresponding thread creation embed
679+ if not self .config .get ('disable_recipient_thread_close' ):
680+ await thread .close (closer = user )
681+ elif not isinstance (channel , discord .DMChannel ):
682+ message_id = str (message .embeds [0 ].author .url ).split ('/' )[- 1 ]
683+ if message_id .isdigit ():
684+ thread = await self .threads .find (channel = message .channel )
685+ channel = thread .recipient .dm_channel
686+ if not channel :
687+ channel = await thread .recipient .create_dm ()
688+ async for msg in channel .history ():
689+ if msg .id == int (message_id ):
690+ await msg .add_reaction (reaction )
691+
637692
638693 async def on_guild_channel_delete (self , channel ):
639694 if channel .guild != self .modmail_guild :
0 commit comments