Qiscus Chat SDK by Qiscus

Create a Simple Chat Application Using Qiscus SDK and Integrate a Simple Echo Bot into it

This article is also published at https://blog.qiscus.com/create-simple-echo-chatbot-using-qiscus-sdk/

In this article, we would like to leverage a process of integrating chatbot into a chat app that is created using Qiscus SDK. We are going to create a simple echo bot and simple chat app to do so. Let's get to the point.

First thing first, you need to sign in (or sign up) into Qiscus SDK dashboard to create a new app and get its app id and its secret key. These two things will be needed later in order to post back any responses of message received by our (webhook) chatbot into our chat app.

1. Setup A webhook

As we already got the app id and the secret key, the next thing we should prepare is a webhook. This webhook may or may not be separated from our main chat application. To make it simple, we will create a simple webhook that is reside in the main application server. In this example we will use Python Flask as our webhook and main server, of course you are free to use any other languages though. To make it even simpler, we will use cookiecutter-flask-minimal as our starter kit. 


For more information about cookiecutter and how to use it, please refer to this docs.
$ # create a minimal flask project using cookiecutter, follow the instruction
$ cookiecutter https://github.com/candidtim/cookiecutter-flask-minimal

It will generate a starter kit to work with minimal Flask application.
Let's say you finished creating a flask project named "simplebot", you may get this kind of directory structure.
.
├── MANIFEST.in
├── Makefile
├── README.md
├── settings.cfg
├── setup.py
├── simplebot
│ ├── __init__.py
│ ├── default_settings.py
│ ├── static
│ │ └── styles.css
│ ├── templates
│ │ └── index.html
│ └── views.py
└── tests
└── test_simplebot.py

4 directories, 11 files

Open it on your beloved text editor. I useSublime Textfor this.
$ cd simplebot
$ sublime .

Now, let's modify simplebot/views.py file, just replace the content with this snippet.

from flask import render_template, request
from simplebot import app

@app.route('/')
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")

return "OK", 200
else:
return render_template('index.html')

The snippet says if the requested method received by this webhook is POST method, we will need to get the payload and extract room_id and message from that payload. These two values will be used when we send back the message to the QiscusSDK.

As we will also post any response back to the Qiscus SDK, we need the 'requests' package to simplify the process. So open up the setup.py and add requests into install_requires argument as an addition list value of package that are need to be installed.

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=[
'flask',
'requests'
],
)


Now, let's start the server.

$ make run

Ok, open up your web browser, and hit this address http://localhost:5000/. If everything is ok, we should see this in the browser.

First appearace
First appearance

Next, let's modify our simplebot/views.py file again to be able to send back the message we received.

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"
qiscus_sdk_url = "https://{}.qiscus.com".format(app_id)


@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")

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)

return "OK", 200 if req.status_code == 200 else "Failed", req.status_code
else:
return render_template('index.html', appId=app_id, senderEmail=sender_email)

Let's explain a modification we've made in the simplebot/views.py file.

  • First we added a requests package as we are going to use it to post back received message to the QiscusSDK.
  • We then specify our required params that were obtain from Qiscus SDK dashboard earlier, e.g: app_id and secret_key
  • If you note the qiscus_sdk_url, this url will be used as our app base url to post our request to the Qiscus SDK, please refer to this part of qiscus sdk docs for more information.
  • As Qiscus SDK required to authenticate who is sending message to our app base url, we add the secret_key as additional header in the request.
  • Last but not the least, we need to specify parameters that are needed to post a message back to the Qiscus SDK. We put it in the data variable.
  • Finally we post the message back.

So far, we have created our webhook to received a message from our chat application and send it back. We cannot test it as we don't have our chat application yet. So the next step is to create our simple chat app.

But before that, let's add a first user as the SimpleBot. Add this code to the simplebot/views.py file.

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)


def init_user():
url = "{}/api/v2/rest/user_profile?user_email={}".format(qiscus_sdk_url, sender_email)
headers = {"QISCUS_SDK_SECRET": secret_key}
req = requests.get(url, headers=headers)

if req.status_code == 401:
reg_url = "{}/api/v2/rest/login_or_register".format(qiscus_sdk_url)
data = {
"email": sender_email,
"password": "simplebot",
"username": bot_name
}
requests.post(reg_url, headers=headers, params=data)


