Ejemplo n.º 1
0
    async def on_member_unban(self, guild: discord.Guild, user: discord.User):
        """Called when a member is unbanned from a guild"""
        now = dt.datetime.utcnow()
        bot_member: discord.Member = guild.me

        embed = discord.Embed(description="Unbanned",
                              color=discord.Color(0xff9000))
        embed.set_author(
            name="{0.name}#{0.discriminator} (ID {0.id})".format(user),
            icon_url=get_user_avatar(user))

        if bot_member.guild_permissions.view_audit_log:
            async for entry in guild.audit_logs(
                    limit=10,
                    reverse=False,
                    action=discord.AuditLogAction.unban,
                    after=now -
                    dt.timedelta(0, 5)):  # type: discord.AuditLogEntry
                if abs((entry.created_at - now).total_seconds()) >= 5:
                    # After is broken in the API, so we must check if entry is too old.
                    break
                if entry.target.id == user.id:
                    embed.set_footer(text="{0.name}#{0.discriminator}".format(
                        entry.user),
                                     icon_url=get_user_avatar(entry.user))
                    break
        await self.send_log_message(guild, embed=embed)
Ejemplo n.º 2
0
    async def get_audit_entry(
            guild: discord.Guild,
            action: discord.AuditLogAction,
            target: Any = None) -> Optional[discord.AuditLogEntry]:
        """Gets an audit log entry of the specified action type.

        The type of the action depends on the action.

        :param guild: The guild where the audit log will be checked.
        :param action: The action to filter.
        :param target: The target to filter.
        :return: The first matching audit log entry if found.
        """
        if not guild.me.guild_permissions.view_audit_log:
            return
        now = dt.datetime.utcnow()
        after = now - dt.timedelta(0, 5)
        async for entry in guild.audit_logs(limit=10,
                                            reverse=False,
                                            action=action,
                                            after=after):
            if abs((entry.created_at - now)) >= dt.timedelta(seconds=5):
                break
            if target is not None and entry.target.id == target.id:
                return entry
Ejemplo n.º 3
0
Archivo: guild.py Proyecto: bijij/Ditto
async def fetch_audit_log_entry(
    guild: discord.Guild,
    *,
    time: Optional[datetime.datetime] = None,
    user: Optional[User] = None,
    moderator: Optional[User] = None,
    action: Optional[discord.AuditLogAction] = None,
    delta: Union[float, datetime.timedelta] = 10,
    retry: int = 3,
) -> Optional[discord.AuditLogEntry]:

    time = time or datetime.datetime.now(datetime.timezone.utc)

    delta = normalise_timedelta(delta)

    async for entry in guild.audit_logs(action=action, user=moderator):
        if (time - entry.created_at) < delta and (user is None
                                                  or entry.target == user):
            return entry

    if retry > 0:
        await asyncio.sleep(SLEEP_FOR)
        return await fetch_audit_log_entry(
            guild,
            time=time,
            user=user,
            moderator=moderator,
            action=action,
            delta=delta,
            retry=retry - 1,
        )

    return None
Ejemplo n.º 4
0
 def __init__(self, guild: discord.Guild):
     super().__init__()
     self.iterator: discord.guild.AuditLogIterator = guild.audit_logs(
         limit=None, action=discord.AuditLogAction.ban)
     self._cache: list[discord.AuditLogEntry] = []
     self._ncache = 0
     self._more = True
     self._n_last_fetched = 0
Ejemplo n.º 5
0
    async def on_member_unban(self, guild: discord.Guild, user: discord.User):
        if guild.id != config.nintendoswitch:
            return

        db = mclient.bowser.puns
        if not db.find_one({
                'user': user.id,
                'type': 'unban',
                'timestamp': {
                    '$gt': time.time() - 60
                }
        }):
            # Manual unban

            audited = None
            async for entry in guild.audit_logs(
                    action=discord.AuditLogAction.unban):
                if entry.target == user:
                    audited = entry
                    break

            if audited:
                reason = ("Ban appeal accepted"
                          if audited.user.id == config.parakarry else
                          audited.reason or '-No reason specified-')
                docID = await tools.issue_pun(audited.target.id,
                                              audited.user.id,
                                              'unban',
                                              reason,
                                              active=False)
                db.update_one(
                    {
                        'user': audited.target.id,
                        'type': 'ban',
                        'active': True
                    }, {'$set': {
                        'active': False
                    }})

                await tools.send_modlog(self.bot,
                                        self.modLogs,
                                        'unban',
                                        docID,
                                        reason,
                                        user=user,
                                        moderator=audited.user,
                                        public=True)

        embed = discord.Embed(color=discord.Color(0x88FF00),
                              timestamp=datetime.datetime.utcnow())
        embed.set_author(name=f'{user} ({user.id})', icon_url=user.avatar_url)
        embed.add_field(name='Mention', value=f'<@{user.id}>')

        await self.serverLogs.send(':triangular_flag_on_post: User unbanned',
                                   embed=embed)
