Just recently on October 10th, Google announced a change in name of API.AI into DialogFlow. There are a couple of new features following this change. Regardless of what has been changed, in this post we are going to share a simple way of how to integrate your agents that is created using DialogFlow into any Qiscus chat SDK application.
Injustice - Developers Among Us (SciFiDevCon 2024)
Integrating dialog flow (api.ai) into qiscus sdk chat application
1. Integrating DialogFlow (API.ai) into
Qiscus SDK Chat Application
Just recently on October 10th, Google announced a change in name of API.AI into DialogFlow. There
are a couple of new features following this change. Regardless of what has been changed, in this
post we are going to share a simple way of how to integrate your agents that is created using
DialogFlow into any Qiscus SDK chat application.
As DialogFlow doesn't have a famous 'one-click integration' feature for Qiscus (yet), we need to
make a workaround to do so. Fortunately, DialogFlow provides some integration ways through its
SDK options, here in the image, you can see several programming languages that you can use for
your agent integration.
2. Image of DialogFlow SDK for integration
For our simplicity purpose, we are going to use our last article on how to create a simple chat
application using QiscusSDK and how to integrate a simple echo bot into it as prior requirement to
this post. You can find the codes here. Since it uses Python as the webhook, in this article we are
going to use DialogFlow SDK for Python as well called apiai (this might changes later as the effect
of name change).
Another thing to note is that we assume you already have an agent or two created in DialogFlow, if
not please refer to the basic tuts to create one.
1. Add DialogFlow SDK Python Package
Alright, let's get started! First thing first, let's add DialogFlow SDK python package (apiai) into our
project, come on open setup.py file, and add it,
from setuptools import setup, find_packages
setup(
name='simplebot',
version='1.0',
long_description=__doc__,
packages=find_packages(),
include_package_data=True,
zip_safe=False,
install_requires=[
'apiai',
3. 'flask',
'requests'
],
)
and let's import that package into our simplebot/views.py file then instantiate new object
from this package,
import apiai
import json
import requests
from flask import render_template, request
from simplebot import app
app_id = "YOUR_APP_ID"
secret_key = "YOUR_SECRET_KEY"
sender_email = "YOUR_BOT_EMAIL"
bot_name = "YOUR_BOT_NAME"
qiscus_sdk_url = "https://{}.qiscus.com".format(app_id)
client_access_token = "YOUR_DIALOGFLOW_CLIENT_ACCESS_TOKEN"
ai = apiai.ApiAI(client_access_token)
...
.
Notice in the code above, we need client_access_token to initiate new object from the
package. So please make sure you already got this token from your agent DialogFlow console
dashboard and assign it to the client_access_token, you may want to see this image to locate
where it is.
4. image of console
2. Incoming Message and Agent Response
After you got this package set, let's implement it in our index() function. First we will need to get
query from Qiscus chat app to be passed to the DialogFlow agent before we send it to get the
response from agent.
...
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
payload = request.get_json().get('payload')
room_id = payload.get("room").get("id")
message = payload.get("message").get("text")
# let's prepare the incoming message (query) we want
to send to dialogflow agent
conv = ai.text_request()
conv.session_id =
"ADD_YOUR_UNIQUE_SESSION_ID(ANY_SESSION_ID_WOULD_WORK)"
conv.query = message
# and let's get the response from dialogflow agent
response = conv.getresponse()
response_json =
json.loads(response.read().decode('utf-8'))
5. response_messages =
response_json.get("result").get("fulfillment").get("messages")
post_url =
"{}/api/v2/rest/post_comment".format(qiscus_sdk_url)
headers = {"QISCUS_SDK_SECRET": secret_key}
data = {
"sender_email": sender_email,
"room_id": room_id,
"message": message,
"type": "text",
"payload": {}
}
req = requests.post(post_url, headers=headers,
params=data)
...
What we need to do next is just to send back any response we got from agent to the Qiscus chat
app. This can be anything: plain text or any additional payload. So, before we return it back, we need
to know the structure of payload that is returned by our agent at DialogFlow, please have a look at
JSON code below, this JSON code is the payload that is returned from our agent in DialogFlow.
{
"id": "354eaf3c-c40e-42e4-acf6-fc2ef0e71799",
"timestamp": "2017-10-26T08:11:58.239Z",
"lang": "en",
"result": {
"source": "agent",
"resolvedQuery": "yo",
"action": "hi",
"actionIncomplete": false,
"parameters": {},
"contexts": [],
"metadata": {
"intentId": "fe8dbb22-43bf-4cb4-b634-48c3a2af98ae",
"webhookUsed": "false",
"webhookForSlotFillingUsed": "false",
"intentName": "hi"
},
"fulfillment": {
"speech": "Hi! How are you doing?",
"messages": [
{
6. "type": 0,
"id": "948f5dad-550c-4fa1-93ba-3819d8e42fbb",
"speech": "Hi! How are you doing?"
}
]
},
"score": 1
},
"status": {
"code": 200,
"errorType": "success"
},
"sessionId": "d70073ae-0cdb-4bc4-b7d9-d8d0b16b98af"
}
From JSON code above, there is a fulfillment field. It has additional children fields that are
actual responses from our agent which we are interested in.
Also read: "Making your Apps “Chatable”"
Notice the messages field? its value is a list. So we may assume our agent could return one or
more messages when we make a request to DialogFlow. This could be another text or additional
custom payload, such as payload for button or card. However, to simplify this process, let's handle
text message only.
Ok, let's modify our index() function in views.py file again.
...
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
payload = request.get_json().get('payload')
room_id = payload.get("room").get("id")
message = payload.get("message").get("text")
# let's prepare the incoming message (query) we want
to send to dialogflow agent
conv = ai.text_request()
conv.session_id =
"ADD_YOUR_UNIQUE_SESSION_ID(ANY_SESSION_ID_WOULD_WORK)"
conv.query = message
# and let's get the response from dialogflow agent
response = conv.getresponse()
response_json =
8. 3. Webhook
Since we've been developing this integration locally, Qiscus SDK won't recognise our webhook even
though we are trying to add our local webhook address to the Qiscus SDK. So to help making our
webhook open to the internet, we are going to use ngrok and add the generated temporary
subdomain addresses into our Qiscus SDK, please refer to this for ngrok.
After you do that, please try to have a chat again through generated subdomain address in your
browser. Voila, you got a reply from your agent in DialogFlow!
Accompanying codes can be found at https://github.com/qiscus/qiscus-dialogflow. You can also
experience directly at https://qiscusdialog.herokuapp.com/.
Closing
To sum up, this article is only focusing on how we integrate our agent that is created in DialogFlow
which returns plain text only. In order to leverage your agent capability, you may want to add
additional custom payload as additional fulfillment response. For example you may want to return
message that contains image and buttons from DialogFlow. You can refer to Qiscus docs for any type
of comments that is supported by Qiscus as well as how to add custom payload in DialogFlow for
more information.