Exemplo n.º 1
0
async def on_member_unban(server, user):
    msgProcessStart = analytics.getEventTime()
    if common.isDiscordMainServer(server) is not True:
        return

    await discord.bot.send_message(
        discord.mod_channel(),
        "{0} **Unbanned User:** {1.mention} (Name:`{1.name}#{1.discriminator}` ID:`{1.id}`)"
        .format(common.bernardUTCTimeNow(), user))

    #check if the user was retroactively rebanned, if they were remove from said list.
    database.cursor.execute('SELECT * FROM bans_retroactive WHERE id=%s',
                            (user.id, ))
    retdb = database.cursor.fetchone()
    if retdb is not None:
        database.cursor.execute('DELETE FROM bans_retroactive WHERE id=%s',
                                (user.id, ))
        database.connection.commit()
        await discord.bot.send_message(
            discord.mod_channel(),
            "{0} **Retroactive Unban:** {1.mention} (Name:`{1.name}#{1.discriminator}` ID:`{1.id}`)"
            .format(common.bernardUTCTimeNow(), user))
        journal.update_journal_event(module=__name__,
                                     event="RETROACTIVE_UNBAN",
                                     userid=user.id,
                                     contents=retdb['reason'])

    #capture the event in the internal log
    journal.update_journal_event(
        module=__name__,
        event="ON_MEMBER_UNBAN",
        userid=user.id,
        contents="{0.name}#{0.discriminator}".format(user))

    analytics.onMemberProcessTime(msgProcessStart, analytics.getEventTime())
Exemplo n.º 2
0
async def on_message_edit(before, after):
    msgProcessStart = analytics.getEventTime()
    if common.isDiscordMainServer(before.server) is not True:
        return

    if before.content != after.content:
        if len(before.content) + len(after.content) < 1800:
            msg = "{0} **Caught Edited Message!**" \
                  "{1.author.mention} (Name:`{1.author}` ID:`{1.author.id}`) in {1.channel.mention} \n" \
                  "  Original: \"`{1.content}`\" \n\n" \
                  "  Edited: \"`{2.content}`\" \n".format(common.bernardUTCTimeNow(), before, after)
            msg_sent = await discord.bot.send_message(
                discord.messages_channel(), msg)
        else:
            msgs = [
                "{0} **Caught Edited Message! (WARNING: may be truncated)** {1.author.mention} (Name:`{1.author}` ID:`{1.author.id}`) in {1.channel.mention}"
                .format(common.bernardUTCTimeNow(), before),
                "  Original:```{0}```".format(before.content[:1980]),
                "  Edited:```{0}```".format(after.content[:1980])
            ]

            for msg in msgs:
                msg_sent = await discord.bot.send_message(
                    discord.messages_channel(), msg)

        journal_msg = "https://discordapp.com/channels/{0.channel.server.id}/{0.channel.id}/{0.id}".format(
            msg_sent)
        journal.update_journal_event(module=__name__,
                                     event="ON_MESSAGE_EDIT",
                                     userid=before.author.id,
                                     eventid=before.id,
                                     contents=journal_msg)

    analytics.onMessageProcessTime(msgProcessStart, analytics.getEventTime())
