Ejemplo n.º 1
0
    async def note(self, message: discord.Message) -> None:
        if not message.content and not message.attachments:
            raise MissingRequiredArgument(param(name="msg"))

        _, msg = await asyncio.gather(
            self.bot.api.append_log(message, self.channel.id, type_="system"),
            self.send(message, self.channel, note=True),
        )

        return msg
Ejemplo n.º 2
0
    async def unblock(self, ctx, *, user: User = None):
        """
        Unblock a user from using Modmail.

        Leave `user` blank when this command is used within a
        thread channel to unblock the current recipient.
        `user` may be a user ID, mention, or name.
        """

        if user is None:
            thread = ctx.thread
            if thread:
                user = thread.recipient
            else:
                raise commands.MissingRequiredArgument(param(name="user"))

        mention = getattr(user, "mention", f"`{user.id}`")

        if str(user.id) in self.bot.blocked_users:
            msg = self.bot.blocked_users.get(str(user.id))
            if msg is None:
                msg = ""
            del self.bot.config.blocked[str(user.id)]
            await self.bot.config.update()

            if msg.startswith("System Message: "):
                # If the user is blocked internally (for example: below minimum account age)
                # Show an extended message stating the original internal message
                reason = msg[16:].strip().rstrip(".") or "no reason"
                embed = discord.Embed(
                    title="Success",
                    description=f"{mention} was previously blocked internally due to "
                    f'"{reason}". {mention} is no longer blocked.',
                    color=self.bot.main_color,
                )
                embed.set_footer(
                    text="However, if the original system block reason still apply, "
                    f"{mention} will be automatically blocked again. Use "
                    f'"{self.bot.prefix}blocked whitelist {mention}" to whitelist the user.'
                )
            else:
                embed = discord.Embed(
                    title="Success",
                    color=self.bot.main_color,
                    description=f"{mention} is no longer blocked.",
                )
        else:
            embed = discord.Embed(
                title="Error",
                description=f"{mention} is not blocked.",
                color=discord.Color.red(),
            )

        return await ctx.send(embed=embed)
Ejemplo n.º 3
0
    async def reply(self,
                    message: discord.Message,
                    anonymous: bool = False) -> None:
        if not message.content and not message.attachments:
            raise MissingRequiredArgument(param(name='msg'))
        if all(not g.get_member(self.id) for g in self.bot.guilds):
            return await message.channel.send(embed=discord.Embed(
                color=discord.Color.red(),
                description='Your message could not be delivered since '
                'the recipient shares no servers with the bot.'))

        tasks = []

        try:
            await self.send(message,
                            destination=self.recipient,
                            from_mod=True,
                            anonymous=anonymous)
        except Exception:
            logger.info(error('Message delivery failed:'), exc_info=True)
            tasks.append(
                message.channel.send(embed=discord.Embed(
                    color=discord.Color.red(),
                    description='Your message could not be delivered as '
                    'the recipient is only accepting direct '
                    'messages from friends, or the bot was '
                    'blocked by the recipient.')))
        else:
            # Send the same thing in the thread channel.
            tasks.append(
                self.send(message,
                          destination=self.channel,
                          from_mod=True,
                          anonymous=anonymous))

            tasks.append(
                self.bot.api.append_log(
                    message,
                    self.channel.id,
                    type_='anonymous' if anonymous else 'thread_message'))

        if self.close_task is not None:
            # Cancel closing if a thread message is sent.
            await self.cancel_closure()
            tasks.append(
                self.channel.send(embed=discord.Embed(
                    color=discord.Color.red(),
                    description='Scheduled close has been cancelled.')))

        await asyncio.gather(*tasks)
Ejemplo n.º 4
0
    async def unblock(self, ctx, *, user: User = None):
        """
        Unblock a user from using Modmail.

        Leave `user` blank when this command is used within a
        thread channel to unblock the current recipient.
        `user` may be a user ID, mention, or name.
        """

        if user is None:
            thread = ctx.thread
            if thread:
                user = thread.recipient
            else:
                raise commands.MissingRequiredArgument(param(name='user'))

        mention = user.mention if hasattr(user, 'mention') else f'`{user.id}`'

        if str(user.id) in self.bot.blocked_users:
            msg = self.bot.blocked_users.get(str(user.id))
            if msg is None:
                msg = ''
            del self.bot.config.blocked[str(user.id)]
            await self.bot.config.update()

            if msg.startswith('System Message: '):
                # If the user is blocked internally (for example: below minimum account age)
                # Show an extended message stating the original internal message
                reason = msg[16:].strip().rstrip('.') or 'no reason'
                embed = discord.Embed(
                    title='Success',
                    description=f'{mention} was previously blocked internally due to '
                    f'"{reason}". {mention} is no longer blocked.',
                    color=self.bot.main_color
                )
            else:
                embed = discord.Embed(
                    title='Success',
                    color=self.bot.main_color,
                    description=f'{mention} is no longer blocked.'
                )
        else:
            embed = discord.Embed(
                title='Error',
                description=f'{mention} is not blocked.',
                color=discord.Color.red()
            )

        return await ctx.send(embed=embed)