@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")

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)

return "OK", 200 if req.status_code == 200 else "Failed", req.status_code
else:
return render_template('index.html', appId=app_id, senderEmail=sender_email)

Then in the simplebot/__init__.py file add this in the end

views.init_user()

Please restart your server in order this changes to take effect.

2. Creating a simple chat app

As we mentioned earlier that we are not going to separate our webhook from our chat app server, let's use Flask templating system to create our chat app.

First, let's open simplebot/templates/index.html file and replace its content with this code. This code is obtained from example of web version of Qiscus SDK with a bit of modification.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Simple Qiscus SDK Bot</title>
<link rel=stylesheet href=https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css>
<link rel="stylesheet" type="text/css" href="https://res.cloudinary.com/qiscus/raw/upload/DbSLsqjXn5/qiscus-sdk.2.5.8.css">
</head>
<body>
<div>
<h3>Simple Qiscus SDK Bot</h3>
</div>
<div id="qiscus-widget"></div>
<!-- add this CDN for emojione if you intend to support emoji -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/emojione/2.2.7/lib/js/emojione.min.js"></script>
<script src="https://res.cloudinary.com/qiscus/raw/upload/qDoXwv1doA/qiscus-sdk.2.5.8.js"></script>
<script>
// let's setup options for our widget
QiscusSDK.core.init({
AppId: {{ appId | tojson | safe }},
options: {
// When we're success login into qiscus SDK we'll have a 1-on-1 chat to guest2@qiscus.com
// You can change this to any user you have on your AppId, e.g: contact@your_company.com, etc
loginSuccessCallback(data) { QiscusSDK.core.UI.chatTarget({{ senderEmail | tojson | safe }}) },
// function below will be called when there's new message
newMessagesCallback(data) { console.log("new message : ", data) }
}
});
// login to qiscus
QiscusSDK.core.setUser('guest3@qiscus.com', 'password', 'Qiscus Demo');
// render the widget
QiscusSDK.render();
</script>
</body>
</html>


If everything is alright, we will see a small green widget with a “chat” text on it at the lower right of our browser.

Chat widget appears on the right bottom of the web

If you click that widget it will show a simple greenish chat interface with an adequate space to enter any texts. It means, our simple chat application is integrated successfully.

Go ahead and try to enter some texts if you will. You may notice, there were not any responses yet, that's because QiscusSDK doesn't know where to redirect the message as we haven't add our webhook URL address into QiscusSDK. To address it, we simply need to do so.

Since we've been developing our bot locally, QiscusSDK won't recognise our webhook even though we are trying to add our local webhook address to the QiscusSDK. So to help making our webhook open to the internet, we are going to use ngrok. It will generate temporary domain subdomain address that enable anyone to access our webhook through internet.

You need to have ngrok installed first, please refer to this

Let's run the ngrok, it will list all available temporary address that accessible to outside. In our case it is https://0af4a78e.ngrok.io.

$ ngrok http 5000
$ ngrok by @inconshreveable (Ctrl+C to quit)

Tunnel Status online
Update update available (version 2.2.8, Ctrl-U to update)
Version 2.0.25/2.1.18
Region United States (us)
Web Interface http://127.0.0.1:4040
Forwarding http://0af4a78e.ngrok.io -> localhost:5000
Forwarding https://0af4a78e.ngrok.io -> localhost:5000

Connections ttl opn rt1 rt5 p50 p90
5 0 0.00 0.00 0.18 1.22

HTTP Requests
-------------

GET /favicon.ico 404 NOT FOUND
GET / 200 OK


Now let's copy this address and paste it into the QiscusSDK webhook dashboard.

Qiscus Chat SDK Dashboard: Adding bot webhook

If we don't face anything wrong, we are now able to try again to have a chat with the bot. Go ahead and try, it will response with the same text you entered.

Bot responses with the same text entered

Above example is just a simple example of echo bot using only text response type. Beside the plain texts, the bot is also able to response with a more advance UI such as card or button. For more information regarding this, please have a look at QiscusSDk Docs.

You can find this bot code at https://bitbucket.org/qiscus/echo-bot-qiscus-sdk.

Cheers,

This article was updated on 19 October 2017

Comments

Follow @nurulishlah