Esempio n. 1
0
def api():
    """
    Endpoint to converse with chatbot
    :param json:
    :return:
    """
    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"]["intentId"] = intent.intentId
            result_json["intent"]["id"] = str(intent.id)
            result_json["input"] = request_json.get("input")
            template = Template(intent.speechResponse,
                                undefined=SilentUndefined)
            result_json["speechResponse"] = template.render(**context)

            logger.info(request_json.get("input"), extra=result_json)
            return build_response.build_json(result_json)

        intent_id, confidence = predict(request_json.get("input"))
        intent = Intent.objects.get(id=ObjectId(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"] = {
                "name": intent.name,
                "confidence": confidence,
                "id": str(intent.id)
            }

            if parameters:
                # Extract NER entities
                entity_extraction = EntityExtractor()
                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"] = 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(id=ObjectId(intent_id))
                result_json["extractedParameters"][request_json.get(
                    "currentNode")] = request_json.get("input")

                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"] = 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"]

                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 = request_template.render(**context)

                try:
                    result = call_api(rendered_url,
                                      intent.apiDetails.requestType,
                                      parameters, isJson)
                except Exception as e:
                    print(e)
                    result_json[
                        "speechResponse"] = "Service is not available. "
                else:
                    print(result)
                    context["result"] = result
                    template = Template(intent.speechResponse,
                                        undefined=SilentUndefined)
                    result_json["speechResponse"] = template.render(**context)
            else:
                context["result"] = {}
                template = Template(intent.speechResponse,
                                    undefined=SilentUndefined)
                result_json["speechResponse"] = template.render(**context)
        logger.info(request_json.get("input"), extra=result_json)
        return build_response.build_json(result_json)
    else:
        return abort(400)
Esempio n. 2
0
def api():
    requestJson = request.get_json(silent=True)
    resultJson = requestJson

    if requestJson:

        context = {}
        context["context"] = requestJson["context"]

        if app.config["DEFAULT_WELCOME_INTENT_NAME"] in requestJson.get(
                "input"):
            story = Story.objects(
                intentName=app.config["DEFAULT_WELCOME_INTENT_NAME"]).first()
            resultJson["complete"] = True
            resultJson["intent"]["name"] = story.storyName
            resultJson["intent"]["storyId"] = str(story.id)
            resultJson["input"] = requestJson.get("input")
            template = Template(story.speechResponse,
                                undefined=SilentUndefined)
            resultJson["speechResponse"] = template.render(**context)

            logger.info(requestJson.get("input"), extra=resultJson)
            return buildResponse.buildJson(resultJson)

        intentClassifier = IntentClassifier()
        storyId = intentClassifier.predict(requestJson.get("input"))
        story = Story.objects.get(id=ObjectId(storyId))

        if story.parameters:
            parameters = story.parameters
        else:
            parameters = []

        if ((requestJson.get("complete") is None)
                or (requestJson.get("complete") is True)):
            resultJson["intent"] = {
                "name": story.intentName,
                "storyId": str(story.id)
            }

            if parameters:
                extractedParameters = sequenceLabeler.predict(
                    storyId, requestJson.get("input"))
                missingParameters = []
                resultJson["missingParameters"] = []
                resultJson["extractedParameters"] = {}
                resultJson["parameters"] = []
                for parameter in parameters:
                    resultJson["parameters"].append({
                        "name":
                        parameter.name,
                        "type":
                        parameter.type,
                        "required":
                        parameter.required
                    })

                    if parameter.required:
                        if parameter.name not in extractedParameters.keys():
                            resultJson["missingParameters"].append(
                                parameter.name)
                            missingParameters.append(parameter)

                resultJson["extractedParameters"] = extractedParameters

                if missingParameters:
                    resultJson["complete"] = False
                    currentNode = missingParameters[0]
                    resultJson["currentNode"] = currentNode["name"]
                    resultJson["speechResponse"] = currentNode["prompt"]
                else:
                    resultJson["complete"] = True
                    context["parameters"] = extractedParameters
            else:
                resultJson["complete"] = True

        elif (requestJson.get("complete") is False):
            if "cancel" not in story.intentName:
                storyId = requestJson["intent"]["storyId"]
                story = Story.objects.get(id=ObjectId(storyId))
                resultJson["extractedParameters"][requestJson.get(
                    "currentNode")] = requestJson.get("input")

                resultJson["missingParameters"].remove(
                    requestJson.get("currentNode"))

                if len(resultJson["missingParameters"]) == 0:
                    resultJson["complete"] = True
                    context = {}
                    context["parameters"] = resultJson["extractedParameters"]
                    context["context"] = requestJson["context"]
                else:
                    missingParameter = resultJson["missingParameters"][0]
                    resultJson["complete"] = False
                    currentNode = [
                        node for node in story.parameters
                        if missingParameter in node.name
                    ][0]
                    resultJson["currentNode"] = currentNode.name
                    resultJson["speechResponse"] = currentNode.prompt
            else:
                resultJson["currentNode"] = None
                resultJson["missingParameters"] = []
                resultJson["parameters"] = {}
                resultJson["intent"] = {}
                resultJson["complete"] = True

        if resultJson["complete"]:
            if story.apiTrigger:
                isJson = False
                parameters = resultJson["extractedParameters"]

                urlTemplate = Template(story.apiDetails.url,
                                       undefined=SilentUndefined)
                renderedUrl = urlTemplate.render(**context)
                if story.apiDetails.isJson:
                    isJson = True
                    requestTemplate = Template(story.apiDetails.jsonData,
                                               undefined=SilentUndefined)
                    parameters = requestTemplate.render(**context)

                try:
                    result = callApi(renderedUrl, story.apiDetails.requestType,
                                     parameters, isJson)
                except Exception as e:
                    print(e)
                    resultJson["speechResponse"] = "Service is not available. "
                else:
                    print(result)
                    context["result"] = result
                    template = Template(story.speechResponse,
                                        undefined=SilentUndefined)
                    resultJson["speechResponse"] = template.render(**context)
            else:
                context["result"] = {}
                template = Template(story.speechResponse,
                                    undefined=SilentUndefined)
                resultJson["speechResponse"] = template.render(**context)
        logger.info(requestJson.get("input"), extra=resultJson)
        return buildResponse.buildJson(resultJson)
    else:
        return abort(400)