Ejemplo n.º 5
0
    async def logs(self, ctx, *, user: User = None):
        """
        Get previous Modmail thread logs of a member.

        Leave `user` blank when this command is used within a
        thread channel to show logs for the current recipient.
        `user` may be a user ID, mention, or name.
        """

        await ctx.trigger_typing()

        if not user:
            thread = ctx.thread
            if not thread:
                raise commands.MissingRequiredArgument(param(name="member"))
            user = thread.recipient

        default_avatar = "https://cdn.discordapp.com/embed/avatars/0.png"
        icon_url = getattr(user, "avatar_url", default_avatar)

        logs = await self.bot.api.get_user_logs(user.id)

        if not any(not log["open"] for log in logs):
            embed = discord.Embed(
                color=discord.Color.red(),
                description="This user does not "
                "have any previous logs.",
            )
            return await ctx.send(embed=embed)

        logs = reversed([e for e in logs if not e["open"]])

        embeds = self.format_log_embeds(logs, avatar_url=icon_url)

        session = PaginatorSession(ctx, *embeds)
        await session.run()
Ejemplo n.º 6
0
    async def block(self,
                    ctx,
                    user: Optional[User] = None,
                    *,
                    after: UserFriendlyTime = None):
        """
        Block a user from using Modmail.

        You may choose to set a time as to when the user will automatically be unblocked.

        Leave `user` blank when this command is used within a
        thread channel to block the current recipient.
        `user` may be a user ID, mention, or name.
        `after` may be a simple "human-readable" time text. See `{prefix}help close` for examples.
        """

        reason = ""

        if user is None:
            thread = ctx.thread
            if thread:
                user = thread.recipient
            elif after is None:
                raise commands.MissingRequiredArgument(param(name="user"))
            else:
                raise commands.BadArgument(f'User "{after.arg}" not found')

        if after is not None:
            reason = after.arg
            if reason.startswith("System Message: "):
                raise commands.BadArgument(
                    "The reason cannot start with `System Message:`.")
            if "%" in reason:
                raise commands.BadArgument(
                    'The reason contains illegal character "%".')
            if after.dt > after.now:
                reason = f"{reason} %{after.dt.isoformat()}%"

        if not reason:
            reason = None

        mention = user.mention if hasattr(user, "mention") else f"`{user.id}`"

        extend = f" for `{reason}`" if reason is not None else ""
        msg = self.bot.blocked_users.get(str(user.id), "")

        if (str(user.id) not in self.bot.blocked_users or reason is not None
                or msg.startswith("System Message: ")):
            if str(user.id) in self.bot.blocked_users:

                old_reason = msg.strip().rstrip(".") or "no reason"
                embed = discord.Embed(
                    title="Success",
                    description=f"{mention} was previously blocked for "
                    f'"{old_reason}". {mention} is now blocked{extend}.',
                    color=self.bot.main_color,
                )
            else:
                embed = discord.Embed(
                    title="Success",
                    color=self.bot.main_color,
                    description=f"{mention} is now blocked{extend}.",
                )
            self.bot.config.blocked[str(user.id)] = reason
            await self.bot.config.update()
        else:
            embed = discord.Embed(
                title="Error",
                color=discord.Color.red(),
                description=f"{mention} is already blocked.",
            )

        return await ctx.send(embed=embed)
Ejemplo n.º 7
0
    async def block(self,
                    ctx,
                    user: Optional[User] = None,
                    *,
                    after: UserFriendlyTime = None):
        """
        Block a user from using Modmail.

        Note: reasons that start with "System Message: " are reserved for internal
        use only.
        """
        reason = ''

        if user is None:
            thread = ctx.thread
            if thread:
                user = thread.recipient
            elif after is None:
                raise commands.MissingRequiredArgument(param(name='user'))
            else:
                raise commands.BadArgument(f'User "{after.arg}" not found')

        if after is not None:
            reason = after.arg
            if reason.startswith('System Message: '):
                raise commands.BadArgument(
                    'The reason cannot start with `System Message:`.')
            if re.search(r'%(.+?)%$', reason) is not None:
                raise commands.MissingRequiredArgument(param(name='reason'))
            if after.dt > after.now:
                reason = f'{reason} %{after.dt.isoformat()}%'

        if not reason:
            reason = None

        mention = user.mention if hasattr(user, 'mention') else f'`{user.id}`'

        extend = f' for `{reason}`' if reason is not None else ''
        msg = self.bot.blocked_users.get(str(user.id))
        if msg is None:
            msg = ''

        if str(user.id
               ) not in self.bot.blocked_users or extend or msg.startswith(
                   'System Message: '):
            if str(user.id) in self.bot.blocked_users:

                old_reason = msg.strip().rstrip('.') or 'no reason'
                embed = discord.Embed(
                    title='Success',
                    description=f'{mention} was previously blocked for '
                    f'"{old_reason}". {mention} is now blocked{extend}.',
                    color=self.bot.main_color)
            else:
                embed = discord.Embed(
                    title='Success',
                    color=self.bot.main_color,
                    description=f'{mention} is now blocked{extend}.')
            self.bot.config.blocked[str(user.id)] = reason
            await self.bot.config.update()
        else:
            embed = discord.Embed(title='Error',
                                  color=discord.Color.red(),
                                  description=f'{mention} is already blocked.')

        return await ctx.send(embed=embed)
