def decorated(bot, channel, *args): if bot.bot_id not in _last_answer or channel not in _last_answer[bot.bot_id]: send_slack_message(bot.bot_token, channel, "Please ask a question first.") return else: return wrapped(bot, channel, *args)
def _answer(bot, channel, request, question): user = User.get('user_id', bot.user_id) request['args']['token'] = user.token request['args']['question'] = question request['args']['numberofitems'] = '5' response = _process_responder_api(bot, channel, responder_answer, request) if not response: return answers = response['result']['items'] if bot.bot_id not in _previous_answers: _previous_answers[bot.bot_id] = {} _last_answer[bot.bot_id] = {} _previous_answers[bot.bot_id][channel] = answers _last_answer[bot.bot_id][channel] = 0 _LAST_QUESTION[bot.bot_id, channel] = question if not answers or answers[0]['confidence'] < NUMERICAL_EXPRESSION_THRESHOLD: numerical_answer = try_numerical_answer(question) if numerical_answer: answers.insert(0, {"answerText": numerical_answer[0] + "=" + numerical_answer[1], "confidence": 0.80, "sourceType": "numerical", "sourceId": str(uuid4()), "matchedQuestion": f"What is {numerical_answer[0]} ?" }) if len(answers) == 0: send_slack_message(bot.bot_token, channel, "Sorry! I don't know the answer to that.") else: _process_answer(bot, channel, question, answers[0]) response = send_slack_message(bot.bot_token, channel, answers[0]['answerText']) _BOT_TS_TO_MESSAGE[bot.bot_id, channel, response['message']['ts']] = answers[0]['answerText']
def _add_saved_reply(bot, channel, request, message): try: if message.startswith("."): message = message[NON_WORD_CHARS.search(message).end():] question_answer = [qa.strip() for qa in message.split('|')] if len(question_answer) < 2: raise IndexError() except IndexError: send_slack_message(bot.bot_token, channel, "Sorry, I didn't understand that. The usage for `.add` is: " ".add question | answer") return request['user'] = User.get('user_id', bot.user_id) questions = question_answer[:-1] answer = question_answer[-1] request['args']['question'] = questions[0] request['args']['answer'] = answer response = _process_responder_api(bot, channel, responder_create_saved_reply, request) if not response: return reply_id = response['result']['replyId'] for question in questions[1:]: request['args']['question'] = question request['args']['replyid'] = reply_id # we do lower() for all parameters if not _process_responder_api(bot, channel, responder_add_paraphrase_question, request): return if len(questions) == 1: questions_text = f'_{questions[0]}_\n' else: questions_text = '' for question in questions: questions_text += f'•_{question}_\n' send_slack_message(bot.bot_token, channel, f"Thanks, I'll remember that:\n{questions_text}>>>{answer}")
def _next(bot, channel, *args): next_answer = _last_answer[bot.bot_id][channel] + 1 if next_answer < len(_previous_answers[bot.bot_id][channel]): answer = _previous_answers[bot.bot_id][channel][next_answer] _process_answer(bot, channel, _LAST_QUESTION[bot.bot_id, channel], answer) response = send_slack_message(bot.bot_token, channel, answer['answerText']) _BOT_TS_TO_MESSAGE[bot.bot_id, channel, response['message']['ts']] = answer['answerText'] _last_answer[bot.bot_id][channel] = next_answer else: send_slack_message(bot.bot_token, channel, "I'm afraid I've run out of answers to that question.")
def _process_responder_api(bot, channel, api_endpoint, request) -> Optional[dict]: try: response = json.loads(api_endpoint(request).body) except UserException as e: send_slack_message(bot.bot_token, channel, e.message + ERROR_HELP_MESSAGE) return None if response['success']: return response else: send_slack_message(bot.bot_token, channel, response['result']['message'] + ERROR_HELP_MESSAGE) return None
def _explain(bot, channel, *args): previous = _get_last_answer(bot, channel) if previous['sourceType'] == 'document': context = previous["answerContext"] local_start_offset = previous['answerTextStartOffset'] - previous['answerContextStartOffset'] local_end_offset = previous['answerTextEndOffset'] - previous['answerContextStartOffset'] bold_text = context[local_start_offset:local_end_offset].replace('\n', '') context = f"{context[:local_start_offset]} *{bold_text}* {context[local_end_offset:]}" send_slack_message(bot.bot_token, channel, f"From _{previous['sourceId']}_ (Index {previous['confidence']:.2f})\n>>>{context}") else: send_slack_message(bot.bot_token, channel, f"I thought you asked (Index {previous['confidence']:.2f})\n_{previous['matchedQuestion']}_\n>>>{previous['answerText']}")
def _help(bot, channel, *args): send_slack_message(bot.bot_token, channel, """Hi, I am *Capebot*, I will answer all your questions, I will learn from you and your documents and improve over time. Here are my commands: *.add* _question_ | _answer_ - Create a new saved reply. *.next* - Show the next possible answer for the last question. *.why* - Explain why the last answer was given. *.help* - Display this message. You can also : *Add* a Slack emoji reaction to bot answers with :thumbsup: or :smiley:, I will remember and improve over time. *Upload* text and markdown documents by sending them to me in a private message. I will read them when answering. *Ask* me to calculate, for example `what is 3+2?`. For more options login to your account at https://thecape.ai. """)
def _process_positive_reaction(bot: Bot, request, event: dict) -> Optional[bool]: if event['type'] != 'reaction_added': return None if event['reaction'] not in {'smiley', 'smile', 'wink', 'simple_smile', 'grinning', 'kissing', 'laughing', 'satisfied', 'thumbsup', 'ok_hand', '+1', 'v', 'point_up', 'point_up_2', 'clap', 'muscle', 'raised_hands', 'arrow_up', 'up', 'ok', 'new', 'top', 'cool', '100', 'heavy_check_mark', 'ballot_box_with_check', 'white_check_mark'}: return False channel = event['item']['channel'] question_answer = _get_question_answer(bot, channel, event['item']['ts']) if not question_answer: return None _remove_question_answer(bot, channel, event['item']['ts']) question = question_answer['question'] last_answer = question_answer['answer'] if last_answer['sourceType'] == 'saved_reply': if last_answer['confidence'] == 1.0: send_slack_message(bot.bot_token, channel, f"Thanks for the feedback.\n_{question}_\n>>>{last_answer['answerText']}") return True request['user'] = User.get('user_id', bot.user_id) request['args']['question'] = question.strip() request['args']['replyid'] = last_answer['sourceId'] # we do lower() for all parameters if _process_responder_api(bot, channel, responder_add_paraphrase_question, request): send_slack_message(bot.bot_token, channel, f"Thanks, I'll remember that:\n_{question}_\n>>>{last_answer['answerText']}") return True elif last_answer['sourceType'] == 'document': request['user'] = User.get('user_id', bot.user_id) request['args']['question'] = question.strip() request['args']['answer'] = last_answer['answerText'].strip() if _process_responder_api(bot, channel, responder_create_saved_reply, request): send_slack_message(bot.bot_token, channel, f"Thanks, I'll remember that:\n_{question}_\n>>>{last_answer['answerText']}") return True else: send_slack_message(bot.bot_token, channel, f"Thanks for the feedback.\n_{question}_\n>>>{last_answer['answerText']}") return True
def process_file(event, request): authed_users = required_parameter(request, 'authed_users') bot_id = authed_users[0] channel = event['channel'] bot = Bot.get('bot_id', bot_id) slack_file = event['file'] if slack_file['filetype'] not in ['text', 'markdown']: send_slack_message(bot.bot_token, channel, ERROR_FILE_TYPE_UNSUPPORTED) else: text = get_slack_file_contents(bot.bot_token, slack_file['url_private']) try: request['user'] = User.get('user_id', bot.user_id) request['args']['text'] = text request['args']['title'] = slack_file['title'] request['args']['origin'] = slack_file['name'] request['args']['replace'] = 'true' responder_upload_document(request) send_slack_message(bot.bot_token, channel, BOT_FILE_UPLOADED) except UserException as e: send_slack_message(bot.bot_token, channel, e.message)
def _echo(bot, channel, request, message): if message.startswith(".echo"): _ECHO_MODE[bot.bot_id, channel] = not _ECHO_MODE.get((bot.bot_id, channel), False) send_slack_message(bot.bot_token, channel, "Echo mode toggled") else: send_slack_message(bot.bot_token, channel, message)