Esempio n. 3
0
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)
def api():
    requestJson = request.get_json(silent=True)
    resultJson = requestJson

    if requestJson:

        context = {}
        context["context"] = requestJson["context"]

        if app.config["DEFAULT_WELCOME_INTENT_NAME"] in requestJson.get("input"):
            story=Story.objects(
                intentName=app.config["DEFAULT_WELCOME_INTENT_NAME"]).first()
            resultJson["complete"] = True
            resultJson["intent"]["name"] = story.storyName
            resultJson["intent"]["storyId"] = str(story.id)
            resultJson["input"] = requestJson.get("input")
            template = Template(story.speechResponse, undefined=SilentUndefined)
            resultJson["speechResponse"] = template.render(**context)

            logger.info(requestJson.get("input"), extra=resultJson)
            return buildResponse.buildJson(resultJson)

        intentClassifier = IntentClassifier()
        storyId = intentClassifier.predict(requestJson.get("input"))
        story = Story.objects.get(id=ObjectId(storyId))


        if story.parameters:
            parameters = story.parameters
        else:
            parameters = []

        if ((requestJson.get("complete") is None) or (requestJson.get("complete") is True)):
            resultJson["intent"] = {
                "name": story.intentName,
                "storyId": str(story.id)
            }

            if parameters:
                extractedParameters = sequenceLabeler.predict(storyId,
                                                              requestJson.get("input")
                                                              )
                missingParameters = []
                resultJson["missingParameters"] = []
                resultJson["extractedParameters"] = {}
                resultJson["parameters"] = []
                for parameter in parameters:
                    resultJson["parameters"].append({
                        "name": parameter.name,
                        "required": parameter.required
                    })

                    if parameter.required:
                        if parameter.name not in extractedParameters.keys():
                            resultJson["missingParameters"].append(parameter.name)
                            missingParameters.append(parameter)

                resultJson["extractedParameters"] = extractedParameters

                if missingParameters:
                    resultJson["complete"] = False
                    currentNode = missingParameters[0]
                    resultJson["currentNode"] = currentNode["name"]
                    resultJson["speechResponse"] = currentNode["prompt"]
                else:
                    resultJson["complete"] = True

                    context["parameters"] = extractedParameters


                    try:
                        if story.apiTrigger:
                            isJson = False
                            parameters = extractedParameters

                            urlTemplate = Template(story.apiDetails.url, undefined=SilentUndefined)
                            renderedUrl = urlTemplate.render(**context)
                            if story.apiDetails.isJson:
                                isJson = True
                                requestTemplate = Template(story.apiDetails.jsonData, undefined=SilentUndefined)
                                parameters = requestTemplate.render(**context)

                            result = callApi(renderedUrl,
                                             story.apiDetails.requestType,
                                             parameters,isJson)

                        else:
                            result = {}

                        context["result"] = result
                        resultTemplate = Template(story.speechResponse, undefined=SilentUndefined)
                        resultJson["speechResponse"] = resultTemplate.render(**context)
                    except Exception as e:
                        print(e)
                        resultJson["speechResponse"] = "Service is not available."
            else:
                resultJson["complete"] = True
                resultTemplate = Template(story.speechResponse, undefined=SilentUndefined)
                resultJson["speechResponse"] = resultTemplate.render(**context)


        elif (requestJson.get("complete") is False):
            if "cancel" not in story.intentName:
                storyId = requestJson["intent"]["storyId"]
                story = Story.objects.get(id=ObjectId(storyId))
                resultJson["extractedParameters"][requestJson.get("currentNode")] = requestJson.get("input")

                resultJson["missingParameters"].remove(requestJson.get("currentNode"))

                if len(resultJson["missingParameters"]) == 0:
                    resultJson["complete"] = True
                    context = {}
                    context["parameters"] = resultJson["extractedParameters"]
                    context["context"] = requestJson["context"]
                    try:
                        if story.apiTrigger:
                            isJson = False
                            parameters = resultJson["extractedParameters"]

                            urlTemplate = Template(story.apiDetails.url, undefined=SilentUndefined)
                            renderedUrl = urlTemplate.render(**context)
                            if story.apiDetails.isJson:
                                isJson = True
                                requestTemplate = Template(story.apiDetails.jsonData, undefined=SilentUndefined)
                                parameters = requestTemplate.render(**context)

                            result = callApi(renderedUrl,
                                             story.apiDetails.requestType,
                                             parameters,isJson)
                            print(result)
                        else:
                            result = {}
                        context["result"] = result

                        template = Template(story.speechResponse, undefined=SilentUndefined)
                        resultJson["speechResponse"] = template.render(**context)
                    except Exception as e:
                        print(e)
                        resultJson["speechResponse"] = "Service is not available. "
                else:
                    missingParameter = resultJson["missingParameters"][0]
                    resultJson["complete"] = False
                    currentNode = [node for node in story.parameters if missingParameter in node.name][0]
                    resultJson["currentNode"] = currentNode.name
                    resultJson["speechResponse"] = currentNode.prompt
            else:
                resultJson["currentNode"] = None
                resultJson["missingParameters"] = []
                resultJson["parameters"] = {}
                resultJson["intent"] = {}
                resultJson["complete"] = True
                template = Template(story.speechResponse, undefined=SilentUndefined)
                resultJson["speechResponse"] = template.render(**context)
        logger.info(requestJson.get("input"), extra=resultJson)
        return buildResponse.buildJson(resultJson)
    else:
        return abort(400)
