Exemplo n.º 1
0
 async def get_reaction(
     self,
     msg: Message,
     message: Message,
     emojilist: list = ['⭕', '❌'],
     timeout: int = 60,
     cls_reaction: bool = False,
     embed: Embed = Embed(title='시간이 종료되었습니다',
                          description=f'정해진 시간이 끝나서 자동으로 반응 콜랙터가 종료되었습니다',
                          color=Color.red())
 ) -> Reaction:
     for e in emojilist:
         await message.add_reaction(str(e))
     try:
         reaction = list(await self.wait_for(
             'reaction_add',
             timeout=timeout,
             check=lambda r, u: r.message.id == message.id and u == msg.
             author and str(r.emoji) in emojilist))[0]
     except AsyncTimeoutError:
         await async_gather(message.delete(),
                            message.channel.send(embed=embed))
         return None
     else:
         try:
             await message.clear_reactions()
         except:
             pass
         return reaction
Exemplo n.º 2
0
    def process_command(self, message: discord.Message) -> None:
        """
        Extract and process a command from a discord message

        params :
            - message: discord.Message = The message to process
        """

        # Extract the command from the message
        com: command.Command = command.Command(message.content)

        # Handle every command
        if com.name == "!help" or com.name == "!h":
            self.dj_bot.show_help()
        elif com.name == "!play" or com.name == "!pl":
            self.dj_bot.add_music(com.arg, message.author)
        elif com.name == "!skip" or com.name == "!sk":
            self.dj_bot.skip_music()
        elif com.name == "!pause" or com.name == "!pa":
            self.dj_bot.pause_music()
        elif com.name == "!resume" or com.name == "!re":
            self.dj_bot.resume_music()
        elif com.name == "!current" or com.name == "!cu":
            self.dj_bot.show_current()
        elif com.name == "!queue" or com.name == "!qu":
            self.dj_bot.show_queue()
        elif com.name == "!pop":
            self.dj_bot.pop_queue(com.arg)
        elif com.name == "!search" or com.name == "!se":
            self.dj_bot.show_search(com.arg, message.author)
        elif com.name == "!choose" or com.name == "!ch":
            self.dj_bot.choose_search(com.arg, message.author)
        elif com.name == "!ban":
            self.dj_bot.ban_user(com.arg, message.author)
        elif com.name == "!unban":
            self.dj_bot.unban_user(com.arg, message.author)
        elif com.name == "!shame":
            self.dj_bot.show_banned(message.author)
        elif com.name == "!empty-queue":
            self.dj_bot.empty_queue(message.author)
        elif com.name == "!clean-cache":
            self.dj_bot.clean_song_cache(message.author)
        elif com.name == "!shutdown":
            self.dj_bot.shutdown(message.author)

        # Remove the request message to keep the board clean
        if com.name != "!shutdown" and com.name != "" and self.remove_req:
            try:
                self.loop.create_task(message.delete())
            except discord.Forbidden as _:
                logging.getLogger(LOGGER_NAME).warning(
                    "Cannot remove message from the listening channel : Forbidden"
                )
            except discord.NotFound as _:
                pass
            except discord.HTTPException as _:
                logging.getLogger(LOGGER_NAME).warning(
                    "Cannot remove message from the listening channel : HTTPError"
                )
Exemplo n.º 3
0
async def phish_match(msg: discord.Message, text: str) -> None:
    assert msg.guild is not None
    logger.info("Message {} contains phishing: {}".format(msg.id, text))
    if isinstance(msg.author, discord.Member):
        if any(role.id in conf.exempt_roles for role in msg.author.roles):
            return
    try:
        reason = "Automatic action: found phishing domain: {}".format(text)
        await asyncio.gather(msg.delete(),
            msg.guild.ban(msg.author, reason=reason, delete_message_days=0))
    except (discord.Forbidden, discord.NotFound):
        logger.error("Could not moderate {}".format(msg.jump_url), exc_info=True)
Exemplo n.º 4
0
 def inner_check(message: discord.Message):
     word_sent: str = message.content
     if check_startwith(_startwith, word_sent) and len(
             word_sent.split(
                 ' ')) == 1 and message.author in players:
         guessed_player.append((message.author, word_sent))
         players.remove(message.author)
         asyncio.create_task(message.delete())
         if len(guessed_player) == _len_players:
             return True
         asyncio.create_task(edit_msg(word_sent))
     return False