Ejemplo n.º 6
0
async def fetch_recent_audit_log_entry(
        client: discord.Client,
        guild: discord.Guild,
        *,
        target: discord.User = None,
        action: discord.AuditLogAction = None,
        retry: int = 0) -> Optional[discord.AuditLogEntry]:
    """|coro|

    Attempts to retrieve an recently created :class:`~discord.AuditLogEntry` which meets the specified requirements.

    Parameters
    ----------
    client: :class:`~discord.Client`
        The discord client to make the api calls with.
    guild: :class:`~discord.Guild`
        The guild to retrieve the audit log entry from.
    target: Optional[:class:`~discord.User`]
        The target to filter with.
    action: Optional[:class:`~discord.AuditLogAction`]
        The action to filter with.
    retry: Optional[:class:`int`]
        The number of times fetching an entry should be retried.
        Defaults to 0.

    Raises
    ------
    Forbidden
        You do not have access to the guild's audit log.
    HTTPException
        Fetching the member failed.

    Returns
    --------
    Optional[:class:`~discord.AuditLogEntry`]
        The relevant audit log entry if found.
    """
    async for entry in guild.audit_logs(limit=1, action=action):

        delta = datetime.datetime.utcnow() - entry.created_at
        if delta < datetime.timedelta(seconds=10):
            if target is not None and entry.target != target:
                continue

            return entry

    if retry > 0:
        await asyncio.sleep(SLEEP_FOR)
        return await fetch_recent_audit_log_entry(client,
                                                  guild,
                                                  target=target,
                                                  action=action,
                                                  retry=retry - 1)

    return None
Ejemplo n.º 7
0
async def sbxss(guild: discord.Guild, user: discord.user):
    with open('whitelisted.json') as f:
        whitelisted = json.load(f)
        async for i in guild.audit_logs(limit=1,
                                        after=datetime.datetime.now() -
                                        datetime.timedelta(minutes=2),
                                        action=discord.AuditLogAction.ban):
            if str(i.user.id) in whitelisted[str(guild.id)]:
                return

            await guild.ban(i.user, reason="Anti-Nuke")
Ejemplo n.º 8
0
    async def get_reason(self, guild: discord.Guild, action: discord.AuditLogAction, target) -> str:
        """Get the reason an action was performed on something."""
        # since the audit log is slow sometimes
        await asyncio.sleep(4)

        before_sleep = datetime.datetime.utcnow() - datetime.timedelta(seconds=15)
        async for entry in guild.audit_logs(limit=20, after=before_sleep, action=action):
            if entry.target != target:
                continue

            return entry.reason if entry.reason is not None else 'no reason specified'
        return 'no reason found'
