def test_team(): _team = Team.get_team_by_name('testteam') _bot = Bot.get_bot_by_name(_team, 'echobot') assert _bot.name == 'echobot' assert _bot.bot_id == 'A12345678' assert _bot.team == _team assert _bot.oauth_user_token == '1234' assert _bot.oauth_bot_token == '1234' assert _bot.verification_token == '1234' _team = Team.get_team_by_id(team_id='TABCDEF12') _bot = Bot.get_bot_by_bot_id(_team, 'A98765432') assert _bot.name == 'echobot' assert _bot.bot_id == 'A98765432' assert _bot.team == _team assert _bot.oauth_user_token == '1234' assert _bot.oauth_bot_token == '' assert _bot.verification_token == '1234' _team = Team.get_team_by_name('testteam') _bot = Bot.get_bot_by_verification_token('5555') assert _bot.name == 'pingbot' assert _bot.bot_id == 'AABCDEF12' assert _bot.team == _team assert _bot.oauth_user_token == '5555' assert _bot.oauth_bot_token == '5555' assert _bot.verification_token == '5555' with pytest.raises(BotInitializationError): _bot = Bot.get_bot_by_name(_team, 'fakebot') with pytest.raises(BotInitializationError): _bot = Bot.get_bot_by_bot_id(_team, 'BADBOTID')
def process_slash_command(command): """ Dispatcher for slack slash commands. """ statsd = stats.get_statsd_client() team = Team.get_team_by_id(command['team_id']) bot = Bot.get_bot_by_bot_id(team, command['omnibot_bot_id']) if command['command'].startswith('/'): command_name = command['command'][1:] else: command_name = command['command'] event_trace = merge_logging_context( { 'trigger_id': command['trigger_id'], 'command': command_name, }, bot.logging_context, ) statsd.incr('slash_command.process.attempt.{}'.format(command_name)) try: with statsd.timer('process_slash_command'): logger.debug('Processing slash_command: {}'.format( json.dumps(command, indent=2)), extra=event_trace) slash_command = SlashCommand(bot, command, event_trace) _process_slash_command_handlers(slash_command) except Exception: statsd.incr('slash_command.process.failed.{}'.format(command_name)) logger.exception('Could not process slash command.', exc_info=True, extra=event_trace)
def process_interactive_component(component): """ Dispatcher for slack interactive components """ statsd = stats.get_statsd_client() team = Team.get_team_by_id(component['team']['id']) bot = Bot.get_bot_by_bot_id(team, component['omnibot_bot_id']) event_trace = merge_logging_context( { 'callback_id': get_callback_id(component), 'component_type': component['type'], }, bot.logging_context, ) statsd.incr('interactive_component.process.attempt.{}'.format( get_callback_id(component))) try: with statsd.timer('process_interactive_component'): logger.debug('Processing interactive component: {}'.format( json.dumps(component, indent=2)), extra=event_trace) interactive_component = InteractiveComponent( bot, component, event_trace) _process_interactive_component(interactive_component) except Exception: statsd.incr('interactive_component.process.failed.{}'.format( get_callback_id(component))) logger.exception('Could not process interactive component.', exc_info=True, extra=event_trace)
def process_event(event): """ Dispatcher for slack api events. """ statsd = stats.get_statsd_client() team = Team.get_team_by_id(event['team_id']) bot = Bot.get_bot_by_bot_id(team, event['api_app_id']) event_info = event['event'] event_type = event_info['type'] event_trace = { 'event_ts': event_info['event_ts'], 'event_type': event_type, 'app_id': event['api_app_id'], 'team_id': bot.team.team_id, 'bot_receiver': bot.name } statsd.incr('event.process.attempt.{}'.format(event_type)) if event_type == 'message' or event_type == 'app_mention': try: with statsd.timer('process_event'): logger.debug( 'Processing message: {}'.format( json.dumps(event, indent=2) ), extra=event_trace ) try: message = Message(bot, event_info, event_trace) _process_message_handlers(message) except MessageUnsupportedError: pass except Exception: statsd.incr('event.process.failed.{}'.format(event_type)) logger.exception( 'Could not process message.', exc_info=True, extra=event_trace ) else: logger.debug( 'Event is not a message type.', extra=event_trace ) logger.debug(event)
def slack_event(): """ Handle event subscription API webhooks from slack. """ event = request.json logger.debug('Event received in API slack_event: {}'.format(event)) # Every event should have a validation token if 'token' not in event: msg = 'No verification token in event.' logger.error(msg) return jsonify({'status': 'failure', 'error': msg}), 403 # url_verification events don't contain info about team_id or api_app_id, # annoyingly, so we need to special case this to validate the token # against all configured apps. if event.get('type') == 'url_verification': try: Bot.get_bot_by_verification_token(event['token']) except BotInitializationError: msg = 'url_verification failed.' logger.error(msg) return jsonify({'status': 'failure', 'error': msg}), 403 return jsonify({'challenge': event['challenge']}) api_app_id = event.get('api_app_id') if api_app_id is None: msg = 'No api_app_id in event.' logger.error(msg) return jsonify({'status': 'failure', 'error': msg}), 403 team_id = event.get('team_id') if team_id is None: msg = 'No team_id in event.' logger.error( msg, extra={'bot_id': api_app_id}, ) return jsonify({'status': 'failure', 'error': msg}), 403 try: team = Team.get_team_by_id(team_id) except TeamInitializationError: msg = 'Unsupported team' logger.warning(msg, extra={'team_id': team_id, 'bot_id': api_app_id}) return jsonify({'status': 'failure', 'error': msg}), 403 try: bot = Bot.get_bot_by_bot_id(team, api_app_id) except BotInitializationError: msg = 'Unsupported bot' logger.info(msg, extra={'team_id': team_id, 'bot_id': api_app_id}) return jsonify({'status': 'ignored', 'warning': msg}), 200 if event['token'] != bot.verification_token: msg = 'Incorrect verification token in event for bot' logger.error( msg, extra=bot.logging_context, ) return jsonify({'status': 'failure', 'error': msg}), 403 if 'event' not in event: msg = 'Request does not have an event. Processing will not proceed!' logger.error( msg, extra=bot.logging_context, ) return jsonify({'status': 'failure', 'error': msg}), 403 try: instrument_event(bot, event) except Exception: logger.exception( 'Could not instrument request', extra=bot.logging_context, ) try: queue_event(bot, event, 'event') except Exception: logger.exception( 'Could not queue request.', extra=bot.logging_context, ) return jsonify({'status': 'failure'}), 500 return jsonify({'status': 'success'}), 200
def get_test_bot() -> BotMatcher: return BotMatcher( Bot.get_bot_by_bot_id(Team.get_team_by_id("TEST_TEAM_ID"), "TEST_OMNIBOT_ID"))