Exemplo n.º 3
0
async def on_member_update(before, after):
    msgProcessStart = analytics.getEventTime()
    if common.isDiscordMainServer(before.server) is not True:
        return

    #handle nickname changes
    if before.nick != after.nick:
        if before.nick is None:
            await discord.bot.send_message(
                discord.mod_channel(),
                "{0} **Server Nickname Added:** {1.mention} was `{1.name}` is now `{2.nick}` (ID:`{1.id}`)"
                .format(common.bernardUTCTimeNow(), before, after))
            journal.update_journal_event(
                module=__name__,
                event="ON_MEMBER_NICKNAME_ADD",
                userid=after.id,
                contents="{0.name} -> {1.nick}".format(before, after))
        elif after.nick is None:
            await discord.bot.send_message(
                discord.mod_channel(),
                "{0} **Server Nickname Removed:** {1.mention} was `{1.nick}` is now `{2.name}` (ID:`{1.id}`)"
                .format(common.bernardUTCTimeNow(), before, after))
            journal.update_journal_event(
                module=__name__,
                event="ON_MEMBER_NICKNAME_REMOVE",
                userid=after.id,
                contents="{0.nick} -> {1.name}".format(before, after))
        else:
            await discord.bot.send_message(
                discord.mod_channel(),
                "{0} **Server Nickname Changed:** {1.mention} was `{1.nick}` is now `{2.nick}` (ID:`{1.id}`)"
                .format(common.bernardUTCTimeNow(), before, after))
            journal.update_journal_event(
                module=__name__,
                event="ON_MEMBER_NICKNAME_CHANGE",
                userid=after.id,
                contents="{0.nick} -> {1.nick}".format(before, after))

    #handle username changes
    if before.name != after.name:
        await discord.bot.send_message(
            discord.mod_channel(),
            "{0} **Discord Username Changed:** {1.mention} was `{1.name}` is now `{2.name}` (ID:`{1.id}`)"
            .format(common.bernardUTCTimeNow(), before, after))
        journal.update_journal_event(module=__name__,
                                     event="ON_USERNAME_CHANGE",
                                     userid=after.id,
                                     contents="{0.name} -> {1.name}".format(
                                         before, after))

    analytics.onMemberProcessTime(msgProcessStart, analytics.getEventTime())
Exemplo n.º 4
0
async def on_member_ban(member):
    msgProcessStart = analytics.getEventTime()
    if common.isDiscordMainServer(member.server) is not True:
        return

    ignore_depart.append(member.id)
    await discord.bot.send_message(
        discord.mod_channel(),
        "{0} **Banned User:** {1.mention} (Name:`{1.name}#{1.discriminator}` ID:`{1.id}`)"
        .format(common.bernardUTCTimeNow(), member))

    #remove any invites from this user
    await invites.on_member_leave_invite_cleanup(member)

    #remove any cached subscriber information
    subscriber.on_member_remove_purgedb(member)

    #capture the event in the internal log
    journal.update_journal_event(
        module=__name__,
        event="ON_MEMBER_BANNED",
        userid=member.id,
        contents="{0.name}#{0.discriminator}".format(member))

    analytics.onMemberProcessTime(msgProcessStart, analytics.getEventTime())
Exemplo n.º 5
0
async def on_member_remove(user):
    global ignore_depart
    msgProcessStart = analytics.getEventTime()
    if common.isDiscordMainServer(user.server) is not True:
        return

    #if the user was banned or removed for another reason dont issue the depart statement
    if user.id in ignore_depart:
        ignore_depart.remove(user.id)
        return

    await discord.bot.send_message(
        discord.mod_channel(),
        "{0} **Departing User:** {1.mention} (Name:`{1.name}#{1.discriminator}` ID:`{1.id}`)"
        .format(common.bernardUTCTimeNow(), user))

    #remove any invites from this user
    await invites.on_member_leave_invite_cleanup(user)

    #remove any cached subscriber information
    subscriber.on_member_remove_purgedb(user)

    #capture the event in the internal log
    journal.update_journal_event(
        module=__name__,
        event="ON_MEMBER_REMOVE",
        userid=user.id,
        contents="{0.name}#{0.discriminator}".format(user))

    analytics.onMemberProcessTime(msgProcessStart, analytics.getEventTime())