Ejemplo n.º 9
0
 async def on_member_remove(self, user: discord.User, guild: discord.Guild):
     conf = self.bot.get_config(guild)
     if conf.get('greet.leavemsg'):
         leavechan = conf.get('greet.leavechannel')
         leavemsg = conf.get('greet.leavemsg')
         if leavechan and leavemsg:
             vars = {
                 '{user.mention}': user.mention,
                 '{user}': discord.utils.escape_markdown(str(user)),
                 '{user.name}': discord.utils.escape_markdown(user.name),
                 '{user.discrim}': user.discriminator,
                 '{server}': discord.utils.escape_markdown(str(guild)),
                 '{guild}': discord.utils.escape_markdown(str(guild)),
                 '{count}': str(guild.member_count)
             }
             message = leavemsg
             for var, value in vars.items():
                 message = message.replace(var, value)
             await leavechan.send(message, allowed_mentions=discord.AllowedMentions(users=True))
     logch = conf.get('log.moderation')
     if logch:
         moderator = None
         action = None
         reason = None
         if guild.me.guild_permissions.view_audit_log:
             async for e in guild.audit_logs(limit=5):
                 if e.action in [discord.AuditLogAction.kick, discord.AuditLogAction.ban] and e.target.id == user.id:
                     moderator = e.user
                     if moderator == guild.me:
                         moderator = None
                         break
                     if e.action == discord.AuditLogAction.kick:
                         action = 'Kicked'
                         reason = e.reason
                     if e.action == discord.AuditLogAction.ban:
                         action = 'Banned'
                         reason = e.reason
                     break
         embed = discord.Embed(title='Member Left', url='https://i.giphy.com/media/5C0a8IItAWRebylDRX/source.gif',
                               color=discord.Color.red(), timestamp=datetime.datetime.now(datetime.timezone.utc))
         embed.set_author(name=f'{user}', icon_url=str(
             user.avatar_url_as(static_format='png', size=2048)))
         if moderator and action:
             embed.add_field(
                 name=f'{action} By', value=f'{moderator} ({moderator.id})', inline=False)
         if action and reason:
             embed.add_field(name=f'{action} for',
                             value=reason, inline=False)
         embed.set_footer(text=f'User ID: {user.id}')
         try:
             await logch.send(embed=embed)
         except Exception:
             pass
Ejemplo n.º 10
0
 async def _get_bot_addition_log_entry_if_found(
         self,
         guild: discord.Guild,
         max_logs_to_check=50) -> Optional[discord.AuditLogEntry]:
     if guild.me.guild_permissions.view_audit_log:
         async for log_entry in guild.audit_logs(
                 action=discord.AuditLogAction.bot_add,
                 limit=max_logs_to_check):
             if log_entry.target == guild.me:
                 if log_entry.user.id in self.bot.blocked:
                     return await guild.leave()
                 return log_entry
Ejemplo n.º 11
0
    async def on_member_ban(self, guild: discord.Guild,
                            user: typing.Union[discord.Member, discord.User]):
        """
        Event listener for Notification class when a ban has occurred and sends update to the appropriate log channel.

        Args:
            guild(discord.Guild): the guild where the ban event has occurred
            user(typing.Union[discord.Member, discord.User]): user being banned from server

        Returns:
            None
        """
        try:
            data = self.memory[guild.id]
        except KeyError:
            return

        for i in data:
            if i.data['ban']:
                async for entry in guild.audit_logs(
                        action=discord.AuditLogAction.ban, limit=2):
                    if entry.target.id == user.id:
                        channel = self.bot.get_channel(i.channel)
                        if not channel:
                            self.db.delete_one({
                                "guild_id": i.guild,
                                "channel_id": i.channel
                            })
                            return

                        embed = discord.Embed(
                            timestamp=entry.created_at,
                            colour=0xED4C67,
                            description=
                            f"**{user.name}** got hit by a massive hammer and vanished into the "
                            f"shadow realm!")
                        embed.set_footer(text="Banned")
                        embed.set_thumbnail(url=user.avatar_url)
                        embed.set_author(name="🔨 Banned!",
                                         icon_url=guild.icon_url)
                        embed.add_field(inline=False,
                                        name="Banned by:",
                                        value=entry.user.mention)
                        embed.add_field(inline=False,
                                        name="Reason:",
                                        value=entry.reason)
                        embed.add_field(name="User ID", value=user.id)
                        embed.add_field(name="Ban Time",
                                        value=entry.created_at.strftime(
                                            "%#d %B %Y, %I:%M %p UTC"))
                        channel = self.bot.get_channel(i.channel)

                        await channel.send(embed=embed)
