def webhook(): data = request.get_json() request_id = str(uuid4()) # insert_user_request(request_id, str(data)) if data["object"] == "page": for entry in data["entry"]: if 'messaging' in entry: for messaging_event in entry["messaging"]: if messaging_event.get("message"): sender_id = messaging_event["sender"]["id"] # recipient_id = messaging_event["recipient"]["id"] log(messaging_event) if 'text' in messaging_event["message"]: message_text = messaging_event["message"]["text"] if is_keyword_query(message_text): handle_keyword(sender_id, message_text) else: handle_message(message_text, sender_id, request_id) if messaging_event.get( "delivery"): # delivery confirmation pass if messaging_event.get("optin"): # optin confirmation pass if messaging_event.get("postback"): sender_id = messaging_event["sender"]["id"] insert_user_answer(request_id, str(messaging_event)) handle_postback(messaging_event, sender_id, request_id) return "ok", 200
def update_answer(response_id, values): try: with db_connection.cursor() as cursor: sql = 'UPDATE answer_provided SET answer_id = %s, is_correct = %s WHERE id = %s' cursor.execute(sql, (values.answer_id, values.is_correct, response_id)) db_connection.commit() except: log('Error! update user answer {}'.format(response_id))
def top_topics_flow(sender_id): top_topics = top_two_scoring_topics(sender_id) log(top_topics) if top_topics: send_text_message( sender_id, 'Your strengths are {}'.format(', '.join(top_topics))) else: send_text_message(sender_id, 'Please solve more questions to use this feature')
def insert_user_question(response_id, sender_id, question): try: with db_connection.cursor() as cursor: sql = 'INSERT INTO questions_given (id, sender_id, question_id) VALUES (%s, %s, %s)' question_id = parse_question(question) cursor.execute(sql, (response_id, sender_id, question_id)) db_connection.commit() except: log('Error! insert user question {}'.format(question))
def insert_user_request(request_id, request): try: with db_connection.cursor() as cursor: sql = 'INSERT INTO user_request (id, sender_id, query) VALUES (%s, %s, %s)' values = parse_request_data(request) if values: cursor.execute(sql, (request_id, values.id, values.query)) db_connection.commit() except: log('Error! insert user request {}'.format(request))
def insert_user_answer(response_id, answer): try: log('insert user {}'.format(answer)) values = parse_answer(answer) if is_answer_there(values.question_request_id): update_answer(get_response_id(values.question_request_id), values) else: insert_answer(response_id, values) except: log('Error! insert user answer {}'.format(answer))
def send(data): params = {"access_token": os.environ["PAGE_ACCESS_TOKEN"]} headers = {"Content-Type": "application/json"} r = requests.post("https://graph.facebook.com/v2.6/me/messages", params=params, headers=headers, data=data) if r.status_code != 200: log(r.status_code) log(r.text)
def execute_sql(query, *args): db_connection = DBConnection.Instance().get_connection() try: cursor = db_connection.cursor() cursor.execute(query, args) except: db_connection.close() cursor = db_connection.cursor() cursor.execute(query) log("error! execute sql {}".format(query)) return cursor
def study_flow(sender_id, response, request_id): topic = response[RESULT][PARAMETERS][TOPICS] if topic != 'default_topic': send_text_message(sender_id, response[RESULT][FULFILLMENT][SPEECH]) else: topic = '' send_text_message(sender_id, "Sure! Let's start with this:") log("TOPIC: {}".format(topic)) question = question_from_topic(topic) options = options_and_answer(question[ID]) send_question(sender_id, request_id, question, options, topic=topic)
def insert_answer(response_id, values): try: with db_connection.cursor() as cursor: sql = 'INSERT INTO answer_provided (id, sender_id, question_id, answer_id, is_correct, test_id, question_request_id) VALUES (%s, %s, %s, %s, %s, %s, %s)' cursor.execute(sql, (response_id, values.sender_id, values.question_id, values.answer_id, values.is_correct, values.test_id, values.question_request_id)) db_connection.commit() except: log('Error! insert user answer {}'.format(response_id))
def handle_postback(event, sender_id, request_id): log(event) if 'postback' in event and 'payload' in event['postback']: payload = event['postback']['payload'] payload = ast.literal_eval(payload) if 'type' in payload and payload['type'] == 'num_questions': handle_new_test(payload, sender_id, request_id) elif 'test' in payload and payload['test'] is True: handle_test(payload, sender_id, request_id) elif 'first_message' in payload: handle_first_message(sender_id) else: handle_question(payload, sender_id)
def insert_user_response(response_id, response): try: with db_connection.cursor() as cursor: sql_to_request = 'UPDATE user_request SET intent = %s, entities = %s WHERE id=%s' values = parse_response_data(response) cursor.execute(sql_to_request, (values.intent, values.entities, response_id)) sql_to_response = 'INSERT INTO user_response (id, sender_id, response) VALUES (%s, %s, %s)' cursor.execute(sql_to_response, (response_id, values.sender_id, values.response)) db_connection.commit() except: log('Error! insert user response {}'.format(response))
def questions_answered(sender_id, num): try: sql = "select count(*) from answer_provided where time_asked \ BETWEEN (select CURRENT_TIMESTAMP + interval '-%s' day) \ AND (select CURRENT_TIMESTAMP) \ AND sender_id = %s" cursor = execute_sql(sql, num, sender_id) response = cursor.fetchone()['count(*)'] cursor.close() return response except: log('error! questions answered') return None
def questions_grouped_by_date_eternity(sender_id): try: sql = "select DATE(time_asked) AS ForDate, count(*) \ from answer_provided \ where sender_id = %s \ GROUP BY ForDate" cursor = execute_sql(sql, sender_id) response = cursor.fetchall() cursor.close() return response except: log('error! questions group by date') return None
def score_in_given_topic(sender_id, topic): try: sql = "select count(*) \ from answer_provided a join questions_question q \ on q.id = a.question_id \ where a.is_correct = 1 \ AND q.topic = %s AND a.sender_id = %s" cursor = execute_sql(sql, topic, sender_id) response = cursor.fetchone()['count(*)'] cursor.close() return response except: log('error! score in a given topic') return None
def scores_in_topics(sender_id): try: sql = "select count(*), q.topic \ from answer_provided a join questions_question q \ on q.id = a.question_id \ where a.is_correct = 1 AND a.sender_id = %s \ GROUP BY q.topic \ ORDER BY count(*) DESC" cursor = execute_sql(sql, sender_id) response = cursor.fetchall() cursor.close() return response except: log('error! scores in topics') return None
def call_bar_plot(question_count, correct_count, file_id, title, question_color): try: x_axis = [ item['ForDate'].strftime('%m/%d/%Y') for item in question_count ] y_axis_1 = [item['count(*)'] for item in question_count] y_axis_2 = [item['count(*)'] for item in correct_count] x_axis = x_axis if len(x_axis) > 0 else [0] y_axis_1 = y_axis_1 if len(y_axis_1) > 0 else [0] y_axis_2 = y_axis_2 if len(y_axis_2) > 0 else [0] answered_vs_correct_plot(file_id, title, question_color, x_axis, y_axis_1, y_axis_2) return True except: log('unable to plot') return False
def get_solution_gifs(question): API = get_wolfram_key() client = wolframalpha.Client(API) gifs = [] try: result = client.query(question) if not result or not result.pods: return None for item in result.pods: if 'subpod' in item and isinstance(item['subpod'], list): for i in item['subpod']: gifs.append(i['img']['@src']) elif 'subpod' in item and isinstance(item['subpod'], dict): gifs.append(item['subpod']['img']['@src']) return gifs except: log('unable to parse wolfram result')
def correct_questions_grouped_by_date_last_month(sender_id): try: sql = "select DATE(time_asked) AS ForDate, count(*) \ from answer_provided \ where time_asked \ BETWEEN (select CURRENT_TIMESTAMP + interval '-30' day) \ AND (select CURRENT_TIMESTAMP) AND is_correct = 1 AND \ sender_id = %s\ GROUP BY ForDate" cursor = execute_sql(sql, sender_id) response = cursor.fetchall() cursor.close() return response except: log('error! correct questions group by date') return None
def bottom_two_scoring_topics(sender_id): try: sql = "select count(*), q.topic \ from answer_provided a join questions_question q \ on q.id = a.question_id \ where a.is_correct = 1 AND a.sender_id = %s \ GROUP BY q.topic \ ORDER BY count(*) \ LIMIT 2" cursor = execute_sql(sql, sender_id) res = cursor.fetchall() res = [r['topic'] for r in res] cursor.close() return res except: log('error! bottom two scoring topics') return None
def scores_in_topics_plot(sender_id, file_id): try: data = scores_in_topics(sender_id) labels = [item['topic'] for item in data] sizes = [item['count(*)'] for item in data] labels = labels if len(labels) > 0 else [0] sizes = sizes if len(sizes) > 0 else [0] fig1, ax1 = plt.subplots() ax1.set_title('topic wise strengths') ax1.pie(sizes, labels=labels, autopct='%1.1f%%', shadow=True, startangle=90) ax1.axis('equal') plt.savefig(get_file_name(file_id)) return True except: log('error! scores in topic') return False
def handle_message(message_text, sender_id, request_id, bing_search=False): response = APIAI.Instance().message_response(message_text, sender_id) intent = response[RESULT][METADATA][INTENT_NAME] log(response) if intent == DIAGNOSTIC_YES: diagnostic_yes_flow(sender_id, response, request_id) elif intent == STUDY: study_flow(sender_id, response, request_id) elif intent == GREETING: greeting_flow(sender_id, response) elif intent == DIAGNOSTIC_NO: diagnostic_no_flow(sender_id, response) elif intent == VIDEO_SEARCH: video_flow(sender_id, message_text) elif intent == TEST: test_start_flow(sender_id, response) elif intent == QUESTIONS_ANSWERED: questions_answered_flow(sender_id, response) elif intent == QUESTIONS_ANSWERED_CORRECTLY: questions_answered_correctly_flow(sender_id, response) elif intent == TOP_TOPICS: top_topics_flow(sender_id) elif intent == BOTTOM_TOPICS: bottom_topics_flow(sender_id) elif intent == PLOT_SCORES: plot_scores_flow(sender_id, response) elif intent == SCORES_IN_TOPICS: scores_in_topics_flow(sender_id) elif intent == PLOT_MENU: plot_menu_flow(sender_id) elif intent == DEFAULT: if not bing_search: corrected_sentence = BingSearcher().correct_spelling(message_text) handle_message(corrected_sentence, sender_id, request_id, bing_search=True) return send_text_message(sender_id, response[RESULT][FULFILLMENT][SPEECH]) send_helper_messages(sender_id)
def send_question(recipient_id, request_id, question, options, **kwargs): log(question) # insert_user_question(request_id, recipient_id, str(question)) buttons = [] question_request_id = str(uuid4()) for option in options.options: payload = { 'id': option['id'], 'correct': options.correct, 'qid': question['id'], 'question_request_id': question_request_id, } payload.update(kwargs) payload = str(payload) button = { "type": "postback", "title": option['text'], "payload": payload, } buttons.append(button) data = json.dumps({ "recipient": { "id": recipient_id }, "message": { "attachment": { "type": "template", "payload": { "template_type": "button", "text": filter_question(question['question_text']), "buttons": buttons, } } } }) send(data)