Exemplo n.º 6
0
async def scheduler_unban_member(work):
    now = int(time.time())
    logger.info(
        "UNBAN_MEMBER JOB ID {0[id]} BANNED BY {0[id_invoker]} BAN HAS EXPIRED, UNBANNING {0[id_targeted]}"
        .format(work))

    #call the unban
    unban_status_discord = await common.unban_id(str(work['id_targeted']))
    if unban_status_discord:
        logger.info(
            "UNBAN_MEMBER JOB ID {0[id]} USER ID {0[id_targeted]} BAN SUCCESSFULLY REMOVED FROM DISCORD."
            .format(work))

        #update the modlog channel
        await discord.bot.send_message(
            discord.mod_channel(),
            "{0} **Scheduled Unban:** ID:`{1[id_targeted]}`)".format(
                common.bernardUTCTimeNow(), work))

        #set a user journal record the unban has happened
        journal.update_journal_event(
            module=__name__,
            event="ON_MEMBER_UNBAN_SCHEDULED",
            userid=work['id_targeted'],
            contents="SCHEDULER JOBID: {0[id]}".format(work))

    else:
        logger.warn(
            "UNBAN_MEMBER JOB ID {0[id]} USER ID {0[id_targeted]} BAN WAS NOT REMOVED FROM DISCORD, USER ALREADY UNBANNED?"
            .format(work))

    await scheduler_mark_work_done(work)
Exemplo n.º 7
0
async def on_message(message):
    msgProcessStart = analytics.getEventTime()

    #process bot DMs into the mod channel if its not the owner.
    if message.server is None:
        logger.info(
            "on_message() got DM from {0.author.name} (ID:{0.author.id}) containing {0.clean_content}"
            .format(message))
        if message.author.id != config.cfg['bernard']['owner']:
            await discord.bot.send_message(
                discord.mod_channel(),
                "{0} **New DM:** {1.author.mention} sent: `{1.clean_content}` "
                .format(common.bernardUTCTimeNow(), message))

    #only reply to the guild set in config file
    try:
        if common.isDiscordMainServer(message.server) is not True:
            await discord.bot.process_commands(message)
            return
    except AttributeError:  #process messages anyway
        await discord.bot.process_commands(message)
        return

    # start looking for gamer words / banned slurs
    if regulator.allow_automod(message):
        await gamerwords.slur_filter(message)

    #get some basic stats of message sending
    analytics.setMessageCounter(message)

    #handoff the message to a function dedicated to its feature see also https://www.youtube.com/watch?v=ekP0LQEsUh0 DO NOT AUDIT OURSELVES BAD THINGS HAPPEN
    if message.author.id != discord.bot.user.id:
        await auditing.attachments(message)  #message attachment auditing
        await auditing.discord_invites(message)  #discord invites
        await auditing.blacklisted_domains(message)  #url blacklisting

    #print the message to the console
    if config.cfg['bernard']['debug']:
        logger.info(
            "Channel: {0.channel} User: {0.author} (ID:{0.author.id}) Message: {0.content}"
            .format(message))

    #handle message processing per rate limit, do not reply to ourselves
    if analytics.rateLimitAllowProcessing(message):
        if message.author.id != discord.bot.user.id:
            await discord.bot.process_commands(message)

    #set the rate limit
    if message.author.id == discord.bot.user.id:
        analytics.rateLimitNewMessage(message.channel.id,
                                      analytics.getEventTime())

    #message processing timings
    analytics.onMessageProcessTime(msgProcessStart, analytics.getEventTime())
Exemplo n.º 8
0
async def journal_events_cleanup():
    await discord.bot.wait_until_ready()
    while not discord.bot.is_closed:
        logger.info(
            "Starting background task journal_events_cleanup() - Interval {0}".
            format(config.cfg['housekeeping']['journal_events_cleanup']
                   ['interval']))

        #get the current time, and our tareted lookup time for the database query
        utc_now = common.bernardUTCEpochTimeNow()
        seconds_grace = 86400 * config.cfg['housekeeping'][
            'journal_events_cleanup']['days_to_keep']
        db_cutoff = int(utc_now - seconds_grace)
        logger.info(
            "journal_events_cleanup() attempting purge of deleted messages older than {0} seconds ({1}) days"
            .format(
                seconds_grace, config.cfg['housekeeping']
                ['journal_events_cleanup']['days_to_keep']))

        #delete the records for deleted and edited messages over configured date
        database.cursor.execute(
            "DELETE from journal_events where event='ON_MESSAGE_DELETE' OR event = 'ON_MESSAGE_EDIT' and time<%s order by time desc",
            (db_cutoff, ))
        deleted_records_count = database.cursor.rowcount

        #log internally and update the modlog channel
        if deleted_records_count > 0:
            logger.warn(
                "journal_events_cleanup() purging {0} deleted messages from journal_events"
                .format(deleted_records_count))
            await discord.bot.send_message(
                discord.mod_channel(),
                "{0} **Pruned Deleted Messages:** {1} messages removed from journal for being older than {2} days"
                .format(
                    common.bernardUTCTimeNow(), deleted_records_count,
                    config.cfg['housekeeping']['journal_events_cleanup']
                    ['days_to_keep']))
        else:
            logger.warn(
                "journal_events_cleanup() nothing to delete at this time.")

        await asyncio.sleep(
            config.cfg['housekeeping']['journal_events_cleanup']['interval'])