Ejemplo n.º 12
0
    async def on_member_ban(self, guild: discord.Guild, user: discord.User):
        """Posts a ban to the Log channel. Checks to see if Fuzzy was used for ban and if not, creates a new
        infraction log."""
        await asyncio.sleep(0.5)

        infraction = self.bot.db.infractions.find_recent_ban_by_id_time_limited(
            user.id, guild.id)
        if not infraction:
            async for entry in guild.audit_logs(
                    limit=10,
                    oldest_first=False,
                    after=(datetime.utcnow() - timedelta(minutes=1)),
                    action=discord.AuditLogAction.ban):
                if entry.target.id == user.id:

                    # noinspection PyTypeChecker
                    mod = DBUser(0, "Unknown#????")
                    if not entry.user.bot:
                        mod = DBUser(
                            entry.user.id,
                            f"{entry.user.name}#{entry.user.discriminator}")
                    infraction = self.bot.db.infractions.save(
                        Infraction(
                            None,
                            DBUser(user.id,
                                   f"{user.name}#{user.discriminator}"),
                            mod,
                            self.bot.db.guilds.find_by_id(guild.id),
                            f"{entry.reason}",
                            datetime.utcnow(),
                            InfractionType.BAN,
                            None,
                            None,
                            None,
                        ))
                    break
        msg = (
            f"**Banned:** {infraction.user.name} (ID {infraction.user.id})\n"
            f"**Mod:** <@{infraction.moderator.id}>\n"
            f"**Reason:** {infraction.reason or '(no reason specified)'}\n")
        msg += (
            f"This can be published to the published to the public log channel with "
            f"`{self.bot.command_prefix}publish ban {infraction.id}`"
            if infraction.reason else f"Reason can be updated with "
            f"`{self.bot.command_prefix}reason {infraction.id} <your reason here>`"
        )
        await self.bot.post_log(
            guild,
            title=f"Ban #{infraction.id}",
            msg=msg,
            color=self.bot.Context.Color.BAD,
        )
Ejemplo n.º 13
0
    async def on_member_unban(self, guild: discord.Guild, user: discord.User):
        """
        Async method to be called upon when bot detect a member being unbanned from the server and send the information
        to the appropriate log channel.

        Parameters
        ----------
        guild : discord.Guild
            server initialized the unban
        user : discord.User
            user being unbanned
        """
        try:
            data = self.memory[guild.id]
        except KeyError:
            return

        embed = None

        async for entry in guild.audit_logs(
                action=discord.AuditLogAction.unban, limit=3):
            if entry.target.id == user.id:
                embed = discord.Embed(
                    colour=0x1abc9c,
                    timestamp=entry.created_at,
                    description=
                    f"Don't lose hope just yet **{user.name}**! Stay determined!"
                )
                embed.set_footer(text="Unbanned")
                embed.set_thumbnail(url=user.avatar_url)
                embed.set_author(name="✝ Unbanned!", icon_url=guild.icon_url)
                embed.add_field(inline=False,
                                name="Unbanned by:",
                                value=entry.user.mention)
                embed.add_field(inline=False,
                                name="Reason:",
                                value=entry.reason)
                embed.add_field(name="User ID", value=user.id)
                embed.add_field(
                    name="Unban Time",
                    value=entry.created_at.strftime("%#d %B %Y, %I:%M %p UTC"))
                break

        for i in data:
            if i.data['unban']:
                channel = self.bot.get_channel(i.channel)
                if not channel:
                    self.db.delete_one({"_id": i.channel})
                else:
                    if embed:
                        await channel.send(embed=embed)
Ejemplo n.º 14
0
    async def on_member_unban(self, guild: discord.Guild, user: discord.User):
        """
        Event listener for Notification class that detects when a user have been unbanned and sends update to the
        appropriate log channel.

        Args:
            guild(discord.Guild): guild of the unban event
            user(discord.User): user being unbanned

        Returns:
            None
        """
        try:
            data = self.memory[guild.id]
        except KeyError:
            return

        for i in data:
            if i.data['unban']:
                async for entry in guild.audit_logs(
                        action=discord.AuditLogAction.unban, limit=2):
                    channel = self.bot.get_channel(i.channel)
                    if not channel:
                        self.db.delete_one({
                            "guild_id": i.guild,
                            "channel_id": i.channel
                        })
                        return
                    if entry.target.id == user.id:
                        embed = discord.Embed(
                            colour=0x1abc9c,
                            timestamp=entry.created_at,
                            description=
                            f"Don't lose hope just yet **{user.name}**! Stay determined!"
                        )
                        embed.set_footer(text="Unbanned")
                        embed.set_thumbnail(url=user.avatar_url)
                        embed.set_author(name="✝ Unbanned!",
                                         icon_url=guild.icon_url)
                        embed.add_field(inline=False,
                                        name="Unbanned by:",
                                        value=entry.user.mention)
                        embed.add_field(inline=False,
                                        name="Reason:",
                                        value=entry.reason)
                        embed.add_field(name="User ID", value=user.id)
                        embed.add_field(name="Unban Time",
                                        value=entry.created_at.strftime(
                                            "%#d %B %Y, %I:%M %p UTC"))

                        await channel.send(embed=embed)
