def command_check_suggestion(msg: twitchirc.ChannelMessage): cd_state = main.do_cooldown('check_suggestion', msg, global_cooldown=0, local_cooldown=30) if cd_state: return t = main.delete_spammer_chrs(msg.text).split(' ') if len(t) == 1: return f'@{msg.user}, Usage: check_suggestion <ID> or check_suggestion.' target = t[1] if target.isnumeric(): target = int(target) with main.session_scope() as session: suggestion = session.query(Suggestion).filter(Suggestion.id == target).first() if suggestion is None: return f'@{msg.user} Suggestion id {target!r} not found.' else: return (f'@{msg.user} ' f'{suggestion.humanize(suggestion.author.last_known_username == msg.user)}') else: with main.session_scope() as session: user = main.User.get_by_message(msg, no_create=True) if user is None: return f'@{msg.user}, You are a new user, you don\'t have any suggestions.' suggestions = (session.query(Suggestion) .filter(Suggestion.author == user) .filter(Suggestion.state.notin_([Suggestion.SuggestionState.done, Suggestion.SuggestionState.rejected, Suggestion.SuggestionState.not_a_suggestion]))) return (f'@{msg.user} Your suggestions: ' f'{", ".join([f"{s.id} ({s.nice_state()})" for s in suggestions])}')
def c_pyramid(self, msg: twitchirc.ChannelMessage): if not self._get_pyramid_enabled(msg.channel): return f'@{msg.user}, This command is disabled here.' cd_state = main.do_cooldown('pyramid', msg, global_cooldown=60, local_cooldown=60) if cd_state: return t = main.delete_spammer_chrs(msg.text).split(' ', 1) if len(t) == 1: return f'@{msg.user}, Usage: pyramid <size> <text...>' args = t[1].rstrip() size = '' for arg in args.split(' '): arg: str if arg.isnumeric(): size = arg break # prefer first number! if size != '': args: str = args.replace(size, '', 1).rstrip() + ' ' size = int(size) if not args.strip(' '): return f'@{msg.user}, Nothing to send. NaM' for i in range(1, size): main.bot.send(msg.reply(args * i)) for i in range(size, 0, -1): main.bot.send(msg.reply(args * i))
def c_ping_output(self, msg: twitchirc.ChannelMessage): cd_state = main.do_cooldown('ping_optout', msg, global_cooldown=0, local_cooldown=30) if cd_state: return if msg.user in self.ping_optouts: del self.ping_optouts[msg.user] return f'@{msg.user}, you can be pinged by the bot now.' args = main.delete_spammer_chrs(msg.text).rstrip(' ').split(' ', 1) if len(args) == 1: main.bot.send( msg.reply( f'@{msg.user}, please select a mode. Available modes: ' f'replacement (will replace ping with [PING]), ' f'invisibles (will add invisible characters to pings), ' f'no@ (will remove the @)')) return args = args[1] if self._in(['replace', 'replacement', 'repl', 'r'], args.lower()): mode = OPTOUT_MODE_REPLACEMENT elif self._in( ['invis', 'invisibles', 'invisible', 'characters', 'i', 'chars'], args.lower()): mode = OPTOUT_MODE_INVISIBLE_CHARACTERS elif self._in(['at', 'noat', '@', 'no@', 'n@', 'no_at'], args.lower()): mode = OPTOUT_MODE_NO_AT # noinspection PyUnboundLocalVariable self.ping_optouts[msg.user] = mode return f'@{msg.user}, i will no longer ping you :)'
async def c_nuke(self, msg: twitchirc.ChannelMessage): try: args = arg_parser.parse_args( main.delete_spammer_chrs(msg.text), { 'regex': str, 'perma': bool, 'timeout': datetime.timedelta, 'search': datetime.timedelta, 'dry-run': bool, 'force': bool }) except arg_parser.ParserError as e: return f'@{msg.user}, error: {e.message}' arg_parser.check_required_keys( args, ('regex', 'timeout', 'search', 'perma', 'dry-run', 'force')) if args['regex'] is ... or args['timeout'] is ... or args[ 'search'] is ...: return f'@{msg.user}, regex, timeout and search are required parameters' if args['perma'] is ...: args['perma'] = False try: r = regex.compile(args['regex']) except Exception as e: return f'@{msg.user}, error while compiling regex: {e}' results = plugin_chat_cache.find_messages( msg.channel, expr=r, min_timestamp=time.time() - args['search'].total_seconds()) if not results: return f'@{msg.user}, found no messages matching the regex.' else: return await self.nuke_from_messages(args, msg, results)
def command_resolve_suggestion(msg: twitchirc.ChannelMessage): t = main.delete_spammer_chrs(msg.text).split(' ', 3) if len(t) < 3: return f'@{msg.user}, Usage: resolve_suggestion <ID> <state> [notes...]' if not t[1].isnumeric(): return f'@{msg.user}, Unknown suggestion {t[1]!r}.' target = int(t[1]) state_names = [i.name for i in Suggestion.SuggestionState] if t[2] in state_names: state = Suggestion.SuggestionState[t[2]] else: main.bot.send( msg.reply( f'@{msg.user}, Invalid state: {t[2]!r}. Choose between ' f'{", ".join([repr(i.name) for i in Suggestion.SuggestionState])}' )) return if len(t) == 4: notes = t[3] else: notes = None with main.session_scope() as session: suggestion = session.query(Suggestion).filter( Suggestion.id == target).first() suggestion.state = state if notes is not None: suggestion.notes = notes session.add(suggestion) main.bot.send( msg.reply(f'@{msg.user} Modified suggestion id {target!r}, ' f'new state {state}, ' f'new notes {notes}.'))
def chan_msg_handler(self, event: str, msg: twitchirc.ChannelMessage): if msg.user in ['supibot', 'mm2pl'] and msg.text.startswith('HONEYDETECTED RECONNECTED') \ and msg.channel == 'supinic': random_msg = random.choice(RECONNECTION_MESSAGES) while '{ping}' in random_msg: random_msg = random_msg.replace( '{ping}', random.choice(self.random_pings), 1) main.bot.send(msg.reply(random_msg)) if msg.channel in ['supinic', 'mm2pl'] and msg.user in ['thepositivebot', 'linkusbanned'] \ and msg.text.startswith('\x01ACTION [Cookies]'): m = COOKIE_PATTERN.findall( main.delete_spammer_chrs(msg.text.replace('\x01ACTION ', ''))) if m and m[0][1].lower() in self.cookie_optin: time_ = self._time_from_rank(msg.text) main.bot.send( msg.reply( f'$remind {m[0][1].lower()} cookie :) in {time_}')) elif not m: log('warn', f'matching against regex failed: {msg.text!r}') if msg.text.startswith('$ps sneeze') and msg.channel in [ 'supinic', 'mm2pl' ]: self._sneeze = (time.time() + self.cooldown_timeout, msg) if msg.user == 'supibot' and self._sneeze[1] is not None and ( msg.text.startswith( self._sneeze[1].user + ', The playsound\'s cooldown has not passed yet! Try again in' ) or msg.text.startswith(self._sneeze[1].user + ', Playsounds are currently disabled!')): # don't respond if the playsound didn't play self._sneeze = (-1, None)
def command_manage_blacklists(self, msg: twitchirc.ChannelMessage): argv = main.delete_spammer_chrs(msg.text).rstrip(' ').split(' ', 1) if len(argv) == 1: return f'@{msg.user}, {plugin_help.all_help[plugin_help.SECTION_COMMANDS]["plonk"]}' text = argv[1] kw = self._parse_blacklist_args(text, msg) if isinstance(kw, str): return kw if kw['command'] is None: return f'@{msg.user}, No `command:...` provided.' if kw['user'] is None: return f'@{msg.user}, No `user:...` provided.' with main.session_scope() as session: if kw['scope'] == 'global': targets = main.User.get_by_name( kw['user'], session) if kw['user'] is not True else None if targets is None or len(targets) == 1: obj = BlacklistEntry( target=targets[0] if targets is not None else targets, command=kw['command'] if kw['command'] is not True else None, channel=None, expires_on=kw['expires'], is_active=True) blacklists.append(obj) session.add(obj) elif len(targets) == 0: return f'@{msg.user} Failed to find user: {kw["user"]}' else: return f'@{msg.user} Found multiple users possible with name {kw["user"]}' else: for ch in kw['scope']: targets = main.User.get_by_name( kw['user'], session) if kw['user'] is not True else None channels = main.User.get_by_name(ch, session) if len(channels) == 1: if targets is None or len(targets) == 1: obj = BlacklistEntry( target=targets[0] if targets is not None else targets, command=kw['command'] if kw['command'] is not True else None, channel=channels[0], expires_on=kw['expires'], is_active=True) blacklists.append(obj) session.add(obj) elif len(targets) == 0: return f'@{msg.user} Failed to find user: {kw["user"]}' else: return f'@{msg.user} Found multiple users possible with name {kw["user"]}' elif len(channels) == 0: return f'@{msg.user} Failed to find channel: {ch}' elif len(channels) > 1: return f'@{msg.user} Found multiple channels possible with name {ch}' return f'@{msg.user}, Added blacklist for command {kw["command"]} with scope {kw["scope"]} for {kw["user"]}'
async def c_replay(self, msg: twitchirc.ChannelMessage): try: args = arg_parser.parse_args( main.delete_spammer_chrs(msg.text), { 'time': datetime.timedelta, 'channel': str, arg_parser.POSITIONAL: str # ignore }) except arg_parser.ParserError as e: return f'@{msg.user}, Error: {e}' if args['time'] is ...: args['time'] = datetime.timedelta(seconds=30) if args['channel'] is ...: args['channel'] = msg.channel if args['channel'] != msg.channel: j_data = await self.get_user(args['channel']) if 'data' not in j_data: return f'@{msg.user}, API error (in get-users).' if len(j_data['data']) == 0: return f'@{msg.user}, failed to find user.' user = j_data['data'][0]['id'] else: user = msg.flags['room-id'] async with aiohttp.request( 'get', 'https://api.twitch.tv/helix/videos', params={ 'user_id': user, 'sort': 'time', 'first': 1 }, headers={ 'Authorization': f'Bearer {main.twitch_auth.json_data["access_token"]}', 'Client-ID': main.twitch_auth.json_data["client_id"] }) as request: j_data = await request.json() print(j_data) if 'data' not in j_data: return f'@{msg.user}, API error (in get-videos).' if len(j_data['data']) == 0: return f'@{msg.user}, failed to find stream.' length = arg_parser.handle_typed_argument( j_data['data'][0]['duration'], datetime.timedelta) if args['time'] > length: return f'@{msg.user}, FeelsWeirdMan It is not possible to create a replay of before the stream started.' t: datetime.timedelta = length - args['time'] return j_data['data'][0]['url'] + f'?t={math.floor(t.seconds / 3600):0>.0f}h' \ f'{math.floor((t.seconds % 3600) / 60):0>.0f}m' \ f'{math.floor((t.seconds % 3600) % 60):0>.0f}s'
async def c_hastebin(self, msg: twitchirc.ChannelMessage): cd_state = main.do_cooldown('hastebin', msg, global_cooldown=0, local_cooldown=30) if cd_state: return data = main.delete_spammer_chrs(msg.text).rstrip(' ').split(' ', 1)[1] link = await self.upload(data) return f'@{msg.user} Here\'s your hastebin link {self.hastebin_addr}{link}'
def command_suggest(msg: twitchirc.ChannelMessage): cd_state = main.do_cooldown('suggest', msg, global_cooldown=0, local_cooldown=30) if cd_state: return t = main.delete_spammer_chrs(msg.text).rstrip(' ').split(' ', 1) if len(t) == 1: return f'@{msg.user}, Usage: suggest <text...>' s = Suggestion(author=main.User.get_by_message(msg), text=t[1], state=Suggestion.SuggestionState.new, notes='<no notes>') with main.session_scope() as session: session.add(s) return f'@{msg.user} Suggestion saved, hopefully. ID: {s.id}'
async def command_debug(msg: twitchirc.ChannelMessage): if isinstance(msg, twitchirc.ChannelMessage): return f'@{msg.user}, This command is only available in whispers :)' argv = arg_parser.parse_args( main.delete_spammer_chrs(msg.text).rstrip(' '), { 0: str, 1: str }) if argv[0] is ...: return f'debug what?' debugee_type = argv[0] print(repr(debugee_type), debugee_type == 'command', debugee_type == 'user', debugee_type == 'me', debugee_type in ('user', 'me')) if debugee_type == 'command': if argv[1] is ...: return f'debug which command?' cmd_name = argv[1] matches = list( filter(lambda c: c.chat_command == cmd_name, main.bot.commands)) if not matches: fake_msg = twitchirc.ChannelMessage(cmd_name, msg.user, msg.channel, parent=main.bot) matches = list( filter( lambda c: c.matcher_function and c.matcher_function( fake_msg, c), main.bot.commands)) if not matches: return f'Unknown command {cmd_name}' if len(matches) == 1: return _debug_command(matches[0]) else: return f'@{msg.user}, {len(matches)} found.' elif debugee_type in ('user', 'me'): if argv[1] is ... and debugee_type != 'me': return f'@{msg.user}, how do I debug?' if debugee_type == 'me': argv[1] = msg.user users = main.User.get_by_name(argv[1]) if users: return _debug_user(users[0]) else: return f'@{msg.user}, couldn\'t find the target user.' else: return f'@{msg.user}, how to debug {debugee_type!r}?'
async def c_nuke_url(self, msg: twitchirc.ChannelMessage): try: args = arg_parser.parse_args(main.delete_spammer_chrs(msg.text), { 'dry-run': bool, 'url': str, 'perma': bool, 'force': bool, 'timeout': datetime.timedelta, 'hastebin': bool }, defaults={ 'dry-run': False, 'perma': False, 'hastebin': False, 'timeout':..., 'force': False }) except arg_parser.ParserError as e: return f'@{msg.user}, error: {e.message}' if args['url'] is ... or (args['timeout'] is ... and not args['perma']): print(args) return f'@{msg.user}, url, timeout (or perma) are required parameters' url = args['url'] if url.startswith(plugin_hastebin.hastebin_addr): url = url.replace(plugin_hastebin.hastebin_addr, plugin_hastebin.hastebin_addr + 'raw/') async with aiohttp.request('get', url) as req: if req.status != 200: return f'@{msg.user}, failed to download user list :(' if req.content_type == 'text/plain': users, reasons = self.parse_user_list( (await req.text('utf-8')).replace('\r\n', '\n').replace( '$(newline)', '\n')) while '' in users: users.remove('') return await self.nuke( args, msg, users, force_nuke=args['force'], disable_hastebinning=not args['hastebin'], reasons=reasons) else: return f'Refusing to use data, bad content type: {req.content_type}, expected text/plain'
def command_convert(msg: twitchirc.ChannelMessage): argv = shlex.split(main.delete_spammer_chrs(msg.text)) if len(argv) == 1: return f"@{msg.user} " + p_conv.format_usage() args = p_conv.parse_args(argv[1:]) if args is None: return f"@{msg.user} " + p_conv.format_usage() number, unit_from = find_unit_with_data(args.data) unit_to = find_unit(args.unit_to) converted = convert_unit(number, unit_from, unit_to) if converted == 'F': return ( f'@{msg.user} Conversion is not possible: conversion ' f'{unit_from}({unit_from.human_name}) to {unit_to}({unit_to.human_name})' ) else: return f'@{msg.user} {number:.2f}{unit_from.human_name} = {converted:.2f}{unit_to.human_name}'
async def c_unnuke(self, msg: twitchirc.ChannelMessage): try: args = arg_parser.parse_args(main.delete_spammer_chrs(msg.text), { 'dry-run': bool, 'url': str, 'perma': bool, 'force': bool, 'hastebin': bool }, defaults={ 'dry-run': False, 'perma': False, 'force': False, 'hastebin': False }) except arg_parser.ParserError as e: return f'@{msg.user}, error: {e.message}' if args['url'] is ...: return f'@{msg.user}, url is a required parameter' if args['perma'] is ...: args['perma'] = False url = args['url'] if url.startswith(plugin_hastebin.hastebin_addr): url = url.replace(plugin_hastebin.hastebin_addr, plugin_hastebin.hastebin_addr + 'raw/') async with aiohttp.request('get', url) as req: if req.status != 200: return f'@{msg.user}, failed to download user list :(' if req.content_type == 'text/plain': users, _ = self.parse_user_list( (await req.text('utf-8')).replace('\r\n', '\n').replace( '$(newline)', '\n')) while '' in users: users.remove('') return await self.unnuke( args, msg, users, disable_hastebinning=(not args['hastebin']))
async def command_eval(msg: twitchirc.ChannelMessage): assert msg.user == 'mm2pl' and msg.flags['user-id'] == '117691339', 'no.' code = main.delete_spammer_chrs(msg.text.split(' ', 1)[1]) log('warn', f'Eval from {msg.user}({msg.flags["user-id"]}): {code!r}') glob = {name: getattr(builtins, name) for name in dir(builtins)} glob.update({ 'msg': msg, 'command_eval': command_eval, 'log': log, 'main': main, 'plugin_help': plugin_help, 'plugin_manager': plugin_manager, 'plugin_prefixes': plugin_prefixes }) result = eval(compile(code, msg.user + '@' + msg.channel, 'eval'), glob, {}) if isinstance(result, (list, str, twitchirc.Message)): return result else: return str(result)
def command_mailbox(self, msg: main.StandardizedMessage): argv = main.delete_spammer_chrs(msg.text).rstrip(' ').split(' ', 2) if len(argv) == 1: return plugin_help.find_topic( 'mailbox') + ' For full help see the help command.' action = argv[1] if action == 'start': return self._mailbox_start(argv, msg) elif action == 'draw': return self._mailbox_draw(argv, msg) elif action == 'stop': return self._mailbox_stop(msg) elif action == 'cancel': return self._mailbox_cancel(msg) elif action == 'timeout': return self._mailbox_timeout(argv, msg) elif action == 'whatif': return self._mailbox_whatif(argv, msg) else: return f'@{msg.user}, Unknown action: {action!r}'
async def c_nuke_url(self, msg: twitchirc.ChannelMessage): try: args = arg_parser.parse_args( main.delete_spammer_chrs(msg.text), { 'dry-run': bool, 'url': str, 'perma': bool, 'force': bool, 'timeout': datetime.timedelta }) except arg_parser.ParserError as e: return f'@{msg.user}, error: {e.message}' arg_parser.check_required_keys( args, ('url', 'timeout', 'search', 'perma', 'dry-run')) if args['url'] is ... or (args['timeout'] is ... and not args['perma']) or args['search'] is ...: return f'@{msg.user}, url, timeout and search are required parameters' if args['perma'] is ...: args['perma'] = False url = args['url'] if url.startswith(plugin_hastebin.hastebin_addr): url = url.replace(plugin_hastebin.hastebin_addr, plugin_hastebin.hastebin_addr + 'raw/') async with aiohttp.request('get', url) as req: if req.status != 200: return f'@{msg.user}, failed to download user list :(' if req.content_type == 'text/plain': users = (await req.text('utf-8')).replace('\r\n', '\n').replace( '$(newline)', '\n').split('\n') while '' in users: users.remove('') return await self.nuke(args, msg, users, force_nuke=args['force'])
async def _cookie(self, msg: twitchirc.ChannelMessage): m = COOKIE_PATTERN.findall(main.delete_spammer_chrs(msg.text.replace('\x01ACTION ', ''))) print(msg.user, m) if m and m[0][1].lower() in self.cookie_optin: time_ = 2 * 60 * 60 print(time_) print('cookie opt in okay') params = { 'username': m[0][1].lower(), 'text': 'Cookie :)', 'schedule': ( ( datetime.datetime.utcnow() + datetime.timedelta(seconds=time_) ).isoformat() + 'Z' ), 'private': 1, } print(params) async with (await main.supibot_api.request('post /bot/reminder/', params=params)) as r: print(f'request {r}') j = await r.json() print(j) if r.status == 200: await main.bot.send(msg.reply( f'@{m[0][1].lower()}, I set up a cookie reminder for you :), ' f'id: {j["data"]["reminderID"]}' )) else: await main.bot.send(msg.reply( f'@{m[0][1].lower()}, monkaS {chr(0x1f6a8)}' f'failed to create cookie reminder ' )) elif not m: log('warn', f'matching against regex failed: {msg.text!r}')
async def c_pyramid(self, msg: twitchirc.ChannelMessage): if not self._get_pyramid_enabled(msg.channel): return main.CommandResult.NOT_WHITELISTED, f'@{msg.user}, This command is disabled here.' t = main.delete_spammer_chrs(msg.text).split(' ', 1) if len(t) == 1: return main.CommandResult.OTHER_FAILED, f'@{msg.user}, Usage: pyramid <size> <text...>' args = t[1].rstrip() size = '' for arg in args.split(' '): arg: str if arg.isnumeric(): size = arg break # prefer first number! if size != '': args: str = args.replace(size, '', 1).rstrip() + ' ' size = int(size) if not args.strip(' '): return main.CommandResult.OTHER_FAILED, f'@{msg.user}, Nothing to send. NaM' output = [] for i in range(1, size): output.append(args * i) for i in range(size, 0, -1): output.append(args * i) return output
async def c_hastebin(self, msg: twitchirc.ChannelMessage): data = main.delete_spammer_chrs(msg.text).rstrip(' ').split(' ', 1)[1] link = await self.upload(data) return f'@{msg.user} Here\'s your hastebin link {self.hastebin_addr}{link}'
def command_manage_blacklists(self, msg: twitchirc.ChannelMessage): argv = main.delete_spammer_chrs(msg.text).rstrip(' ').split(' ', 1) if len(argv) == 1: return f'@{msg.user}, {plugin_help.all_help[plugin_help.SECTION_COMMANDS]["plonk"]}' text = argv[1] try: kw = arg_parser.parse_args(text, { 'scope': str, 'user': str, 'command': str, 'expires': datetime.timedelta }, defaults={ 'scope': None, 'user': None, 'command': None, 'expires': None }) except arg_parser.ParserError as e: return e.message if kw['command'] is None: return f'@{msg.user}, No `command:...` provided.' if kw['user'] is None: return f'@{msg.user}, No `user:...` provided.' kw['user'] = kw['user'].lower() if kw['user'] == 'everyone': kw['user'] = True kw['scope'] = kw['scope'].lower().strip('#') if kw['scope'] != 'global': sc = [] for ch in kw['scope'].split(','): ch = ch.lstrip('#').lower() if ch not in main.bot.channels_connected: return f'@{msg.user}, Invalid `scope`: {kw["scope"]!r}, no such channel.' sc.append(ch) kw['scope'] = sc if kw['command'].lower() == 'all': kw['command'] = True else: cmd = None for i in main.bot.commands: i: main.Command if i.chat_command.lower( ) == kw['command'] or kw['command'] in i.aliases: cmd = i.chat_command if cmd is None: return f'@{msg.user}, Invalid `command`: {kw["command"]!r}. No such command exists.' else: kw['command'] = cmd del cmd if kw['expires']: kw['expires'] = datetime.datetime.now() + kw['expires'] with main.session_scope() as session: if kw['scope'] == 'global': targets = main.User.get_by_name( kw['user'], session) if kw['user'] is not True else None if targets is None or len(targets) == 1: obj = BlacklistEntry( target=targets[0] if targets is not None else targets, command=kw['command'] if kw['command'] is not True else None, channel=None, expires_on=kw['expires'], is_active=True) blacklists.append(obj) session.add(obj) elif len(targets) == 0: return f'@{msg.user} Failed to find user: {kw["user"]}' else: return f'@{msg.user} Found multiple users possible with name {kw["user"]}' else: for ch in kw['scope']: targets = main.User.get_by_name( kw['user'], session) if kw['user'] is not True else None channels = main.User.get_by_name(ch, session) if len(channels) == 1: if targets is None or len(targets) == 1: obj = BlacklistEntry( target=targets[0] if targets is not None else targets, command=kw['command'] if kw['command'] is not True else None, channel=channels[0], expires_on=kw['expires'], is_active=True) blacklists.append(obj) session.add(obj) elif len(targets) == 0: return f'@{msg.user} Failed to find user: {kw["user"]}' else: return f'@{msg.user} Found multiple users possible with name {kw["user"]}' elif len(channels) == 0: return f'@{msg.user} Failed to find channel: {ch}' elif len(channels) > 1: return f'@{msg.user} Found multiple channels possible with name {ch}' return f'@{msg.user}, Added blacklist for command {kw["command"]} with scope {kw["scope"]} for {kw["user"]}'
def command_seval(msg: twitchirc.ChannelMessage): assert msg.user == 'mm2pl' and msg.flags['user-id'] == '117691339', 'no.' code = main.delete_spammer_chrs(msg.text.split(' ', 1)[1]) eval_result = do_eval(code, msg) return eval_result
async def command_eval(msg: twitchirc.ChannelMessage): assert msg.user == 'mm2pl' and msg.flags['user-id'] == '117691339', 'no.' code = main.delete_spammer_chrs(msg.text.split(' ', 1)[1]) eval_result = await asyncio.get_event_loop().run_in_executor( None, do_eval, code, msg) return eval_result