Integrating Dialogflow v2 into Qiscus Multichannel
This article is posted at https://blog.qiscus.com/integrating-dialogflow-v2-qiscus-multichannel/ as well
This article is an update to the previous one about Integrating Dialogflow into Qiscus SDK. Dialogflow v2 embraces the concept of service account and no longer uses client access token approach. Hence, there will be a gap in integrating Dialogflow bot into our services from the v1 point of view. We are going to use the Qiscus Multichannel Platform widget as user client instead of the Qiscus SDK widget in this article.
If you already have an existing agent in Dialogflow, it is recommended to create a back up file so that if something goes wrong, you can revert to v1 easily. You can do this by exporting the agent in the ‘Export and Import’ section in the settings panel and click ‘EXPORT AS ZIP’.
Setting up a Service Account
As mentioned above, in v2, Dialogflow is using the service account. Thus, in the first step, we are going to set up Dialogflow agent’s service account; more precisely, its key.
So let’s go to the settings page, and under the general tab, click on the service account name.

This will open up your Google Cloud Platform project’s service account page. In its table, you will see ‘Dialogflow integrations’ service account already created.
Click on the three vertical dots on the right and click the ‘Create Key’ option. Keep it as a JSON file type, and save it locally. We will use it later.

Prepare the Chatbot Webhook
As we already have the service account key, we will then set up our bot webhook to connect the Dialogflow agent with Qiscus Multichannel. In this article, we are going to use the codebase from the previous article located at https://bitbucket.org/qiscus/qiscus-dialogflow/. We will modify several parts of the codes.
Firstly, if you open up the codes, you will notice in the setup.py
file that it is using the apiai
python package. We are going to change this into the dialogflow
package as the supported package for Dialogflow v2.
from setuptools import setup, find_packages setup( name='qiscus_dialogflow', version='1.0', long_description=__doc__, packages=find_packages(), include_package_data=True, zip_safe=False, install_requires=[ 'flask', 'dialogflow', 'requests' ], )
Next, as we only need to detect intent from text and get response from the agent, we are going to utilise the Dialogflow package. The example is illustrated here: https://github.com/googleapis/dialogflow-python-client-v2/blob/master/samples/detect_intent_texts.py. Let’s save the file as dialogflow_response.py
in the main directory and modify the code a little to look like this:
def detect_intent_texts(project_id, session_id, texts, language_code="en_US"): """Returns the result of detect intent with texts as inputs. Using the same `session_id` between requests allows continuation of the conversation.""" import dialogflow_v2 as dialogflow session_client = dialogflow.SessionsClient() session = session_client.session_path(project_id, session_id) print('Session path: {}\n'.format(session)) text_input = dialogflow.types.TextInput( text=texts, language_code=language_code) query_input = dialogflow.types.QueryInput(text=text_input) response = session_client.detect_intent( session=session, query_input=query_input) return response.query_result.intent.display_name, \ response.query_result.intent_detection_confidence, \ response.query_result.fulfillment_text # [END dialogflow_detect_intent_text]
Several modifications have been made here:
- For language, we set en_US as the default language
- Instead of using a list of statements, we will assume we only check one statement
- Return intent, confidence value, and fulfilment text as bot’s response
We will have the directory structure appear as follows:
. ├── MANIFEST.in ├── Makefile ├── Procfile ├── README.md ├── app.json ├── qiscus_dialogflow │ ├── __init__.py │ ├── default_settings.py │ ├── dialogflow_response.py │ ├── static │ │ └── styles.css │ ├── templates │ │ └── index.html │ └── views.py ├── requirements.txt ├── run.py ├── settings.cfg ├── setup.py ├── tests │ └── test_dialogflow.py
After that, let’s use it in view.py
. Let’s modify the current view.py
file into something like this below.
import os import requests from flask import render_template, request from qiscus_dialogflow import app, dialogflow_response DEBUG = os.environ.get("DEBUG") APP_ID = os.environ.get("APP_ID") SECRET_KEY = os.environ.get("SECRET_KEY") BOT_EMAIL = os.environ.get("BOT_EMAIL") BOT_NAME = os.environ.get("BOT_NAME") QISMO_URL = "https://qismo.qiscus.com" HEADERS = {"QISCUS_SDK_SECRET": SECRET_KEY} @app.route('/webhook/', methods=['GET', 'POST']) def webhook(): if request.method == 'POST': # get message from Qiscus Multichannel payload = request.get_json().get('payload') room_id = payload.get("room").get("id") message = payload.get("message").get("text") # get dialogflow response intent, confidence_level, fulfilment = dialogflow_response\ .detect_intent_texts({{agent_name}}, "1", message) # post url url = "{}/{}/bot/api/v2/rest/post_comment".format(QISMO_URL, APP_ID) post_type = "text" data = { "sender_email": BOT_EMAIL, "room_id": room_id, "message": fulfilment, "type": post_type, "payload": {} } req = requests.post(url, headers=HEADERS, params=data) print(req.status_code) if req.status_code == 200: return "OK", 200 else: return "Failed", req.status_code else: return "Qiscus Dialogflow webhook", 200 @app.route('/', methods=['GET', 'POST']) def index(): if request.method == 'POST': return "POST method is not supported here", 404 else: return render_template('index.html', app_id=APP_ID)
If you notice in the code above, we are no longer using the apiai
package, and we also removed the init_user()
function. Instead, we are using:
# get dialogflow response intent, confidence_level, fulfilment = dialogflow_response.detect_intent_texts({{agent_name}}, "1", message)
with the specific agent_name to get Dialogflow agent’s response.
Before we run the codes, let’s add a service account key as the environment variable for GOOGLE_APPLICATION_CREDENTIALS to service account key JSON. To do so, you could do it like in the terminal:
$ export GOOGLE_APPLICATION_CREDENTIALS="path/to/your/service_account_key.json"
Then run the codes:
$ make run FLASK_APP=qiscus_dialogflow DIALOGFLOW_SETTINGS=../settings.cfg venv/bin/flask run * Serving Flask app "qiscus_dialogflow" * Environment: production WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Debug mode: off * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
And to make it globally accessable, we are going to utilise ngrok:
$ ngrok http 5000 ngrok by @inconshreveable (Ctrl+C to quit) Session Status online Session Expires 7 hours, 59 minutes Version 2.3.29 Region United States (us) Web Interface http://127.0.0.1:4040 Forwarding http://a1fde2ba.ngrok.io -> http://localhost:5000 Forwarding https://a1fde2ba.ngrok.io -> http://localhost:5000 Connections ttl opn rt1 rt5 p50 p90 2 0 0.02 0.01 0.05 0.10
Please note, this method will only work in a local environment. To set it up when you deploy it in your server, such as Heroku or others, please refer to the articles below:
- https://simpleit.rocks/apis/google-cloud/using-google-cloud-with-heroku/
- https://medium.com/@tzahi/how-to-setup-dialogflow-v2-authentication-programmatically-with-node-js-b37fa4815d89
Setting up Qiscus Multichannel
Qiscus Multichannel is an additional product from Qiscus SDK. it is running on top of Qiscus SDK itself. It provides several channels as means to obtain conversations from users and respond to them from one dashboard. One of the channels that we can use is the Qiscus Widget. If you have seen this widget in the previous article before, we are going to use it again here.
In this section, we are going to setup Qiscus Multichannel to connect to the Dialogflow agent. We are going to also use the widget to interact with our agent. If you haven’t had any Qiscus Multichannel account yet, please go to https://multichannel.qiscus.com and register to get one. We give every user a two-week free trial to get familiar with our product.
Now let’s go to the Integration page and select the Bot Integration tab:

In the page above, we have Agent ID, App ID, Qiscus Secret Key, and Qiscus Webhook Bot URL. We save them in the env variables as we are going to use these credentials to post to Qiscus Multichannel as Bot’s responses as written in the view.py file above.
Next, let’s grab the generated URL from ngrok and put it on the Bot Webhook URL. In our case, the URL is https://a1fde2ba.ngrok.io/. Since we use /webhook as our webhook endpoint, the bot webhook URL is https://a1fde2ba.ngrok.io/
webhook/
. Click “Connect” to connect it.
Qiscus Widget
We have set up our bot webhook for Dialogflow agent and we have also connected it to Qiscus Multichannel. The last thing to do is to use Qiscus Widget to get messages from users. Still in the Integration page, click Qiscus Widget tab and click the <> button to get a snippet code of the widget to be used in the client side. Copy it:


Now, let’s go back to the codes, and open up index.html in the templates directory and paste the code there:
<html> <head> <title>Qiscus Multichannel Widget</title> </head> <body> <script> document.addEventListener('DOMContentLoaded', function() { var s,t; s = document.createElement('script'); s.type = 'text/javascript'; s.src = 'https://s3-ap-southeast-1.amazonaws.com/qiscus-sdk/public/qismo/qismo-v2.js'; s.async = true; s.onload = s.onreadystatechange = function() { new Qismo({{ app_id | tojson | safe }}); } t = document.getElementsByTagName('script')[0]; t.parentNode.insertBefore(s, t); }); </script> </body> </html>
As soon as you have finished it, open up the ngrok generated URL in the browser, such as in the image below, and start a chat:

In summary, to be able to use Dialogflow in one of Qiscus’ products, we need to have an intermediate webhook service to connect both services together. This intermediate service will act as a webhook which connects messages from Qiscus and pass it to the Dialogflow agent and obtain the response back to pass it back to Qiscus. In our example, we used Python to build this webhook service, but it’s not limited to this. As Dialogflow is using a service account for authentication, we can utilise any libraries that will handle it. You can read more here.
This code repository is located here.
Comments