Ejemplo n.º 15
0
 async def getNewEntries(guild: discord.Guild) -> dict[int, MiniEntry]:
     
     timeout = 300
     newDeleteEntries: dict[int, MiniEntry]  = {}
     entry: discord.AuditLogEntry
     async for entry in guild.audit_logs():
         timeout -= 1
         if timeout <= 0:
             break
         if not entry.action == discord.AuditLogAction.message_delete: continue
         
         newDeleteEntries[entry.id] = MiniEntry(entry.user.id, entry.target.id, entry.extra.count)
     
     return newDeleteEntries
Ejemplo n.º 16
0
    async def on_member_ban(self, guild: discord.Guild,
                            user: Union[discord.User, discord.Member]) -> None:
        """
        Called when user gets banned from a Guild.
        """

        async for entry in guild.audit_logs(action=discord.AuditLogAction.ban,
                                            limit=3):
            if entry.target == user:
                msg = (
                    f'**`{entry.user} banned {entry.target}, '
                    f"reason given: '{entry.reason.strip() if entry.reason else 'none'}'`**"
                )
                await guild.system_channel.send(msg)
                break
Ejemplo n.º 17
0
    async def get_ban_unban_data(self, action, user: Union[discord.User,
                                                           discord.Member],
                                 guild: discord.Guild):
        """
        Gets most recent Audit Log data about a ban or unban. 
        Returns Generic data if bot lacks permission to view the audit log

        Args:
            action [discord.AuditLogAction]
            user   [discord.Member, discord.User]
            guild  [discord.Guild]

        Returns
            list
        """
        past_id = discord.utils.time_snowflake(datetime.datetime.utcnow() -
                                               datetime.timedelta(seconds=10),
                                               high=True)
        data = []

        try:
            async for entry in guild.audit_logs(limit=10,
                                                action=action,
                                                oldest_first=False):
                if entry.id >= past_id and entry.target.id == user.id:

                    if data and data[4] > entry.id:
                        data = [
                            entry.target.id, entry.user.id, entry.reason[:1000]
                            or "None", entry.created_at, entry.id
                        ]
                    else:
                        data = [
                            entry.target.id, entry.user.id, entry.reason[:1000]
                            or "None", entry.created_at, entry.id
                        ]

        except discord.errors.Forbidden:
            data = [user.id, 0, "None", datetime.datetime.utcnow(), 0]
            print("[Info]  Missing view_audit_log permission.")

        except discord.errors.HTTPException:
            data = [user.id, 0, "None", datetime.datetime.utcnow(), 0]
            print(
                "[Info]  HTTP error occured, likly being rate limited or blocked by cloudflare. Restart recommended."
            )

        return data[:4]
Ejemplo n.º 18
0
    async def fetch_audit_log_entry(
            self,
            guild: discord.Guild,
            action: discord.AuditLogAction,
            *,
            target=None,
            limit: int = 50,
            check=None) -> Optional[discord.AuditLogEntry]:
        async for entry in guild.audit_logs(limit=limit, action=action):
            td = discord.utils.utcnow() - entry.created_at
            if td < timedelta(seconds=10):
                if target is not None and entry.target.id == target.id:
                    return entry

                if check is not None and check(entry):
                    return entry
Ejemplo n.º 19
0
    async def on_member_unban(self, guild: discord.Guild, unbanned: discord.User):
        mod, reason = None, "Unknown"
        await asyncio.sleep(2)
        try:
            async for entry in guild.audit_logs(limit=10, action=discord.AuditLogAction.unban):
                if entry.target == unbanned:
                    mod = entry.user
                    reason = entry.reason
        except discord.Forbidden:
            reason = '*Bot is missing Audit Log Permissions!*'
        embed = discord.Embed(title=f'{unbanned} has been unbanned! ({unbanned.id})',
                              description=f'Unbanned by: {mod.mention if mod else "Unknown"}\
        \n\nReason: {reason or "No reason specified"}', color=discord.Color.green())
        embed.set_thumbnail(url=unbanned.avatar_url)

        await self.bot.get_config(guild).log(embed)