Exemplo n.º 9
0
async def purge_inactive_users():
    await discord.bot.wait_until_ready()
    while not discord.bot.is_closed:
        job_start = analytics.getEventTime()
        logger.info(
            "Starting background task purge_inactive_users() - Interval {0}".
            format(config.cfg['housekeeping']['purge_inactive_users']
                   ['interval']))

        est = await discord.bot.estimate_pruned_members(
            server=discord.objectFactory(config.cfg['discord']['server']),
            days=config.cfg['housekeeping']['purge_inactive_users']
            ['inactive_days'])
        if est > 0:
            #send the cleanup
            pruned = await discord.bot.prune_members(
                server=discord.objectFactory(config.cfg['discord']['server']),
                days=config.cfg['housekeeping']['purge_inactive_users']
                ['inactive_days'])

            #notify via mod room and console log whos getting purged
            logger.warn(
                "Purging {0} inactive users via purge_inactive_users() background job"
                .format(pruned))
            await discord.bot.send_message(
                discord.mod_channel(),
                "{0} **Pruned Inactive Users:** {1} users removed for inactivity of {2} days"
                .format(
                    common.bernardUTCTimeNow(), pruned,
                    config.cfg['housekeeping']['purge_inactive_users']
                    ['inactive_days']))

        logger.info(
            "Sleeping background task purge_inactive_users() - Interval {0}".
            format(config.cfg['housekeeping']['purge_inactive_users']
                   ['interval']))
        journal.update_journal_job(module=__name__,
                                   job="purge_inactive_users",
                                   start=job_start,
                                   result=est)
        await asyncio.sleep(
            config.cfg['housekeeping']['purge_inactive_users']['interval'])
Exemplo n.º 10
0
async def on_message_delete(message):
    msgProcessStart = analytics.getEventTime()
    if common.isDiscordMainServer(message.server) is not True:
        return

    if message.author.id in IGNORE_IDS:
        logger.info(
            "on_message_delete() ignoring deleted message user id is in IGNORE_IDS variable"
        )
        return

    if message.attachments and message.content == "":
        msg = "{0.author.mention} (Name:`{0.author}` ID:`{0.author.id}`) in {0.channel.mention} \n Deleted Attachment: `{0.attachments[0][filename]}` \n URL: <{0.attachments[0][url]}>".format(
            message)
        journal_msg = "Attachment: {0.attachments[0][filename]} Size: {0.attachments[0][size]}".format(
            message)
    elif message.attachments and message.content != "":
        msg = "{0.author.mention} (Name:`{0.author}` ID:`{0.author.id}`) in {0.channel.mention} \n Message: \"`{0.content}`\" \n\n Deleted Attachment: `{0.attachments[0][filename]}` \n URL: <{0.attachments[0][url]}>".format(
            message)
        journal_msg = "Text: {0.content} Attachment: {0.attachments[0][filename]} Size: {0.attachments[0][size]}".format(
            message)
    else:
        msg = "{0.author.mention} (Name:`{0.author}` ID:`{0.author.id}`) in {0.channel.mention} \n Message: \"`{0.content}`\" \n\n".format(
            message)
        journal_msg = "Text: {0.content}".format(message)

    await discord.bot.send_message(
        discord.messages_channel(),
        "{0} **Caught Deleted Message!** {1}".format(
            common.bernardUTCTimeNow(), msg))

    journal.update_journal_event(module=__name__,
                                 event="ON_MESSAGE_DELETE",
                                 userid=message.author.id,
                                 eventid=message.id,
                                 contents=journal_msg)

    analytics.onMessageProcessTime(msgProcessStart, analytics.getEventTime())
