async def send( self, message: discord.Message, destination: typing.Union[ discord.TextChannel, discord.DMChannel, discord.User, discord.Member ] = None, from_mod: bool = False, note: bool = False, anonymous: bool = False, ) -> None: self.bot.loop.create_task( self._restart_close_timer() ) # Start or restart thread auto close if self.close_task is not None: # cancel closing if a thread message is sent. self.bot.loop.create_task(self.cancel_closure()) self.bot.loop.create_task( self.channel.send( embed=discord.Embed( color=discord.Color.red(), description="Scheduled close has been cancelled.", ) ) ) if not self.ready: await self.wait_until_ready() if not from_mod and not note: self.bot.loop.create_task(self.bot.api.append_log(message, self.channel.id)) destination = destination or self.channel author = message.author embed = discord.Embed(description=message.content, timestamp=message.created_at) system_avatar_url = ( "https://discordapp.com/assets/f78426a064bc9dd24847519259bc42af.png" ) if not note: if ( anonymous and from_mod and not isinstance(destination, discord.TextChannel) ): # Anonymously sending to the user. tag = self.bot.config["mod_tag"] if tag is None: tag = str(message.author.top_role) name = self.bot.config["anon_username"] if name is None: name = tag avatar_url = self.bot.config["anon_avatar_url"] if avatar_url is None: avatar_url = self.bot.guild.icon_url else: # Normal message name = str(author) avatar_url = author.avatar_url embed.set_author(name=name, icon_url=avatar_url, url=message.jump_url) else: # Special note messages embed.set_author( name=f"Note ({author.name})", icon_url=system_avatar_url, url=message.jump_url, ) delete_message = not bool(message.attachments) ext = [(a.url, a.filename) for a in message.attachments] images = [] attachments = [] for attachment in ext: if is_image_url(attachment[0]): images.append(attachment) else: attachments.append(attachment) image_urls = re.findall( r"http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*(),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+", message.content, ) image_urls = [(url, None) for url in image_urls if is_image_url(url)] images.extend(image_urls) embedded_image = False prioritize_uploads = any(i[1] is not None for i in images) additional_images = [] additional_count = 1 for url, filename in images: if not prioritize_uploads or ( is_image_url(url) and not embedded_image and filename ): embed.set_image(url=url) if filename: embed.add_field(name="Image", value=f"[{filename}]({url})") embedded_image = True elif filename is not None: if note: color = discord.Color.blurple() elif from_mod: color = self.bot.mod_color else: color = self.bot.recipient_color img_embed = discord.Embed(color=color) img_embed.set_image(url=url) img_embed.title = filename img_embed.url = url img_embed.set_footer( text=f"Additional Image Upload ({additional_count})" ) img_embed.timestamp = message.created_at additional_images.append(destination.send(embed=img_embed)) additional_count += 1 file_upload_count = 1 for url, filename in attachments: embed.add_field( name=f"File upload ({file_upload_count})", value=f"[{filename}]({url})" ) file_upload_count += 1 if from_mod: embed.colour = self.bot.mod_color # Anonymous reply sent in thread channel if anonymous and isinstance(destination, discord.TextChannel): embed.set_footer(text="Anonymous Reply") # Normal messages elif not anonymous: mod_tag = self.bot.config["mod_tag"] if mod_tag is None: mod_tag = str(message.author.top_role) embed.set_footer(text=mod_tag) # Normal messages else: embed.set_footer(text=self.bot.config["anon_tag"]) elif note: embed.colour = discord.Color.blurple() else: embed.set_footer(text=f"Message ID: {message.id}") embed.colour = self.bot.recipient_color try: await destination.trigger_typing() except discord.NotFound: logger.warning("Channel not found.", exc_info=True) return if not from_mod and not note: mentions = self.get_notifications() else: mentions = None msg = await destination.send(mentions, embed=embed) if additional_images: self.ready = False await asyncio.gather(*additional_images) self.ready = True if delete_message: self.bot.loop.create_task(ignore(message.delete())) return msg
async def send(self, message: discord.Message, destination: typing.Union[discord.TextChannel, discord.DMChannel, discord.User, discord.Member] = None, from_mod: bool = False, note: bool = False, anonymous: bool = False) -> None: if self.close_task is not None: # cancel closing if a thread message is sent. self.bot.loop.create_task( self.cancel_closure() ) self.bot.loop.create_task( self.channel.send(embed=discord.Embed( color=discord.Color.red(), description='Scheduled close has been cancelled.' )) ) if not self.ready: await self.wait_until_ready() if not from_mod and not note: self.bot.loop.create_task( self.bot.api.append_log(message, self.channel.id) ) destination = destination or self.channel author = message.author embed = discord.Embed( description=message.content, timestamp=message.created_at ) system_avatar_url = 'https://discordapp.com/assets/' \ 'f78426a064bc9dd24847519259bc42af.png' if not note: if anonymous and from_mod and \ not isinstance(destination, discord.TextChannel): # Anonymously sending to the user. tag = self.bot.config.get('mod_tag', str(message.author.top_role)) name = self.bot.config.get('anon_username', tag) avatar_url = self.bot.config.get('anon_avatar_url', self.bot.guild.icon_url) else: # Normal message name = str(author) avatar_url = author.avatar_url embed.set_author(name=name, icon_url=avatar_url, url=message.jump_url) else: # Special note messages embed.set_author(name=f'Note ({author.name})', icon_url=system_avatar_url, url=message.jump_url) delete_message = not bool(message.attachments) attachments = [(a.url, a.filename) for a in message.attachments] images = [x for x in attachments if is_image_url(*x)] attachments = [x for x in attachments if not is_image_url(*x)] image_links = [ (link, None) for link in re.findall(r'(https?://[^\s]+)', message.content) ] image_links = [x for x in image_links if is_image_url(*x)] images.extend(image_links) embedded_image = False prioritize_uploads = any(i[1] is not None for i in images) additional_images = [] additional_count = 1 for att in images: if not prioritize_uploads or ( is_image_url(*att) and not embedded_image and att[1] ): embed.set_image(url=att[0]) if att[1]: embed.add_field(name='Image', value=f'[{att[1]}]({att[0]})') embedded_image = True elif att[1] is not None: if note: color = discord.Color.blurple() elif from_mod: color = self.bot.mod_color else: color = self.bot.recipient_color img_embed = discord.Embed(color=color) img_embed.set_image(url=att[0]) img_embed.title = att[1] img_embed.url = att[0] img_embed.set_footer( text=f'Additional Image Upload ({additional_count})' ) img_embed.timestamp = message.created_at additional_images.append(destination.send(embed=img_embed)) additional_count += 1 file_upload_count = 1 for att in attachments: embed.add_field(name=f'File upload ({file_upload_count})', value=f'[{att[1]}]({att[0]})') file_upload_count += 1 if from_mod: # noinspection PyUnresolvedReferences,PyDunderSlots embed.color = self.bot.mod_color # pylint: disable=E0237 # Anonymous reply sent in thread channel if anonymous and isinstance(destination, discord.TextChannel): embed.set_footer(text='Anonymous Reply') # Normal messages elif not anonymous: tag = self.bot.config.get('mod_tag', str(message.author.top_role)) embed.set_footer(text=tag) # Normal messages else: embed.set_footer( text=self.bot.config.get('anon_tag', 'Response') ) elif note: # noinspection PyUnresolvedReferences,PyDunderSlots embed.color = discord.Color.blurple() # pylint: disable=E0237 else: embed.set_footer(text=f'Recipient') # noinspection PyUnresolvedReferences,PyDunderSlots embed.color = self.bot.recipient_color # pylint: disable=E0237 await destination.trigger_typing() if not from_mod: mentions = self.get_notifications() else: mentions = None await destination.send(mentions, embed=embed) if additional_images: self.ready = False await asyncio.gather(*additional_images) self.ready = True if delete_message: self.bot.loop.create_task(ignore(message.delete()))
async def send( self, message: discord.Message, destination: typing.Union[ discord.TextChannel, discord.DMChannel, discord.User, discord.Member ] = None, from_mod: bool = False, note: bool = False, anonymous: bool = False, ) -> None: self.bot.loop.create_task( self._restart_close_timer() ) # Start or restart thread auto close if self.close_task is not None: # cancel closing if a thread message is sent. self.bot.loop.create_task(self.cancel_closure()) self.bot.loop.create_task( self.channel.send( embed=discord.Embed( color=discord.Color.red(), description="Planlagte lukning er annulleret.", ) ) ) if not self.ready: await self.wait_until_ready() if not from_mod and not note: self.bot.loop.create_task(self.bot.api.append_log(message, self.channel.id)) destination = destination or self.channel author = message.author embed = discord.Embed(description=message.content, timestamp=message.created_at) system_avatar_url = ( "https://discordapp.com/assets/f78426a064bc9dd24847519259bc42af.png" ) if not note: if ( anonymous and from_mod and not isinstance(destination, discord.TextChannel) ): # Anonymously sending to the user. tag = self.bot.config.get("mod_tag", str(message.author.top_role)) name = self.bot.config.get("anon_username", tag) avatar_url = self.bot.config.get( "anon_avatar_url", self.bot.guild.icon_url ) else: # Normal message name = str(author) avatar_url = author.avatar_url embed.set_author(name=name, icon_url=avatar_url, url=message.jump_url) else: # Special note messages embed.set_author( name=f"Note ({author.name})", icon_url=system_avatar_url, url=message.jump_url, ) delete_message = not bool(message.attachments) attachments = [(a.url, a.filename) for a in message.attachments] images = [x for x in attachments if is_image_url(*x)] attachments = [x for x in attachments if not is_image_url(*x)] image_links = [ (link, None) for link in re.findall( r"http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+", message.content, ) ] image_links = [x for x in image_links if is_image_url(*x)] images.extend(image_links) embedded_image = False prioritize_uploads = any(i[1] is not None for i in images) additional_images = [] additional_count = 1 for att in images: if not prioritize_uploads or ( is_image_url(*att) and not embedded_image and att[1] ): embed.set_image(url=att[0]) if att[1]: embed.add_field(name="Image", value=f"[{att[1]}]({att[0]})") embedded_image = True elif att[1] is not None: if note: color = discord.Color.blurple() elif from_mod: color = self.bot.mod_color else: color = self.bot.recipient_color img_embed = discord.Embed(color=color) img_embed.set_image(url=att[0]) img_embed.title = att[1] img_embed.url = att[0] img_embed.set_footer( text=f"Additional Image Upload ({additional_count})" ) img_embed.timestamp = message.created_at additional_images.append(destination.send(embed=img_embed)) additional_count += 1 file_upload_count = 1 for att in attachments: embed.add_field( name=f"File upload ({file_upload_count})", value=f"[{att[1]}]({att[0]})" ) file_upload_count += 1 if from_mod: # noinspection PyUnresolvedReferences,PyDunderSlots embed.color = self.bot.mod_color # pylint: disable=E0237 # Anonymous reply sent in thread channel if anonymous and isinstance(destination, discord.TextChannel): embed.set_footer(text="Anonymt svar") # Normal messages elif not anonymous: tag = self.bot.config.get("mod_tag", str(message.author.top_role)) embed.set_footer(text=tag) # Normal messages else: embed.set_footer(text=self.bot.config.get("anon_tag", "Response")) elif note: # noinspection PyUnresolvedReferences,PyDunderSlots embed.color = discord.Color.blurple() # pylint: disable=E0237 else: embed.set_footer(text=f"Recipient") # noinspection PyUnresolvedReferences,PyDunderSlots embed.color = self.bot.recipient_color # pylint: disable=E0237 await destination.trigger_typing() if not from_mod and not note: mentions = self.get_notifications() else: mentions = None _msg = await destination.send(mentions, embed=embed) if additional_images: self.ready = False await asyncio.gather(*additional_images) self.ready = True if delete_message: self.bot.loop.create_task(ignore(message.delete())) return _msg