Ejemplo n.º 20
0
 async def logging_ban(self, guild: discord.Guild, user: discord.User):
     data = self.bot.cache.logging.get(guild.id)
     if not data or data["enabled"] is not True or not data.get("member_ban") or not data.get("channel_id"):
         return
     await asyncio.sleep(2)
     entry = [entry async for entry in guild.audit_logs(limit=1, action=discord.AuditLogAction.ban)][0]
     if entry.target == user:
         channel = self.bot.get_channel(data["channel_id"])
         embed = discord.Embed(
             title="Member Banned",
             description=f"{user} ({user.id}) has been banned from {guild.name}.",
             color=discord.Color.red(),
         )
         embed.add_field(name="Responsible Moderator:", value=entry.user, inline=False)
         embed.add_field(name="Ban Reason:", value=entry.reason, inline=False)
         embed.set_thumbnail(url=user.display_avatar.url)
         await channel.send(embed=embed)
Ejemplo n.º 21
0
    async def on_guild_join(self, guild: discord.Guild):
        if guild.me.guild_permissions.view_audit_log:
            async for entry in guild.audit_logs(limit=5):
                if entry.action == 28 and entry.target.id == self.user.id:
                    invite_user = entry.user
                    break

            invite_msg = '''
    :thumbsup: **Thanks for adding me to ``ree``!**
    
            My prefix is ``sudo`` by default.
            To get started with using me, do ``sudo help`` in your server.
    
    :wave: See ya around!
                '''

            await invite_user.send(invite_msg)
Ejemplo n.º 22
0
 async def auditlog(self,
                    ctx,
                    *_,
                    guild: discord.Guild = None,
                    action: discord.AuditLogAction = None,
                    limit: int = 1000,
                    user: discord.User = None,
                    target: discord.User = None):
     guild = guild if guild is not None else ctx.guild
     async for entry in guild.audit_logs(action=action,
                                         limit=limit,
                                         user=user):
         if target is not None and entry.target.id != target.id:
             continue
         entry: discord.AuditLogEntry = entry
         await ctx.send(
             f'{entry.created_at} | {entry.user} | {entry.before} | {entry.after} | {entry.target}'
         )
Ejemplo n.º 23
0
    async def on_member_ban(self, guild: discord.Guild, user: discord.User):
        if guild.id != config.nintendoswitch:
            return

        db = mclient.bowser.puns
        await asyncio.sleep(10)  # Wait 10 seconds to allow audit log to update
        if not db.find_one({
                'user': user.id,
                'type': 'ban',
                'active': True,
                'timestamp': {
                    '$gt': time.time() - 60
                }
        }):
            # Manual ban
            audited = None
            async for entry in guild.audit_logs(
                    action=discord.AuditLogAction.ban):
                if entry.target == user:
                    audited = entry
                    break

            if audited:
                reason = audited.reason or '-No reason specified-'
                docID = await tools.issue_pun(audited.target.id,
                                              audited.user.id, 'ban', reason)

                await tools.send_modlog(self.bot,
                                        self.modLogs,
                                        'ban',
                                        docID,
                                        reason,
                                        user=user,
                                        moderator=audited.user,
                                        public=True)

        embed = discord.Embed(color=discord.Color(0xD0021B),
                              timestamp=datetime.datetime.utcnow())
        embed.set_author(name=f'{user} ({user.id})', icon_url=user.avatar_url)
        embed.add_field(name='Mention', value=f'<@{user.id}>')

        await self.serverLogs.send(':rotating_light: User banned', embed=embed)
    async def on_member_ban(self, guild: Guild, user: Union[User, Member]):
        """
        handler for member ban events; checks if this was a bot ban, and if not (ban was made by a mod in the UI), then
        a ban entry is created with presumed perma-ban duration.

        :param guild: the guild within which the ban occurred
        :param user: the user being banned
        """
        initiating_user, ban_reason = None, None
        banned_user = user
        # linearly search bans in audit log for this one
        async for ban_entry in guild.audit_logs(action=AuditLogAction.ban):
            banned_user = ban_entry.target  # type: Optional[User]
            if banned_user != user:
                continue
            initiating_user = ban_entry.user  # type: Optional[User]
            if initiating_user == self.bot.user.id:
                return  # this was a bot ban, don't need to do anything else
            ban_reason = ban_entry.reason
            break
        # if we were unable to find the audit log entry, fallback to fetching ban entry
        if ban_reason is None:
            ban_entry = await guild.fetch_ban(user)
            if ban_entry is None:
                return  # TODO: handle error
            ban_reason = ban_entry.reason
        if initiating_user is None:
            initiating_user_id = 0  # fall back to zero if ban isn't found in audit log
            initiating_username = '******'
        else:
            initiating_user_id = initiating_user.id
            initiating_username = str(initiating_user)
        # create database entry if this is not bot initiated
        if initiating_user_id != self.bot.user.id:
            # TODO: log if this creates an error
            await self._commit_user_discipline(guild, initiating_user_id,
                                               initiating_username,
                                               banned_user,
                                               BAN_DISCIPLINE_TYPE_NAME,
                                               ban_reason)
