def api(): """ Endpoint to converse with chatbot. Chat context is maintained by exchanging the payload between client and bot. sample input/output payload => { "currentNode": "", "complete": false, "parameters": [], "extractedParameters": {}, "missingParameters": [], "intent": { }, "context": {}, "input": "hello", "speechResponse": [ ] } :param json: :return json: """ request_json = request.get_json(silent=True) result_json = request_json if request_json: context = {"context": request_json["context"]} if app.config["DEFAULT_WELCOME_INTENT_NAME"] in request_json.get( "input"): intent = Intent.objects( intentId=app.config["DEFAULT_WELCOME_INTENT_NAME"]).first() result_json["complete"] = True result_json["intent"]["object_id"] = str(intent.id) result_json["intent"]["id"] = intent.intentId result_json["input"] = request_json.get("input") template = Template(intent.speechResponse, undefined=SilentUndefined) result_json["speechResponse"] = split_sentence( template.render(**context)) app.logger.info(request_json.get("input"), extra=result_json) return build_response.build_json(result_json) # check if input method is event or raw text elif request_json.get("event"): intent_id = request_json.get("event") confidence = 1 result_json["event"] = None else: intent_id, confidence, suggestions = predict( request_json.get("input")) app.logger.info("intent_id => %s" % intent_id) intent = Intent.objects.get(intentId=intent_id) if intent.parameters: parameters = intent.parameters result_json["extractedParameters"] = request_json.get( "extractedParameters") or {} else: parameters = [] if ((request_json.get("complete") is None) or (request_json.get("complete") is True)): result_json["intent"] = { "object_id": str(intent.id), "confidence": confidence, "id": intent.intentId } if parameters: # Extract NER entities result_json["extractedParameters"].update( entity_extraction.predict(intent_id, request_json.get("input"))) missing_parameters = [] result_json["missingParameters"] = [] result_json["parameters"] = [] for parameter in parameters: result_json["parameters"].append({ "name": parameter.name, "type": parameter.type, "required": parameter.required }) if parameter.required: if parameter.name not in result_json[ "extractedParameters"].keys(): result_json["missingParameters"].append( parameter.name) missing_parameters.append(parameter) if missing_parameters: result_json["complete"] = False current_node = missing_parameters[0] result_json["currentNode"] = current_node["name"] result_json["speechResponse"] = split_sentence( current_node["prompt"]) else: result_json["complete"] = True context["parameters"] = result_json["extractedParameters"] else: result_json["complete"] = True elif request_json.get("complete") is False: if "cancel" not in intent.name: intent_id = request_json["intent"]["id"] app.logger.info(intent_id) intent = Intent.objects.get(intentId=intent_id) extracted_parameter = entity_extraction.replace_synonyms({ request_json.get("currentNode"): request_json.get("input") }) # replace synonyms for entity values result_json["extractedParameters"].update(extracted_parameter) result_json["missingParameters"].remove( request_json.get("currentNode")) if len(result_json["missingParameters"]) == 0: result_json["complete"] = True context = { "parameters": result_json["extractedParameters"], "context": request_json["context"] } else: missing_parameter = result_json["missingParameters"][0] result_json["complete"] = False current_node = [ node for node in intent.parameters if missing_parameter in node.name ][0] result_json["currentNode"] = current_node.name result_json["speechResponse"] = split_sentence( current_node.prompt) else: result_json["currentNode"] = None result_json["missingParameters"] = [] result_json["parameters"] = {} result_json["intent"] = {} result_json["complete"] = True if result_json["complete"]: if intent.apiTrigger: isJson = False parameters = result_json["extractedParameters"] headers = intent.apiDetails.get_headers() app.logger.info("headers %s" % headers) url_template = Template(intent.apiDetails.url, undefined=SilentUndefined) rendered_url = url_template.render(**context) if intent.apiDetails.isJson: isJson = True request_template = Template(intent.apiDetails.jsonData, undefined=SilentUndefined) parameters = json.loads(request_template.render(**context)) try: result = call_api(rendered_url, intent.apiDetails.requestType, headers, parameters, isJson) except Exception as e: app.logger.warn("API call failed", e) result_json["speechResponse"] = [ "Service is not available. Please try again later." ] else: context["result"] = result template = Template(intent.speechResponse, undefined=SilentUndefined) result_json["speechResponse"] = split_sentence( template.render(**context)) else: context["result"] = {} template = Template(intent.speechResponse, undefined=SilentUndefined) result_json["speechResponse"] = split_sentence( template.render(**context)) app.logger.info(request_json.get("input"), extra=result_json) return build_response.build_json(result_json) else: return abort(400)
def webhook_action(): request_json = request.get_json(silent=True) data = request_json print(data) for entry in data['entry']: messaging = entry['messaging'] for message in messaging: if message.get('message'): user_id = message['sender']['id'] user_details_url = "https://graph.facebook.com/v2.6/%s" % user_id user_details_params = { 'fields': 'first_name,last_name,profile_pic', 'access_token': access_token } try: user_details = call_api(user_details_url, "GET", '', user_details_params, True) user_name = user_details['first_name'] userid = int(user_id) except Exception as e: app.logger.warn("API call failed", e) if message['message'].get('text'): msg = message['message']['text'] if message['message'].get('quick_reply'): isCorrect = message['message']['quick_reply'][ 'payload'] print(isCorrect, type(isCorrect)) if 'Play Game' in msg: r.set(user_id + '_playing', 1) if 'exit' in msg: r.set(user_id + '_playing', 0) r.set(user_id + '_count', 0) if r.get(user_id + '_playing') == '1': response = { "access_token": access_token, 'recipient': { 'id': user_id }, 'message': { 'text': '', } } r.incr(user_id + '_count') count = int(r.get(user_id + '_count')) - 1 questions = read_questions().get_json() if len(questions) > count: response['message']['text'] = questions[count][ 'question'] answers = [] for ans in questions[count]['Answers']: a = { 'content_type': 'text', 'title': '', 'payload': '' } a['title'] = ans['ans'] a['payload'] = str(ans['isCorrect']) answers.append(a) if answers: response['message']['quick_replies'] = answers msg = 'Play Game' else: r.set(user_id + '_playing', 0) r.set(user_id + '_count', 0) response['message'][ 'text'] = 'Thanks for playing...' print('/n', response) else: response = { "access_token": access_token, 'recipient': { 'id': user_id }, 'message': { 'text': '', 'quick_replies': quick_replies_game } } try: global face_json face_json['input'] = msg headers = {"Content-Type": "application/json"} face_json = call_api( url='http://localhost:5000/api/v1', type="POST", headers=headers, parameters=face_json, is_json=True) for speechResponse in face_json['speechResponse']: response['message'][ 'text'] += speechResponse + '\n' except Exception as e: app.logger.warn("API call failed", e) if 'Play Game' in msg: r.set(user_id + '_playing', 1) else: r.set(user_id + '_playing', 0) elif message['message'].get('attachments'): attachment_link = message["message"]["attachments"][0][ "payload"]["url"] response = { "access_token": access_token, 'recipient': { 'id': user_id }, 'message': {} } response['message']['text'] = "couldn't catch that..." else: response = { "access_token": access_token, 'recipient': { 'id': user_id }, 'message': {} } response['message']['text'] = "couldn't catch that..." headers = {"Content-Type": "application/json"} #r = requests.post('https://graph.facebook.com/v2.6/me/messages', params=params, headers=headers, json=response) try: result = call_api( 'https://graph.facebook.com/v2.6/me/messages', "POST", headers, response, True) except Exception as e: app.logger.warn("API call failed", e) return build_response.sent_ok()
def api(): """ Endpoint to converse with chatbot. Chat context is maintained by exchanging the payload between client and bot. sample input/output payload => { "currentNode": "", "complete": false, "parameters": [], "extractedParameters": {}, "missingParameters": [], "intent": {}, "context": {}, "input": "hello", "speechResponse": [], "seat_map" : [] } :param json: :return json: """ #GET JSON FROM POST REQUEST request_json = request.get_json(silent=True) result_json = request_json print("-------------chat input is ", request_json.get("input")) seat_map = request_json.get( "seat_map" ) #PROBLEM -> seat_map is null,but keys in request json has seat_map sometimes print("----seat map in backend is ", seat_map) if request_json: #dont know what is context yet context = {"context": request_json["context"]} app.logger.info("-----context is ", context) #if input contain "init_conversation" then send fixed result_json -> dont predict anything if app.config["DEFAULT_WELCOME_INTENT_NAME"] in request_json.get( "input"): intent = Intent.objects( intentId=app.config["DEFAULT_WELCOME_INTENT_NAME"]).first() result_json["complete"] = True result_json["intent"]["object_id"] = str(intent.id) result_json["intent"]["id"] = str(intent.intentId) result_json["input"] = request_json.get("input") template = Template(intent.speechResponse, undefined=SilentUndefined) result_json["speechResponse"] = split_sentence( template.render(**context)) app.logger.info(request_json.get("input"), extra=result_json) return build_response.build_json(result_json) #predict intent id from intent model #get intentid #confidence for that intet #other intent with low confidence intent_id, confidence, suggestions = predict(request_json.get("input")) print("-----keys in request_json", request_json.keys()) app.logger.info("intent_id => %s" % intent_id) #get predicted intent object from mongo,which contains #_id, intent_id, api_trigger, name, #parameters = [parameter_name, type, required compulsary, message to ask this parameter] #speech response = how to show result when all parameters provided #training data = [ {"text" : "hello there", "entities":[]}, {"text" : "hello there", "entities":[]}, ....] #userdefined = true.false intent = Intent.objects.get(intentId=intent_id) if intent.parameters: parameters = intent.parameters else: parameters = [] #for first request -> doesnt have param -> so None #First request after init response is always complete -> then it is inspected and decided if complete or not #So path is always: #first -> third (if no param required) #first -> second ->third (if 1 param required) #first -> second -> second ->third (if 2 params required) if ((request_json.get("complete") is None) or (request_json.get("complete") is True)): print("----FIRST PATH FOR REQUEST_JSON -> None || True") result_json["intent"] = { "object_id": str(intent.id), "confidence": confidence, "id": str(intent.intentId.encode('utf8')) } #if intent require parameters then extract them from input with entity extractor model -> crfsuit #else result_json is complete if parameters: # Extract NER entities app.logger.info("---entity extracting in first path") extracted_parameters = entity_extraction.predict( intent_id, request_json.get("input")) print("---entity extracted is ", extracted_parameters) #find missing parameters and fill result_json missing_parameters = [] result_json["missingParameters"] = [] result_json["extractedParameters"] = {} result_json["parameters"] = [] for parameter in parameters: result_json["parameters"].append({ "name": parameter.name, "type": parameter.type, "required": parameter.required }) if parameter.required: if parameter.name not in extracted_parameters.keys(): result_json["missingParameters"].append( parameter.name) missing_parameters.append(parameter) result_json["extractedParameters"] = extracted_parameters #if missing some parameters: #mark result_json as not complete #set current node to first missing parameter #put that paramter asking response in result_json if missing_parameters: result_json["complete"] = False current_node = missing_parameters[0] result_json["currentNode"] = current_node["name"] result_json["speechResponse"] = split_sentence( current_node["prompt"]) print("---result json in missing parameter", result_json) else: result_json["complete"] = True context["parameters"] = extracted_parameters print("---result json in no missing parameter", result_json) else: result_json["complete"] = True elif request_json.get("complete") is False: #if some params are required further #and it is not cancel intent print("----SECOND PATH FOR REQUEST_JSON -> False") if "cancel" not in intent.name: intent_id = request_json["intent"]["id"] intent = Intent.objects.get(intentId=intent_id) #print("---request json in complete false is ", intent_id, request_json) print( "----SECOND TIME ENTITY EXTRACTION WITH REPLACING SYNONYMS FOR ", request_json.get("currentNode"), request_json.get("input")) extracted_parameter = entity_extraction.replace_synonyms({ request_json.get("currentNode"): request_json.get("input") }) # replace synonyms for entity values result_json["extractedParameters"].update(extracted_parameter) result_json["missingParameters"].remove( request_json.get("currentNode")) if len(result_json["missingParameters"]) == 0: result_json["complete"] = True context = { "parameters": result_json["extractedParameters"], "context": request_json["context"] } else: missing_parameter = result_json["missingParameters"][0] result_json["complete"] = False current_node = [ node for node in intent.parameters if missing_parameter in node.name ][0] result_json["currentNode"] = current_node.name result_json["speechResponse"] = split_sentence( current_node.prompt) else: result_json["currentNode"] = None result_json["missingParameters"] = [] result_json["parameters"] = {} result_json["intent"] = {} result_json["complete"] = True if result_json["complete"]: print("----THIRD PATH FOR RESULT_JSON -> True") if intent.apiTrigger: isJson = False parameters = result_json["extractedParameters"] headers = intent.apiDetails.get_headers() app.logger.info("headers %s" % headers) url_template = Template(intent.apiDetails.url, undefined=SilentUndefined) rendered_url = url_template.render(**context) if intent.apiDetails.isJson: isJson = True request_template = Template(intent.apiDetails.jsonData, undefined=SilentUndefined) parameters = json.loads(request_template.render(**context)) try: result = call_api(rendered_url, intent.apiDetails.requestType, headers, parameters, isJson) except Exception as e: app.logger.warn("API call failed", e) result_json["speechResponse"] = [ "Service is not available. Please try again later." ] else: context["result"] = result template = Template(intent.speechResponse, undefined=SilentUndefined) result_json["speechResponse"] = split_sentence( template.render(**context)) else: context["result"] = {} template = Template(intent.speechResponse, undefined=SilentUndefined) result_json["speechResponse"] = split_sentence( template.render(**context)) #get seat map with updated seats print("----result json before treating", result_json) result = treat_intent(intent_id, result_json["extractedParameters"], seat_map) if result is not None: result_seat_map, response = result result_json["seat_map"] = result_seat_map template = Template(response, undefined=SilentUndefined) result_json["speechResponse"] = split_sentence( template.render(**context)) app.logger.info(request_json.get("input"), extra=result_json) return build_response.build_json(result_json) else: return abort(400)
def api(): """ Endpoint to Converse with the Chatbot. Chat context is maintained by exchanging the payload between client and bot. --- definitions: currentNode: type: string complete: type: boolean context: type: object properties: parameters: type: array items: type: object properties: name: type: string type: type: string required: type: boolean extractedParameters: type: object properties: country: type: string speechResponse: type: array items: type: string intent: type: object properties: object_id: type: string confidence: type: number id: type: string input: type: string missingParameters: type: array items: owner: type: string date: type: string :param json: :return json: """ request_json = request.get_json(silent=True) print(request_json) result_json = copy.deepcopy(request_json) if request_json: context = {"context": request_json["context"]} # check if input method is event or raw text if request_json.get("input", "").startswith("/"): intent_id = request_json.get("input").split("/")[1] confidence = 1 else: intent_id, confidence, suggestions = predict( request_json.get("input")) app.logger.info("intent_id => %s" % intent_id) intent = Intent.objects.get(intentId=intent_id) # set intent as fallback intent if intent is None: intent = Intent.objects.get( intentId=app.config["DEFAULT_FALLBACK_INTENT_NAME"]) parameters = [] if intent.parameters: parameters = intent.parameters result_json["extractedParameters"] = request_json.get( "extractedParameters") or {} if ((request_json.get("complete") is None) or (request_json.get("complete") is True)): result_json["intent"] = { "object_id": str(intent.id), "confidence": confidence, "id": intent.intentId } if parameters: # Extract NER entities result_json["extractedParameters"].update( entity_extraction.predict(intent_id, request_json.get("input"))) missing_parameters = [] result_json["missingParameters"] = [] result_json["parameters"] = [] for parameter in parameters: result_json["parameters"].append({ "name": parameter.name, "type": parameter.type, "required": parameter.required }) if parameter.required: if parameter.name not in result_json[ "extractedParameters"].keys(): result_json["missingParameters"].append( parameter.name) missing_parameters.append(parameter) if missing_parameters: result_json["complete"] = False current_node = missing_parameters[0] result_json["currentNode"] = current_node["name"] result_json["speechResponse"] = split_sentence( current_node["prompt"]) else: result_json["complete"] = True context["parameters"] = result_json["extractedParameters"] else: result_json["complete"] = True elif request_json.get("complete") is False: if "cancel" not in intent.name: intent_id = request_json["intent"]["id"] app.logger.info(intent_id) intent = Intent.objects.get(intentId=intent_id) extracted_parameter = entity_extraction.replace_synonyms({ request_json.get("currentNode"): request_json.get("input") }) # replace synonyms for entity values result_json["extractedParameters"].update(extracted_parameter) result_json["missingParameters"].remove( request_json.get("currentNode")) if len(result_json["missingParameters"]) == 0: result_json["complete"] = True context = { "parameters": result_json["extractedParameters"], "context": request_json["context"] } else: missing_parameter = result_json["missingParameters"][0] result_json["complete"] = False current_node = [ node for node in intent.parameters if missing_parameter in node.name ][0] result_json["currentNode"] = current_node.name result_json["speechResponse"] = split_sentence( current_node.prompt) else: result_json["currentNode"] = None result_json["missingParameters"] = [] result_json["parameters"] = {} result_json["intent"] = {} result_json["complete"] = True if result_json["complete"]: if intent.apiTrigger: isJson = False parameters = result_json["extractedParameters"] headers = intent.apiDetails.get_headers() app.logger.info("headers %s" % headers) url_template = Template(intent.apiDetails.url, undefined=SilentUndefined) rendered_url = url_template.render(**context) if intent.apiDetails.isJson: isJson = True request_template = Template(intent.apiDetails.jsonData, undefined=SilentUndefined) parameters = json.loads(request_template.render(**context)) try: result = call_api(rendered_url, intent.apiDetails.requestType, headers, parameters, isJson) except Exception as e: app.logger.warn("API call failed", e) result_json["speechResponse"] = [ "Service is not available. Please try again later." ] else: context["result"] = result template = Template(intent.speechResponse, undefined=SilentUndefined) result_json["speechResponse"] = split_sentence( template.render(**context)) else: context["result"] = {} template = Template(intent.speechResponse, undefined=SilentUndefined) result_json["speechResponse"] = split_sentence( template.render(**context)) app.logger.info(request_json.get("input"), extra=result_json) return build_response.build_json(result_json) else: return abort(400)
def api(): """ Endpoint to converse with chatbot. Chat context is maintained by exchanging the payload between client and bot. sample input/output payload => { "currentNode": "", "complete": false, "parameters": [], "extractedParameters": {}, "missingParameters": [], "intent": { }, "context": {}, "input": "hello", "speechResponse": [ ] } :param json: :return json: """ request_json = request.get_json(silent=True) result_json = request_json if request_json: context = {} context["context"] = request_json["context"] if app.config["DEFAULT_WELCOME_INTENT_NAME"] in request_json.get( "input"): intent = Intent.objects( intentId=app.config["DEFAULT_WELCOME_INTENT_NAME"]).first() result_json["complete"] = True result_json["intent"]["object_id"] = str(intent.id) result_json["intent"]["id"] = str(intent.intentId) result_json["input"] = request_json.get("input") template = Template( intent.speechResponse, undefined=SilentUndefined) result_json["speechResponse"] = split_sentence(template.render(**context)) logger.info(request_json.get("input"), extra=result_json) return build_response.build_json(result_json) intent_id, confidence,suggetions = predict(request_json.get("input")) app.logger.info("intent_id => %s"%intent_id) intent = Intent.objects.get(intentId=intent_id) if intent.parameters: parameters = intent.parameters else: parameters = [] if ((request_json.get("complete") is None) or ( request_json.get("complete") is True)): result_json["intent"] = { "object_id": str(intent.id), "confidence": confidence, "id": str(intent.intentId) } if parameters: # Extract NER entities extracted_parameters = entity_extraction.predict( intent_id, request_json.get("input")) missing_parameters = [] result_json["missingParameters"] = [] result_json["extractedParameters"] = {} result_json["parameters"] = [] for parameter in parameters: result_json["parameters"].append({ "name": parameter.name, "type": parameter.type, "required": parameter.required }) if parameter.required: if parameter.name not in extracted_parameters.keys(): result_json["missingParameters"].append( parameter.name) missing_parameters.append(parameter) result_json["extractedParameters"] = extracted_parameters if missing_parameters: result_json["complete"] = False current_node = missing_parameters[0] result_json["currentNode"] = current_node["name"] result_json["speechResponse"] = split_sentence(current_node["prompt"]) else: result_json["complete"] = True context["parameters"] = extracted_parameters else: result_json["complete"] = True elif request_json.get("complete") is False: if "cancel" not in intent.name: intent_id = request_json["intent"]["id"] intent = Intent.objects.get(intentId=intent_id) extracted_parameter = entity_extraction.replace_synonyms({ request_json.get("currentNode"): request_json.get("input") }) # replace synonyms for entity values result_json["extractedParameters"].update(extracted_parameter) result_json["missingParameters"].remove( request_json.get("currentNode")) if len(result_json["missingParameters"]) == 0: result_json["complete"] = True context = {} context["parameters"] = result_json["extractedParameters"] context["context"] = request_json["context"] else: missing_parameter = result_json["missingParameters"][0] result_json["complete"] = False current_node = [ node for node in intent.parameters if missing_parameter in node.name][0] result_json["currentNode"] = current_node.name result_json["speechResponse"] = split_sentence(current_node.prompt) else: result_json["currentNode"] = None result_json["missingParameters"] = [] result_json["parameters"] = {} result_json["intent"] = {} result_json["complete"] = True if result_json["complete"]: if intent.apiTrigger: isJson = False parameters = result_json["extractedParameters"] headers = intent.apiDetails.get_headers() app.logger.info("headers %s"%headers) url_template = Template( intent.apiDetails.url, undefined=SilentUndefined) rendered_url = url_template.render(**context) if intent.apiDetails.isJson: isJson = True request_template = Template( intent.apiDetails.jsonData, undefined=SilentUndefined) parameters = json.loads(request_template.render(**context)) try: result = call_api(rendered_url, intent.apiDetails.requestType,headers, parameters, isJson) except Exception as e: app.logger.warn("API call failed", e) result_json["speechResponse"] = ["Service is not available. Please try again later."] else: context["result"] = result template = Template( intent.speechResponse, undefined=SilentUndefined) result_json["speechResponse"] = split_sentence(template.render(**context)) else: context["result"] = {} template = Template(intent.speechResponse, undefined=SilentUndefined) result_json["speechResponse"] = split_sentence(template.render(**context)) logger.info(request_json.get("input"), extra=result_json) return build_response.build_json(result_json) else: return abort(400)