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
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
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
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({})
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)
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)
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
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