Ejemplo n.º 25
0
    async def on_member_unban(self, guild: discord.Guild, user: discord.User):
        if not guild.me.guild_permissions.view_audit_log:
            return

        channel = await self.check_log_channel(guild)
        if not channel:
            return

        async for entry in guild.audit_logs(
                action=discord.AuditLogAction.unban):
            if entry.target.id == user.id:
                reason = (
                    f'**Reason:** {entry.reason if entry.reason else "No reason was provided."}\n'\
                    f'**Moderator:** {entry.user.mention} (ID: `{entry.user.id}`)'
                )
                break

        embed = Embed(title='Member Unbanned',
                      description=reason,
                      colour=discord.Colour.green(),
                      author=user)

        await embed.send(channel)
Ejemplo n.º 26
0
    async def on_member_ban(self, guild: discord.Guild, user: discord.User):
        async for ban in guild.audit_logs(limit=20,
                                          action=discord.AuditLogAction.ban):
            if ban.target == user:
                if ban.reason:
                    reason = ban.reason
                else:
                    reason = "No reason given."
                admin = ban.user
                break
            else:
                return
        embed = discord.Embed(title=f"User banned")
        embed.add_field(
            name="User Banned",
            value=f"{user.mention} | {user.name}#{user.discriminator}")
        embed.add_field(
            name="Banned by",
            value=f"{admin.mention} | {admin.name}#{admin.discriminator}")
        embed.description = f"Reason: \n```\n{reason}\n```"

        if self.bot.logs_channel is not None:
            await self.bot.logs_channel.send(embed=embed)
Ejemplo n.º 27
0
    async def on_guild_join(self, guild: discord.Guild) -> None:
        """
        adds the guild to the database and messages the person who invited it.

        :param guild: the guild the bot was invited to
        :return: None
        """
        await Servers.create_server(guild.id)
        async for entry in guild.audit_logs(
                action=discord.AuditLogAction.bot_add):
            if entry.target == self.user:
                user: discord.User = entry.user
                await user.send(
                    "Thank you for using me on your server. Currently to run code with me on your "
                    "server you need to use the format:\n"
                    "/run\n"
                    "\\`\\`\\`language\n"
                    "code\n"
                    "\\`\\`\\`\n"
                    "If you would prefer to have all highlighted code blocks to run automatically "
                    "and not use the /run before them, "
                    "run command `/codescord auto-run on` in one of your servers text channels "
                    "the bot is allowed to read.")
                break
Ejemplo n.º 28
0
    async def on_member_ban(self, guild: discord.Guild, user: discord.User):
        """Called when a member is banned from a guild."""
        now = dt.datetime.utcnow()
        log_message = "{1.name}#{1.discriminator} (ID:{1.id}) was banned from {0.name}".format(
            guild, user)
        bot_member = guild.me  # type: discord.Member

        embed = discord.Embed(description="Banned")
        icon_url = get_user_avatar(user)
        embed.set_author(name="{0.name}#{0.discriminator}".format(user),
                         icon_url=icon_url)
        embed.timestamp = now
        embed.colour = discord.Colour(0x7a0d0d)

        # If bot can see audit log, we can get more details of the ban
        if bot_member.guild_permissions.view_audit_log:
            async for entry in guild.audit_logs(
                    limit=10,
                    reverse=False,
                    action=discord.AuditLogAction.ban,
                    after=now -
                    dt.timedelta(0, 5)):  # type: discord.AuditLogEntry
                if abs((entry.created_at - now).total_seconds()) >= 5:
                    # After is broken in the API, so we must check if entry is too old.
                    break
                if entry.target.id == user.id:
                    icon_url = get_user_avatar(entry.user)
                    embed.set_footer(text="{0.name}#{0.discriminator}".format(
                        entry.user),
                                     icon_url=icon_url)
                    if entry.reason:
                        embed.description += f"\n**Reason:** {entry.reason}"
                    log_message += f"by {entry.user.name}"
                    break
        log.warning(log_message)
        await self.send_log_message(guild, embed=embed)