Exemplo n.º 11
0
async def on_member_join(user):
    msgProcessStart = analytics.getEventTime()
    if common.isDiscordMainServer(user.server) is not True:
        return

    #the user got here somehow, get the discord.Invite object we *think* they came from
    invite = await invites.on_member_join_attempt_invite_source(user)

    #if the user is retroactively banned, handle it and issue the ban
    database.cursor.execute('SELECT * FROM bans_retroactive WHERE id=%s',
                            (user.id, ))
    retdb = database.cursor.fetchone()

    print(user.id, retdb)

    if retdb is not None:
        ignore_depart.append(user.id)
        await common.ban_verbose(
            user, "RETROACTIVE_BAN_VIA_BOT_DB - '{}'".format(retdb['reason']))
        await discord.bot.send_message(
            discord.mod_channel(),
            "{0} **Retroactive Ban:** {1.mention} (Name:`{1.name}#{1.discriminator}` ID:`{1.id}` REASON: `{2}`)"
            .format(common.bernardUTCTimeNow(), user, retdb['reason']))
        journal.update_journal_event(module=__name__,
                                     event="RETROACTIVE_BAN",
                                     userid=user.id,
                                     contents=retdb['reason'])
        return

    ##send the message to the admin defined channel
    await discord.bot.send_message(
        discord.mod_channel(),
        "{0} **New User:** {1.mention} (Name:`{1.name}#{1.discriminator}` ID:`{1.id}`) **Account Age:** {2} **From:** `{3}`"
        .format(common.bernardUTCTimeNow(), user,
                common.bernardAccountAgeToFriendly(user), invite))

    #handle kicking / banning of "new" accounts
    if config.cfg['auditing']['account_age_min']['enable']:
        logger.info(
            "on_member_join() Account age minimum is enabled: Minimum account age required {} minutes."
            .format(
                config.cfg['auditing']['account_age_min']['min_age_required']))
        account_age_minutes = int((datetime.datetime.utcnow().timestamp() -
                                   user.created_at.timestamp()) / 60)

        #if the users account is too new lets apply logic to kick or ban
        if account_age_minutes <= config.cfg['auditing']['account_age_min'][
                'min_age_required']:
            journal.update_journal_event(
                module=__name__,
                event="ON_MEMBER_JOIN_ACCOUNT_TOONEW",
                userid=user.id,
                contents="{0.name}#{0.discriminator} - {1} mins old".format(
                    user, account_age_minutes))
            #await discord.bot.send_message(user, config.cfg['auditing']['account_age_min']['enforcement_dm'])
            await asyncio.sleep(3)
            if config.cfg['auditing']['account_age_min'][
                    'enforcement'] == "ban":
                logger.warn(
                    "on_member_join() BANNING ID {0.id} for being too new. Account age was {1} minutes, config is {2} minute age.."
                    .format(
                        user, account_age_minutes, config.cfg['auditing']
                        ['account_age_min']['min_age_required']))
                await common.ban_verbose(
                    user, "BOT_BAN_VIA_ACCOUNT_TOONEW - {} min old".format(
                        account_age_minutes))
            else:
                logger.warn(
                    "on_member_join() KICKING ID {0.id} for being too new. Account age was {1} minutes, config is {2} minute age."
                    .format(
                        user, account_age_minutes, config.cfg['auditing']
                        ['account_age_min']['min_age_required']))
                await discord.bot.kick(user)

    #do a subscriber check and assign any roles on joining
    check_sub = subscriber.subscriber_update(user)
    await check_sub.update_subscriber()

    #capture the event in the internal log
    journal.update_journal_event(
        module=__name__,
        event="ON_MEMBER_JOIN",
        userid=user.id,
        contents="{0.name}#{0.discriminator}".format(user))

    analytics.onMemberProcessTime(msgProcessStart, analytics.getEventTime())