Esempio n. 5
0
def api():
    print("Inside /api/.v1")
    requestJson = request.get_json(silent=True)
    resultJson = requestJson
    print("Test.....", requestJson)
    print("Bot Iddddddddddddddddddddddddddddddd",requestJson.get("botId"))
    if requestJson:


        context = {}
        context["context"] = requestJson["context"]

        if app.config["DEFAULT_WELCOME_INTENT_NAME"] in requestJson.get(
                "input"):
            print("--------------insideif------------------")
            story = Story.objects(
                intentName=app.config["DEFAULT_WELCOME_INTENT_NAME"]).first()
            print("Story" , story)
            resultJson["complete"] = True
#            resultJson["intent"]["name"] = story.storyName
            resultJson["intent"]["storyId"] = str(story.id)
            resultJson["input"] = requestJson.get("input")
            template = Template(
                story.speechResponse,
                undefined=SilentUndefined)
            resultJson["speechResponse"] = template.render(**context)

            logger.info(requestJson.get("input"), extra=resultJson)
            return buildResponse.buildJson(resultJson)
        print("OutSide if")

        intentClassifier = IntentClassifier()
        try:
            storyId = intentClassifier.predict(requestJson.get("input"))
            print("Story Id",storyId)
        except AttributeError:
            resultJson["speechResponse"]="Question not available"
            return buildResponse.buildJson(resultJson)
        story = Story.objects.get(id=ObjectId(storyId))

        if story.parameters:
            print("Inside story.params")
            parameters = story.parameters
        else:
            print("No paramters")
            parameters = []

        if ((requestJson.get("complete") is None) or (
                requestJson.get("complete") is True)):
            print("Check whether complete is none or true")
            resultJson["intent"] = {
                "name": story.intentName,
                "storyId": str(story.id)
            }
            print(resultJson["intent"])

            if parameters:
                print("Check whether parametrs are present are not")
                extractedParameters = sequenceLabeler.predict(
                    storyId, requestJson.get("input"))
                print("Extracted parameters",extractedParameters)
                missingParameters = []
                resultJson["missingParameters"] = []
                resultJson["extractedParameters"] = {}
                resultJson["parameters"] = []
                for parameter in parameters:
                    print("If parameters are present")
                    resultJson["parameters"].append({
                        "name": parameter.name,
                        "type": parameter.type,
                        "required": parameter.required
                    })
                    print("Result JSON...",resultJson)

                    if parameter.required:
                        print("Check whether parameter is required are not")
                        if parameter.name not in extractedParameters.keys():
                            print("Check whether paramter name is present in extracted paramters")
                            resultJson["missingParameters"].append(
                                parameter.name)
                            missingParameters.append(parameter)
                            print("Result JSON2",resultJson)

                resultJson["extractedParameters"] = extractedParameters
                print("F Result json",resultJson)

                if missingParameters:
                    print("Check whether missing parameters is present or not")
                    resultJson["complete"] = False
                    currentNode = missingParameters[0]
                    resultJson["currentNode"] = currentNode["name"]
                    resultJson["speechResponse"] = currentNode["prompt"]
                    print("Inside missingparameters if ",resultJson)
                else:
                    resultJson["complete"] = True
                    context["parameters"] = extractedParameters
            else:
                resultJson["complete"] = True

        elif (requestJson.get("complete") is False):
            if "cancel" not in story.intentName:
                storyId = requestJson["intent"]["storyId"]
                story = Story.objects.get(id=ObjectId(storyId))
                resultJson["extractedParameters"][requestJson.get(
                    "currentNode")] = requestJson.get("input")

                resultJson["missingParameters"].remove(
                    requestJson.get("currentNode"))

                if len(resultJson["missingParameters"]) == 0:
                    resultJson["complete"] = True
                    context = {}
                    context["parameters"] = resultJson["extractedParameters"]
                    context["context"] = requestJson["context"]
                else:
                    missingParameter = resultJson["missingParameters"][0]
                    resultJson["complete"] = False
                    currentNode = [
                        node for node in story.parameters if missingParameter in node.name][0]
                    resultJson["currentNode"] = currentNode.name
                    resultJson["speechResponse"] = currentNode.prompt
            else:
                resultJson["currentNode"] = None
                resultJson["missingParameters"] = []
                resultJson["parameters"] = {}
                resultJson["intent"] = {}
                resultJson["complete"] = True

        if resultJson["complete"]: 
            if story.apiTrigger:
                isJson = False
                isHeader=False
                parameters = resultJson["extractedParameters"]

                urlTemplate = Template(story.apiDetails.url, undefined=SilentUndefined)
                renderedUrl = urlTemplate.render(**context)
                if story.apiDetails.isJson and story.apiDetails.isHeader:
                    isJson = True
                    isHeader= True
                    requestTemplate = Template(story.apiDetails.jsonData,story.apiDetails.headerData, undefined=SilentUndefined)
                    parameters = requestTemplate.render(**context)
                elif story.apiDetails.isJson:
                    isJson = True
                    requestTemplate = Template(story.apiDetails.jsonData,
                                               undefined=SilentUndefined)
                    parameters = requestTemplate.render(**context)
                elif story.apiDetails.isHeader:
                    isHeader = True
                    requestTemplate = Template(story.apiDetails.headerData,
                                               undefined=SilentUndefined)
                    parameters = requestTemplate.render(**context)
                try:
                    result = callApi(renderedUrl,
                                     story.apiDetails.requestType,
                                     parameters,story.apiDetails.headerData,isJson,isHeader)
                except Exception as e:
                    print(e)
                    resultJson["speechResponse"] = "Service is not available. "
                else:
                    print(result)
                    context["result"] = result
                    template = Template(story.speechResponse, undefined=SilentUndefined)
                    resultJson["speechResponse"] = template.render(**context)
            else:
                context["result"] = {}
                template = Template(story.speechResponse, undefined=SilentUndefined)
                resultJson["speechResponse"] = template.render(**context)
        logger.info(requestJson.get("input"), extra=resultJson)
        return buildResponse.buildJson(resultJson)
    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)