Ejemplo n.º 1
0
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')
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
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)
Ejemplo n.º 4
0
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)
Ejemplo n.º 5
0
Archivo: api.py Proyecto: lyft/omnibot
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
Ejemplo n.º 6
0
def get_test_bot() -> BotMatcher:
    return BotMatcher(
        Bot.get_bot_by_bot_id(Team.get_team_by_id("TEST_TEAM_ID"),
                              "TEST_OMNIBOT_ID"))