예제 #1
0
def slack_command():
    """
        Handle incoming Slack commands.
    """
    command = request.form.to_dict()
    command["rec_time"] = time.time()

    if 'payload' in command:
        command = json.loads(command['payload'])

    if 'token' not in command:
        current_app.logger.error(
            "There is no verification token, discarding command")
        abort(401)
    if command['token'] != current_app.config.get('VERIFICATION_TOKEN'):
        current_app.logger.error(
            f"Wrong verification token {current_app.config.get('VERIFICATION_TOKEN')} {command['token']}, discarding command"
        )  # noqa 501
        abort(403)
    else:
        log_metrics('karmabot_commands_passed', None, 'count', 1)
        current_app.logger.debug(command['command'])
        if command['command'] == '/karma':
            karma_controller = get_karma_controller()
            executor.submit(karma_controller.handle_command, command)

        elif command['command'] == '/badge':
            badges_controller = get_badges_controller()
            executor.submit(badges_controller.handle_command, command)

        else:
            current_app.logger.info(
                f"Ignoring unknown command {command['command']}")

        return '', 200
예제 #2
0
def slack_interaction():
    """
        Handle incoming Slack interactions
    """
    interaction = None
    current_app.logger.error(request.form)
    if 'payload' in request.form:
        interaction = json.loads(request.form['payload'])
        interaction["rec_time"] = time.time()
    else:
        current_app.logger.error("Missing payload, ignored interaction")
        abort(401)

    if 'token' not in interaction:
        current_app.logger.error(
            "There is no verification token, discarding interaction")
        abort(401)
    if interaction['token'] != current_app.config.get('VERIFICATION_TOKEN'):
        current_app.logger.error(
            "Wrong verification token, discarding command")
        abort(403)
    else:
        badges_controller = get_badges_controller()
        if interaction['type'] == "dialog_submission":
            if interaction['callback_id'] == 'karma-badge-create-0':
                executor.submit(badges_controller.cmd_badge_create_complete,
                                interaction)
            elif interaction['callback_id'].startswith('karma-badge-update-'):
                executor.submit(badges_controller.cmd_badge_update_complete,
                                interaction)
            else:
                current_app.logger.warning(
                    f"Unknown callback_id {interaction['callback_id']}")
        elif interaction['type'] == "interactive_message":
            if interaction['callback_id'] == 'karma-badge-delete-0':
                executor.submit(badges_controller.cmd_badge_delete_complete,
                                interaction)
            else:
                current_app.logger.warning(
                    f"Unknown callback_id {interaction['callback_id']}")
        else:
            current_app.logger.warning(
                f"Unknown interaction type: {interaction['type']}")

        log_metrics('karmabot_interactions_passed', None, 'count', 1)

        return '', 200
예제 #3
0
파일: karma.py 프로젝트: target/karmabot
    def handle_event(self, eventw):
        late = time.time() - float(eventw['rec_time'])
        log_metrics('karmabot_event_latency', None, 'time_elapsed', int(late * 1000))

        current_app.logger.debug(f"{eventw['event']['type']}")
        if eventw['event']['type'] != 'message':
            current_app.logger.warning("Ignoring unknown event type")
            return

        if 'user' in eventw['event']:

            if self.blacklisted(eventw['team_id'], eventw['event']['user']):
                return
            rlc = self.ratelimit_count(eventw['team_id'], eventw['event']['user'])
            if rlc > settings.KARMA_RATE_LIMIT:
                msg = f"Slow down there, partner! You only get to use karma {settings.KARMA_RATE_LIMIT} times per hour. Wait a little while and try again."  # noqa E501
                self.karma_error_reply(eventw, msg)
                return
        else:
            # Not a message from a user; ignore bots, etc
            current_app.logger.info("No user provided in the event")
            return
        self.karma_it(eventw, rlc)
        return
