Press enter to see results or esc to cancel.

Create a Simple Echo ChatBot Using Qiscus Chat SDK

In this article, we would like to leverage a process of integrating chatbot into a chat app that is created using our chat engine Qiscus Chat  SDK. We are going to create a simple echo bot and simple chat sdk 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 use Sublime Text for 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. For more detail about payload that being received from Qiscus Chat SDK Webhook, you can check here.

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.


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

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 Chat SDK. We put it in the data variable.
  • Finally we post back the message.
  • Please note that this SimpleBot will receive messages from all users, hence it will try to post back every message it received, however since we restrict the sender only can post to room that it belongs to, it will only receive to room that the chatbot become participant. We do not do any checking condition in this example for simplification purpose.

So far, we have created our webhook to received a message from our chat sdk application and send it back as chatbot. 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.

Also read: “Protocol for Modularity in Swift

2. Creating a simple chat sdk 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 sdk 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 [email protected]
          // You can change this to any user you have on your AppId, e.g: [email protected]_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('[email protected]', '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.


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 sdk 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 chatbot 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. Please put the webhook only On Client Post Comment, otherwise you will also receive echo from chatbot’s own messages.


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

Above example is just a simple example of chatbot using only text response type. Beside the plain texts, the chatbot is also able to response with a more advance UI such as card or button. You can even custom the chat UI. For more information regarding this, please have a look at QiscusSDK API Docs.

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

Comments

Leave a Comment

Show Buttons
Hide Buttons