ConversationAI: Integrating DialogflowCX with backends data sources using webhooks
Date:
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
I have uploaded the data to.
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.
There are 3 parts to this cloud function:
- parse the request from DialogflowCX
intent = req.get('intentInfo').get('displayName') parameters = req.get('intentInfo').get('parameters')
- Cloud Function to query Cloud Spanner.
with database.snapshot() as snapshot: results = snapshot.execute_sql(query)
- 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.
Fullfilment from the webhook
Now we need to inform the intent to use the webook for fullfilment of the reposnse.
We update the Agent reposnse to read the paramter which we send from the cloud funciton.
Testing this
- DFCX with NLU interpreted the request parameter as a query for foundational basics.
- DFCX then calls a webhook, which triggers a Cloud Function.
- The Cloud Function parses the parameter ‘topic.’ Since the value is ‘foundation,’ it queries the Spanner table.
- The Spanner table returns the following URL: 1, foundation, https://nuneskris.github.io/portfolio/.
- The Cloud Function sends the URL back to DFCX: https://nuneskris.github.io/portfolio/.
- DFCX responds to the user with the provided URL.