Exemplo n.º 5
0
 async def expand_custom_emoji(self, message: Message):
     if message.guild is None:
         return
     emojis = re.compile(r'<:[a-zA-Z_0-9]{2,}:\d{18}>').findall(
         message.content)
     if emojis:
         embeds = [
             self.get_custom_emoji_embed(int(emoji[-19:-1]))
             for emoji in emojis
         ]
         message = await message.channel.send(embed=embeds[0])
         await attach_page_interface(
             self.client,
             message, [
                 InterfaceState(message.edit, embed=embed)
                 for embed in embeds
             ],
             after=message.delete())
Exemplo n.º 6
0
    async def on_message(self, message: Message) -> None:
        channel = message.channel
        if isinstance(channel, (DMChannel, )):  # on dm
            print('dm')
            await self.on_direct_message(message)

        elif self.anonc_guild.get_anonc_chat_channel_from_channel(
                channel):  # on anonc chat
            if not await self._is_message_for_chat(message):
                return

            print('anonc chat :', channel)

            # TODO : private command
            ...

            anonc_count = self.anonc_count + 1
            self.anonc_count += 1

            attachments = message.attachments
            if attachments:
                await self.head_request_to_attachments(attachments)

            anonc_message = await self.anonc_message_maker.make(
                message, anonc_count)
            self.loop.create_task(
                self.anonc_send(anonc_message)).add_done_callback(
                    lambda _: self.loop.create_task(message.delete()))
            self.loop.create_task(
                self.on_anonc_message(anonc_message))  # for public command etc

        elif channel in self.anonc_guild.anonc_system_channels:  # on anonc system
            print('anonc system :', channel)
            on_message_at_some_channel = getattr(
                self, f'on_message_at_{channel.name}_channel', None)
            if on_message_at_some_channel:
                await on_message_at_some_channel(message)

        else:
            print('else :', message, message.channel)

        return
Exemplo n.º 7
0
async def clear(message: discord.Message, data: None):
    """Clears all messages from this channel.
Usage: &clear [optionally the number of messages or @user]
Category: SERVER
    """
    user_permissions = message.author.permissions_in(message.channel)
    if (not user_permissions.administrator
            and not user_permissions.manage_messages):
        return
    user: discord.Member = None
    number: int = None
    if data is not None and "<@" in data:
        user = client.get_user(int(data.replace("<@!", '').replace(">", '')))
    elif data is not None:
        number = int(data)
    helper = clear_helper(number, user)
    try:
        async with message.channel.typing():
            while True:
                history = await message.channel.history(limit=None).flatten()
                for message in history:
                    if helper.check(message):
                        if datetime.datetime.now(
                        ) - message.created_at < datetime.timedelta(14):
                            helper.add_to_bulk(message)
                        else:
                            helper.trigger_bulk(message.channel)
                            loop.create_task(message.delete())
                    if helper.is_finished():
                        break
                if helper.is_finished() or len(history) == 0:
                    break
    except discord.Forbidden:
        await message.channel.send("I'm afraid, I can't do that.")
    except Exception as ex:
        errors[datetime.datetime.now(
        )] = f'Exception occured during cleaning:\n```{ex}```'
        await message.channel.send("Sorry, something went wrong!")
Exemplo n.º 8
0
    def _get_memo_line(cls, message: Message, name_executor: TextParamExecutor,
                       line_executor: FixedValueParamExecutor,
                       int_executor: IntParamExecutor):
        # memo_name and line_count : just to display a better error message
        memo_name = DbMemo.get_memo_name(message.author.id,
                                         name_executor.get_text())
        if not memo_name:
            cls._display_error(
                message, "Aucun mémo trouvé commençant par `{}`.".format(
                    name_executor.get_text()))
            return

        line_count = DbMemo.count_memo_lines(message.author.id,
                                             name_executor.get_text())

        if line_count < int_executor.get_int():
            cls._reply(
                message, "Le mémo [**{}**] n'a que `{}` ligne(s).".format(
                    memo_name, line_count))
            return

        memo_line = DbMemo.get_memo_line(message.author.id,
                                         name_executor.get_text(),
                                         int_executor.get_int())

        if not memo_line:
            cls._display_error(message, "Je n'ai rien trouvé.")
            return

        # Put text in bold if not containing *
        if "*" not in memo_line:
            memo_line = f"**{memo_line}**"

        cls._async(
            message.channel.send(embed=AppMessages.get_memo_line_embed(
                memo_line, f"Mémo de {message.author.display_name}")))
        cls._async(message.delete(delay=cls._delete_delay))