예제 #4
0
def slack_event():
    """
        Handle incoming Slack events.
        SLA:
         * Must respond successfully 5% of events per hour
         * Must respond within 3 seconds
    """
    eventw = request.get_json()
    eventw["rec_time"] = time.time()

    if 'token' not in eventw:
        current_app.logger.error(
            "There is no verification token in the JSON, discarding event")
        abort(401)
    if eventw['token'] != current_app.config.get('VERIFICATION_TOKEN'):
        current_app.logger.error(
            "Wrong verification token in JSON, discarding event")
        abort(403)
    if 'challenge' in eventw:
        return jsonify({'challenge': eventw['challenge']})
    else:
        log_metrics('karmabot_events_passed', None, 'count', 1)

        if eventw['event']['type'] == "message":
            if 'subtype' in eventw['event']:
                # skip all known subtypes.  None of them are relvant to karmabot today
                return jsonify({})

            if karma_re.search(eventw['event']['text']):
                log_metrics('karmabot_events_passed', None, 'count', 1)
                eventw["rec_time"] = time.time()
                karma_controller = get_karma_controller()
                executor.submit(karma_controller.handle_event, eventw)
            else:
                current_app.logger.debug("Not match: %s" %
                                         eventw['event']['text'])
        elif eventw['event']['type'] == "app_mention":
            if not karma_re.search(eventw['event']['text']):
                # skip karma events- another event type "message" will handle it
                log_metrics('karmabot_events_passed', None, 'count', 1)
                eventw["rec_time"] = time.time()
                karma_controller = get_karma_controller()
                executor.submit(karma_controller.handle_mention, eventw)

        else:
            current_app.logger.error("Unknown event type: %s" %
                                     eventw['event']['type'])
        return jsonify({})
예제 #5
0
파일: karma.py 프로젝트: target/karmabot
    def handle_command(self, command):
        current_app.logger.info(command['text'])

        if not command['text']:
            log_metrics('karmabot_command', {"command": "none"}, 'count', 1)
            return self.cmd_karma(command)

        # this needs to be checked before `if args[0] == "top"`
        if ' '.join(command['text'].split()) == 'top channel members':
            return self.get_top_channel_members(command)

        args = command['text'].split()
        if args[0] == "stats":
            log_metrics('karmabot_command', {"command": "stats"}, 'count', 1)
            if len(args) > 1:
                return self.cmd_karma_subject_stats(command, command['text'][6:])
            return self.cmd_karma_stats(command)

        if args[0] == "show":
            log_metrics('karmabot_command', {"command": "show"}, 'count', 1)
            return self.cmd_karma_show(command)

        if args[0] == "top":
            log_metrics('karmabot_command', {"command": "top"}, 'count', 1)
            return self.cmd_karma_top(command)

        if args[0] == "bottom":
            log_metrics('karmabot_command', {"command": "bottom"}, 'count', 1)
            return self.cmd_karma_top(command, 1)

        if args[0] == "leave":
            log_metrics('karmabot_command', {"command": "leave"}, 'count', 1)
            return self.cmd_leave(command)

        if args[0] == "help":
            log_metrics('karmabot_command', {"command": "help"}, 'count', 1)
        else:
            log_metrics('karmabot_command', {"command": "unknown"}, 'count', 1)
        return self.cmd_karma_help(command)
예제 #6
0
파일: karma.py 프로젝트: target/karmabot
    def handle_mention(self, eventw):
        command = eventw
        if 'user' in eventw['event']:
            current_app.logger.debug(f"Got a mention from {eventw['event']['user']}")
            if self.blacklisted(eventw['team_id'], eventw['event']['user']):
                return

        else:
            # Not a message from a user; ignore bots, etc
            current_app.logger.debug("Got a mention without a user. Ignoring.")
            return
        text = eventw['event']['text'].split(' ', 1)  # remove the `@user` mention
        eventw['text'] = text[1]  # Store the text to mimic the 'command' object
        args = text[1].split(' ', 1)

        if args[0] == "stats":
            log_metrics('karmabot_mention', {"command": "stats"}, 'count', 1)
            if len(args) > 1:
                return self.cmd_karma_subject_stats(command, command['text'][6:])
            return self.cmd_karma_stats(command)

        if args[0] == "show":
            log_metrics('karmabot_mention', {"command": "show"}, 'count', 1)
            return self.cmd_karma_show(command)

        if args[0] == "top":
            log_metrics('karmabot_mention', {"command": "top"}, 'count', 1)
            return self.cmd_karma_top(command)

        if args[0] == "bottom":
            log_metrics('karmabot_mention', {"command": "bottom"}, 'count', 1)
            return self.cmd_karma_top(command, 1)

        if args[0] == "help":
            log_metrics('karmabot_mention', {"command": "help"}, 'count', 1)
        else:
            log_metrics('karmabot_mention', {"command": "unknown"}, 'count', 1)
        return self.cmd_karma_help(command)
예제 #7
0
def get_health():
    log_metrics("threads", None, "queue_size", executor._work_queue.qsize())
    log_metrics("threads", None, "count", len(executor._threads))
    if executor._work_queue.qsize() > (1.5 * len(executor._threads)):
        return "QUEUE FULL", 503
    return "OK", 200
예제 #8
0
def server_error(e):
    log_metrics('exceptions', {'name': e.__class__.__name__}, 'count', 1)
    current_app.logger.exception(f'An error occurred during a request via {e}')
    return 'An internal error occurred.', 500