Ejemplo n.º 8
0
    async def reply(self, message: discord.Message, anonymous: bool = False) -> None:
        if not message.content and not message.attachments:
            raise MissingRequiredArgument(param(name="msg"))
        if all(not g.get_member(self.id) for g in self.bot.guilds):
            return await message.channel.send(
                embed=discord.Embed(
                    color=discord.Color.red(),
                    description="Din besked kunne ikke blive leveret siden "
                    "personen ikke deler nogen server med botten.",
                )
            )

        tasks = []

        try:
            await self.send(
                message, destination=self.recipient, from_mod=True, anonymous=anonymous
            )
        except Exception:
            logger.info(error("Message delivery failed:"), exc_info=True)
            tasks.append(
                message.channel.send(
                    embed=discord.Embed(
                        color=discord.Color.red(),
                        description="Din besked blev ikke leveret siden "
                        "personen kun accepterer direkte "
                        "beskeder fra venner, eller botten er "
                        "blokeret af personen.",
                    )
                )
            )
        else:
            # Send the same thing in the thread channel.
            tasks.append(
                self.send(
                    message,
                    destination=self.channel,
                    from_mod=True,
                    anonymous=anonymous,
                )
            )

            tasks.append(
                self.bot.api.append_log(
                    message,
                    self.channel.id,
                    type_="anonymous" if anonymous else "thread_message",
                )
            )

            # Cancel closing if a thread message is sent.
            if self.close_task is not None:
                await self.cancel_closure()
                tasks.append(
                    self.channel.send(
                        embed=discord.Embed(
                            color=discord.Color.red(),
                            description="Den planlagte lukning er blevet annulleret.",
                        )
                    )
                )

        await asyncio.gather(*tasks)
Ejemplo n.º 9
0
    async def block(self,
                    ctx,
                    user: Optional[User] = None,
                    *,
                    after: UserFriendlyTime = None):
        """
        Bloquez un utilisateur.
        """

        reason = ""

        if user is None:
            thread = ctx.thread
            if thread:
                user = thread.recipient
            elif after is None:
                raise commands.MissingRequiredArgument(param(name="user"))
            else:
                raise commands.BadArgument(
                    f'Utilateur "{after.arg}" na pas été trouvé')

        mention = getattr(user, "mention", f"`{user.id}`")

        if str(user.id) in self.bot.blocked_whitelisted_users:
            embed = discord.Embed(
                title="Error",
                description=f"Cannot block {mention}, user is whitelisted.",
                color=discord.Color.red(),
            )
            return await ctx.send(embed=embed)

        if after is not None:
            reason = after.arg
            if reason.startswith("System Message: "):
                raise commands.BadArgument(
                    "The reason cannot start with `System Message:`.")
            if "%" in reason:
                raise commands.BadArgument(
                    'The reason contains illegal character "%".')
            if after.dt > after.now:
                reason = f"{reason} %{after.dt.isoformat()}%"

        if not reason:
            reason = None

        extend = f" for `{reason}`" if reason is not None else ""
        msg = self.bot.blocked_users.get(str(user.id), "")

        if (str(user.id) not in self.bot.blocked_users or reason is not None
                or msg.startswith("System Message: ")):
            if str(user.id) in self.bot.blocked_users:

                old_reason = msg.strip().rstrip(".") or "no reason"
                embed = discord.Embed(
                    title="Success",
                    description=f"{mention} was previously blocked for "
                    f'"{old_reason}". {mention} is now blocked{extend}.',
                    color=self.bot.main_color,
                )
            else:
                embed = discord.Embed(
                    title="Success",
                    color=self.bot.main_color,
                    description=f"{mention} is now blocked{extend}.",
                )
            self.bot.config.blocked[str(user.id)] = reason
            await self.bot.config.update()
        else:
            embed = discord.Embed(
                title="Error",
                color=discord.Color.red(),
                description=f"{mention} is already blocked.",
            )

        return await ctx.send(embed=embed)