Exemplo n.º 9
0
    async def get_dice_reaction(self, message: Message):

        emojis = [dice[0] for dice in sorted(self.dice.items(), key=lambda item: item[1])] \
                 + [REROLL_EMOJI, CONFIRM_EMOJI]
        asyncio.create_task(add_reactions(message, emojis))

        def is_dice_reaction(reaction_: Reaction, user_: User):
            return user_ == self.player and reaction_.message.id == message.id \
                   and (str(reaction_) in (REROLL_EMOJI, CONFIRM_EMOJI) or str(reaction_) in DICE_ID)

        selected = list()
        last_emoji = ''
        while not (selected and last_emoji
                   == REROLL_EMOJI) and not (last_emoji == CONFIRM_EMOJI):
            reaction, _, added = await self.wait_for_reaction_change(
                is_dice_reaction)
            last_emoji = str(reaction)
            if last_emoji in DICE_ID:
                if added:
                    selected.append(last_emoji)
                elif last_emoji in selected:
                    selected.remove(last_emoji)
        asyncio.create_task(message.delete(delay=1))
        return selected if last_emoji == REROLL_EMOJI else list()
Exemplo n.º 10
0
    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()))
Exemplo n.º 11
0
    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
Exemplo n.º 12
0
 async def on_support(self, message: discord.Message):
     loop = asyncio.get_running_loop()
     loop.create_task(message.delete())
     loop.create_task(self.start_support_session(message))
     return True
Exemplo n.º 13
0
    def on_message(self, msg: discord.Message):
        print('[MESSAGE] [{}] [{}] ({}) - {}'.format(msg.channel.name,
                                                     msg.author,
                                                     msg.author.top_role,
                                                     msg.content))

        message = str(msg.content).lower()

        #WELCOME CHANNEL
        #region
        if msg.channel.id == '505440537332023316':  #Welcome channel ID
            if message.strip() == '-agree' or message.strip() == '.agree':
                newcomer_role = next(r for r in self.server.roles
                                     if r.name == 'Newcomer')
                joinee = msg.author
                yield from msg.author.remove_roles(newcomer_role)
                yield from msg.delete()
                wm = yield from msg.guild.get_channel(219867619103211520).send(
                    "{0} has joined the server".format(joinee.mention))
                yield from asyncio.sleep(5)
                yield from wm.delete()
                return
            else:
                if msg.pinned != True:
                    yield from msg.delete()
                    return
#endregion

#MUTES
#region
#IMAGE MUTE
        if msg.author.id in self.imgmuted:
            if len(msg.attachments) > 0:
                if '.' + msg.attachments[0]['url'].split(
                        '.')[-1] in self.imgmute_extensions:
                    yield from msg.delete()
                    yield from msg.channel.send(
                        "You are image muted and cannot post image attachments {0}"
                        .format(msg.author.mention))
                    return
#TOTAL MUTE
        elif msg.author.id in self.muted:
            yield from msg.delete()
            return
#endregion

        if msg.author.id == self.user.id:
            return
        elif message.startswith(self.trigger):
            #Commands
            command = message[1:].split(' ')[0]
            parameters = message[1:].split(' ')[1:]

            if command in self.commands.keys():
                yield from self.process_command(msg, command, parameters)
        elif self.in_trivia:
            if msg.author.id in self.trivia_instance.current_players:
                if message in self.trivia_instance.answers_given:
                    yield from msg.channel.send(
                        "Answer {0} has already been given once".format(
                            message))
                points = self.trivia_instance.giveAnswer(message)
                if points > 0:
                    self.trivia_instance.givePoints(msg.author.id, points)

                    yield from msg.channel.send(
                        "{0} got it with '{1}'! He receives {2} points for a total of {3}."
                        .format(
                            msg.author.mention, message.capitalize(), points,
                            self.trivia_instance.current_players[
                                msg.author.id]))
                    if self.trivia_instance.current_players[
                            msg.author.id] >= self.trivia_instance.max_score:
                        winner = msg.author
                        yield from msg.channel.send(
                            "{0} wins the trivia game!".format(
                                msg.author.mention))
                        self.trivia_instance.End()
                        self.trivia_instance = None
                        self.in_trivia = False
                    else:
                        self.trivia_instance.getNextQuestion()
                        yield from asyncio.sleep(5)
                        yield from msg.channel.send(
                            "TRIVIA QUESTION ({0})\n\n{1}".format(
                                self.trivia_instance.current_subject,
                                self.trivia_instance.current_question.question.
                                capitalize()))
Exemplo n.º 14
0
 def _safe_delete(self, message: discord.Message, *args, **kwargs) -> None:
     return message.delete(*args, **kwargs)
Exemplo n.º 15
0
    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