def on_message_create(self, event): if event.author.id == self.state.me.id: return if event.message.author.bot: return # Lineralize events by guild ID to prevent spamming events if event.guild.id not in self.guild_locks: self.guild_locks[event.guild.id] = Semaphore() self.guild_locks[event.guild.id].acquire() tags = {'guild_id': event.guild.id, 'channel_id': event.channel.id} with timed('rowboat.plugin.spam.duration', tags=tags): try: member = event.guild.get_member(event.author) if not member: self.log.warning( 'Failed to find member for guild id %s and author id %s', event.guild.id, event.author.id) return level = int( self.bot.plugins.get('CorePlugin').get_level( event.guild, event.author)) # TODO: We should linearize the work required for all rules in one go, # we repeat all the work in each rule which sucks. for rule in event.config.compute_relevant_rules(member, level): self.check_message_simple(event, member, rule) except Violation as v: self.violate(v) finally: self.guild_locks[event.guild.id].release()
def on_message_create(self, event, author=None): author = author or event.author if author.id == self.state.me.id: return configs = list(self.compute_relevant_configs(event, author)) if not configs: return tags = {'guild_id': event.guild.id, 'channel_id': event.channel.id} with timed('rowboat.plugin.censor.duration', tags=tags): try: # TODO: perhaps imap here? how to raise exception then? for config in configs: if config.filter_zalgo: self.filter_zalgo(event, config) if config.filter_invites: self.filter_invites(event, config) if config.filter_domains: self.filter_domains(event, config) if config.blocked_words: self.filter_blocked_words(event, config) except Censorship as c: self.bot.plugins.get('ModLogPlugin').log_action_ext( Actions.CENSORED, event, c=c) self.bot.plugins.get('ModLogPlugin').create_debounce(event, author.id, 'censor') event.delete()
def on_message_create(self, event, author=None): author = author or event.author if author.id == self.state.me.id: return if event.message.author.bot or rdb.sismember('ignored_channels', event.message.channel_id): return if not event.channel.type == 1: if not event.message.channel.get_permissions(self.state.me).can( Permissions.SEND_MESSAGES): return if event.webhook_id: return configs = list(self.compute_relevant_configs(event, author)) if not configs: return tags = {'guild_id': event.guild.id, 'channel_id': event.channel.id} with timed('rowboat.plugin.censor.duration', tags=tags): try: # TODO: perhaps imap here? how to raise exception then? for config in configs: if config.filter_zalgo: self.filter_zalgo(event, config) if config.filter_invites: self.filter_invites(event, config) if config.filter_domains: self.filter_domains(event, config) if config.blocked_words or config.blocked_tokens: self.filter_blocked_words(event, config) except Censorship as c: self.call( 'ModLogPlugin.create_debounce', event, ['MessageDelete'], message_id=event.message.id, ) try: event.delete() self.call('ModLogPlugin.log_action_ext', Actions.CENSORED, event.guild.id, e=event, c=c) except APIException: self.log.exception('Failed to delete censored message: ')
def on_message_create(self, event, author=None): author = author or event.author if author.id == self.state.me.id: return if event.message.author.bot or event.channel.type is ChannelType.DM: return if event.webhook_id: return configs = list(self.compute_relevant_configs(event, author)) if not configs: return tags = {'guild_id': event.guild.id, 'channel_id': event.channel.id} with timed('rowboat.plugin.censor.duration', tags=tags): try: for config in configs: if config.filter_zalgo: self.filter_zalgo(event, config) if config.filter_invites: self.filter_invites(event, config) if config.filter_domains: if str(event.channel.id) not in config.domain_filter_ignored_channels: self.filter_domains(event, config) if config.blocked_words or config.blocked_tokens: self.filter_blocked_words(event, config) except Censorship as c: self.call( 'ModLogPlugin.create_debounce', event, ['MessageDelete'], message_id=event.message.id, ) try: event.delete() self.call( 'ModLogPlugin.log_action_ext', Actions.CENSORED, event.guild.id, e=event, c=c) except: self.log.exception('Failed to delete censored message: ')
def on_message_create(self, event): """ This monstrosity of a function handles the parsing and dispatching of commands. """ # Ignore messages sent by bots if event.message.author.bot: return # If this is message for a guild, grab the guild object if hasattr(event, 'guild') and event.guild: guild_id = event.guild.id elif hasattr(event, 'guild_id') and event.guild_id: guild_id = event.guild_id else: guild_id = None guild = self.guilds.get(event.guild.id) if guild_id else None config = guild and guild.get_config() # If the guild has configuration, use that (otherwise use defaults) if config and config.commands: commands = list( self.bot.get_commands_for_message(config.commands.mention, {}, config.commands.prefix, event.message)) elif guild_id: # Otherwise, default to requiring mentions commands = list( self.bot.get_commands_for_message(True, {}, '', event.message)) else: if ENV != 'prod': if not event.message.content.startswith(ENV + '!'): return event.message.content = event.message.content[len(ENV) + 1:] # DM's just use the commands (no prefix/mention) commands = list( self.bot.get_commands_for_message(False, {}, '', event.message)) # If we didn't find any matching commands, return if not len(commands): return event.user_level = self.get_level(event.guild, event.author) if event.guild else 0 # Grab whether this user is a global admin # TODO: cache this global_admin = rdb.sismember('global_admins', event.author.id) # Iterate over commands and find a match for command, match in commands: if command.level == -1 and not global_admin: continue level = command.level if guild and not config and command.triggers[0] != 'setup': continue elif config and config.commands and command.plugin != self: overrides = {} for obj in config.commands.get_command_override(command): overrides.update(obj) if overrides.get('disabled'): continue level = overrides.get('level', level) if not global_admin and event.user_level < level: continue with timed('rowboat.command.duration', tags={ 'plugin': command.plugin.name, 'command': command.name }): try: command_event = CommandEvent(command, event.message, match) command_event.user_level = event.user_level command.plugin.execute(command_event) except CommandResponse as e: event.reply(e.response) except: tracked = Command.track(event, command, exception=True) self.log.exception('Command error:') with self.send_control_message() as embed: embed.title = u'Command Error: {}'.format(command.name) embed.color = 0xff6961 embed.add_field(name='Author', value='({}) `{}`'.format( event.author, event.author.id), inline=True) embed.add_field(name='Channel', value='({}) `{}`'.format( event.channel.name, event.channel.id), inline=True) embed.description = '```{}```'.format(u'\n'.join( tracked.traceback.split('\n')[-8:])) return event.reply( '<:{}> something went wrong, perhaps try again later'. format(RED_TICK_EMOJI)) Command.track(event, command) # Dispatch the command used modlog event if config: modlog_config = getattr(config.plugins, 'modlog', None) if not modlog_config: return self._attach_local_event_data(event, 'modlog', event.guild.id) plugin = self.bot.plugins.get('ModLogPlugin') if plugin: plugin.log_action(Actions.COMMAND_USED, event) return
def on_message_create(self, event): """ This monstrosity of a function handles the parsing and dispatching of commands. """ # Ignore messages sent by bots if event.message.author.bot: return if rdb.sismember('ignored_channels', event.message.channel_id): return # If this is message for a guild, grab the guild object if hasattr(event, 'guild') and event.guild: guild_id = event.guild.id elif hasattr(event, 'guild_id') and event.guild_id: guild_id = event.guild_id else: guild_id = None guild = self.guilds.get(event.guild.id) if guild_id else None config = guild and guild.get_config() # If the guild has configuration, use that (otherwise use defaults) if config and config.commands: commands = list( self.bot.get_commands_for_message(config.commands.mention, {}, config.commands.prefix, event.message)) elif guild_id: # Otherwise, default to requiring mentions commands = list( self.bot.get_commands_for_message(True, {}, '', event.message)) else: if ENV != 'prod': if not event.message.content.startswith(ENV + '!'): return event.message.content = event.message.content[len(ENV) + 1:] # DM's just use the commands (no prefix/mention) commands = list( self.bot.get_commands_for_message(False, {}, '', event.message)) # If we didn't find any matching commands, return if not len(commands): return event.user_level = self.get_level(event.guild, event.author) if event.guild else 0 # Grab whether this user is a global admin # TODO: cache this global_admin = rdb.sismember('global_admins', event.author.id) # Iterate over commands and find a match for command, match in commands: if command.level == -1 and not global_admin: continue level = command.level if guild and not config and command.triggers[0] != 'setup': continue elif config and config.commands and command.plugin != self: overrides = {} for obj in config.commands.get_command_override(command): overrides.update(obj) if overrides.get('disabled'): continue level = overrides.get('level', level) if not global_admin and event.user_level < level: continue with timed('rowboat.command.duration', tags={ 'plugin': command.plugin.name, 'command': command.name }): try: command.plugin.execute( CommandEvent(command, event.message, match)) except CommandResponse as e: return event.reply(e.response) except: event.reply( '<:{}> something went wrong, perhaps try again later'. format(RED_TICK_EMOJI)) self.log.exception('Command error:') Message.update(command=command.plugin.name + ':' + command.name).where( (Message.id == event.message.id)).execute() # Dispatch the command used modlog event if config: event.config.set(getattr(config.plugins, 'modlog', None)) if not event.config: return plugin = self.bot.plugins.get('ModLogPlugin') if plugin: plugin.log_action(Actions.COMMAND_USED, event) return