ConversationAI: Integrating DialogflowCX with backends data sources using webhooks

Date:

image

I explained the setup of DialogflowCX and I explained how to create a conversational flow design and demonstrated how NLU can interpret user requests and understand context. I also used Entities and Intents to navigate and use variables as parameters provided by the user.

This approach does not focus on machine learning but provides integrations with Dialogflow, a Conversational AI Platform.

Cloud Spanner

image

I have uploaded the data to.

image

Cloud Function - Request Handler

  • We will use cloud function as a request handler.
  • Ensure the spanner and cloud function roles are assigned to the servce agent.
  • Also update the requirements.txt as I forgot and wasted sometime debuging this.

image

There are 3 parts to this cloud function:

  1. parse the request from DialogflowCX
    intent = req.get('intentInfo').get('displayName')
    parameters = req.get('intentInfo').get('parameters')
    
  2. Cloud Function to query Cloud Spanner.
      with database.snapshot() as snapshot:
     results = snapshot.execute_sql(query)
    
  3. Frame the response to DialogflowCX
      "session_info": {
             "parameters": {
                 "param-url": output
             }
         }
    

Below is the cloud funciton

import json
import os
from flask import Flask, request, jsonify
from google.cloud import spanner

# Replace with your instance ID and database ID
INSTANCE_ID = "knowledgebase"
DATABASE_ID = "knowledgebase"
# Initialize the Spanner client and connect to the database
spanner_client = spanner.Client()
instance = spanner_client.instance(INSTANCE_ID)
database = instance.database(DATABASE_ID)

app = Flask(__name__)

@app.route('/', methods=['POST'])
def webhook(request):
    # Part 1: parse the request
    # Print the request data for debugging
    print(f"Request data: {request.get_json()}")

    # Get the request data from Dialogflow
    req = request.get_json(silent=True, force=True)

    # Check if req is None
    if req is None:
        return jsonify({"fulfillmentText": "Error: No request data received."})

    # Extract relevant information from the request
    intent = req.get('intentInfo').get('displayName')
    parameters = req.get('intentInfo').get('parameters')

    print(f"parameters: {parameters}")

    # Access the 'topic' parameter
    topic = parameters.get('topic', {}).get('resolvedValue')

    # Part 2: Cloud Function to query Cloud Spanner.

    # Your SQL query
    query = f"SELECT url FROM urlmapping where topic = '{topic}'"

    with database.snapshot() as snapshot:
        results = snapshot.execute_sql(query)

        # Process the results
        output = []
        for row in results:
            output.append(f"URL: {row}")


    response_text = "Some text from the cloud function: Please go to the URL for more information."


    # Part 3: Frame the response.
    response_payload = {
        "fulfillment_response": {
            "messages": [
                {
                    "text": {
                        "text": [response_text]
                    }
                }
            ]
        },
        "session_info": {
            "parameters": {
                "param-url": output
            }
        },
        "payload": {
            "customField1": "customValue1"
        }
    }

    # Return the response as a JSON object
    return jsonify(response_payload)

if __name__ == '__main__':
    port = int(os.environ.get('PORT', 5000))
    app.run(debug=True, host='0.0.0.0', port=port)

Webhook

Creating a webhook is very simple. Just point to the HTTP URL of the cloud function and we ready to go.

image

Fullfilment from the webhook

Now we need to inform the intent to use the webook for fullfilment of the reposnse.

image

We update the Agent reposnse to read the paramter which we send from the cloud funciton. image

Testing this

  1. DFCX with NLU interpreted the request parameter as a query for foundational basics.
  2. DFCX then calls a webhook, which triggers a Cloud Function.
  3. The Cloud Function parses the parameter ‘topic.’ Since the value is ‘foundation,’ it queries the Spanner table.
  4. The Spanner table returns the following URL: 1, foundation, https://nuneskris.github.io/portfolio/.
  5. The Cloud Function sends the URL back to DFCX: https://nuneskris.github.io/portfolio/.
  6. DFCX responds to the user with the provided URL.

image