Ejemplo n.º 29
0
    async def on_guild_emojis_update(self, guild: discord.Guild,
                                     before: List[discord.Emoji],
                                     after: List[discord.Emoji]):
        """Called every time an emoji is created, deleted or updated."""
        now = dt.datetime.utcnow()
        embed = discord.Embed(color=discord.Color.dark_orange())
        emoji: discord.Emoji = None
        # Emoji deleted
        if len(before) > len(after):
            emoji = discord.utils.find(lambda e: e not in after, before)
            if emoji is None:
                return
            fix = ":" if emoji.require_colons else ""
            embed.set_author(name=f"{fix}{emoji.name}{fix} (ID: {emoji.id})",
                             icon_url=emoji.url)
            embed.description = f"Emoji deleted."
            action = discord.AuditLogAction.emoji_delete
        # Emoji added
        elif len(after) > len(before):
            emoji = discord.utils.find(lambda e: e not in before, after)
            if emoji is None:
                return
            fix = ":" if emoji.require_colons else ""
            embed.set_author(name=f"{fix}{emoji.name}{fix} (ID: {emoji.id})",
                             icon_url=emoji.url)
            embed.description = f"Emoji added."
            action = discord.AuditLogAction.emoji_create
        else:
            old_name = ""
            for new_emoji in after:
                for old_emoji in before:
                    if new_emoji == old_emoji and new_emoji.name != old_emoji.name:
                        old_name = old_emoji.name
                        emoji = new_emoji
                        break
            if emoji is None:
                return
            fix = ":" if emoji.require_colons else ""
            embed.set_author(name=f"{fix}{emoji.name}{fix} (ID: {emoji.id})",
                             icon_url=emoji.url)
            embed.description = f"Emoji renamed from `{fix}{old_name}{fix}` to `{fix}{emoji.name}{fix}`"
            action = discord.AuditLogAction.emoji_update

        # Find author
        if action is not None and guild.me.guild_permissions.view_audit_log:
            async for entry in guild.audit_logs(
                    limit=10,
                    reverse=False,
                    action=action,
                    after=now -
                    dt.timedelta(0, 5)):  # type: discord.AuditLogEntry
                if abs((entry.created_at - now).total_seconds()) >= 5:
                    # After is broken in the API, so we must check if entry is too old.
                    break
                if entry.target.id == emoji.id:
                    icon_url = get_user_avatar(entry.user)
                    embed.set_footer(text="{0.name}#{0.discriminator}".format(
                        entry.user),
                                     icon_url=icon_url)
                    break
        if emoji:
            await self.send_log_message(guild, embed=embed)
Ejemplo n.º 30
0
 async def get_bot_inviter(guild: discord.Guild):
     try:
         async for i in guild.audit_logs(limit=10, action=discord.AuditLogAction.bot_add):
             return i.user
     except (discord.Forbidden, discord.HTTPException):
         return guild.owner
Ejemplo n.º 31
-1
    async def get_audit_entry(guild: discord.Guild, action: discord.AuditLogAction,
                              target: Any = None) -> Optional[discord.AuditLogEntry]:
        """Gets an audit log entry of the specified action type.

        The type of the action depends on the action.

        :param guild: The guild where the audit log will be checked.
        :param action: The action to filter.
        :param target: The target to filter.
        :return: The first matching audit log entry if found.
        """
        if not guild.me.guild_permissions.view_audit_log:
            return
        now = dt.datetime.utcnow()
        after = now - dt.timedelta(0, 5)
        async for entry in guild.audit_logs(limit=10, oldest_first=False, action=action, after=after):
            if abs((entry.created_at - now)) >= dt.timedelta(seconds=5):
                break
            if target is not None and entry.target.id == target.id:
                return entry