Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / Node.js

Integrate Your Slack Application with IBM Watson/Bluemix Assistant Services Quickly and Easily

5.00/5 (4 votes)
25 Feb 2019CPOL7 min read 8.3K   45  
How to quickly and easily create an automated chatbot or instant messenger (IM) application
In this short article, we will discuss about the aspects of Slack API and IBM Watson/Bluemix Assistant cloud-based solutions integration, to quickly and easily create an automated chatbot or instant messenger (IM) application.

Background

IBM Watson/Bluemix Assistant Services

We basically start the entire Slack integration process at creating a Slack account and setting up a specific chatbot application. There's lots of documentation and guidelines describing the process for creating a Slack account and deploying various Slack applications, such as:

Another aspect we're about to discuss in this section is signing up for IBM Cloud and creating Watson/Bluemix Assistant service, as well as configuring it to satisfy our needs.

Creating an IBM Cloud Account

To create an IBM Cloud account, we must pass the regular registration procedure by visiting https://cloud.ibm.com/registration with your local web-browser and entering our credentials to complete the registration:

Image 1

After you've completed the registration, go to your IBM Cloud Dashboard and toggle Create Resource button. In the resources pane, toggle the AI/Watson Assistant as it's shown below:

Image 2

After that, choose the proper service name, location, resource group and plan, and then toggle Create button at the right-bottom of page to deploy the resource:

Image 3

After that, you will be redirected to the newly created service page.

Launching the IBM/Bluemix Assistant Services

To continue the deployment, click on Launch Tool button in the assistant services page. Also don't forget to download the ibm-credentials.env file and copy it into the project's directory.

Image 4

After you'll be redirected to another page, in which you must toggle Create a Skill button at the bottom of page:

Image 5

Creating Dialog Skills

To create specific skills, make sure that you enter skill name and description in the following page, you'll be redirected to:

Image 6

After toggling Create button, you'll be redirected to the web-page in which you will be able to create specific intents for the skill being deployed:

Image 7

Adding Intents

To create specific intents, you must following the intents adding procedure in the following web-page:

Image 8

Building Dialog

Finally, before creating the specific assistant service, we must create a dialog and add the intents to the dialog's nodes as follows:

Image 9

After we've created a specific dialog, let's now add a new node and associate it with the intent previously created:

Image 10

Creating Assistant Service

Finally, we must create the specific assistant service by following the procedure shown below:

Image 11

Image 12

Image 13

Using the Code

In this section, we will demonstrate how to create a Slack API web-application server, performing messages routing to the IBM Watson/Bluemix assistant services, previously discussed:

Initializing Slack And IBM Watson Assistant APIs

The first thing that we have to do to implement a specific custom web-application server is to install and initialize the either Slack and IBM Watson Assistant APIs. Here's the list of APIs and Node.js modules used by the following web-application service:

  • 'bootkit' - the Node.js module providing basic Slack API's functionality
  • 'watson-developer-cloud' - the Node.js module providing the connectivity with IBM Watson Cloud
  • 'express' and 'request' - the Node.js modules used to deploy an Express 4 app's web service

The following code below illustrates how to install and use these Node.js modules:

JavaScript
npm install express request --save
npm install botkit watson-developer-cloud --save

After we've installed the following modules, we must add the following code to the web-application's main script file chatbot.js:

JavaScript
const Botkit = require('botkit');
const express = require('express');
const request = require('request');

const AssistantV1 = require('watson-developer-cloud/assistant/v1');

The 'express' and 'request' modules are actually needed to support the web-server Express 4 functionality to the Slack API and the specific chatbot engine script.

Loading Slack and IBM Cloud Configuration

To provide Slack and IBM Watson/Bluemix Assistant client connectivity, we must specify the number of parameters, required to connect our chatbot engine service to Slack and IBM Cloud. The project introduced in this article contains three main configuration files to support this connectivity:

ibm-credentials.env

JavaScript
ASSISTANT_APIKEY=<YOUR_API_KEY>
ASSISTANT_URL=<SERVER URL>

The following file contains the two variables of either ASSISTANT_APIKEY and ASSISTANT_URL. The values of these two variables are used to specify a Watson Assistant Service API-Key identifier previously created, as well as the URL of the specific server instance which our application server will be communicating with. The values of the API_KEY and URL are generated during the specific Watson Assistant Server creation.

conversation.json

Another file conversation.json is used to store the number of Watson Assistant workspace connection parameters, including data. Workspace ID is the only parameter value we actually need to retrieve from this file. The entire file contents are shown below:

JavaScript
{

   ...

  "workspace_id": "YOUR_WORKSPACE_GUID",
  "counterexamples": [],
  "system_settings": {
    "tooling": {
      "store_generic_responses": true
    }
  },
  "learning_opt_out": false,
  "status": "Available"
}

conversation.json file is a string JSON-format file that can be downloaded at the Watson Assistant dashboard, containing the proper GUID-value of the workspace-id required.

slack.json

slack.json - the last important configuration file we're about to discuss. This file contains the data in string JSON-format on the main credentials to establish the connection to Slack API services:

JavaScript
{
  "clientId": "YOUR_APP'S_CLIENT_ID",
  "clientSecret": "CLIENT_SECRET",
  "redirectUri": "YOUR_NGROK_SERVER_URL",
  "clientSigningSecret": "SIGNED_SECRET",
  "token": "SLACK_APP'S_AUTH_TOKEN"
}

To run the chatbot web-application, we must provide proper credentials by editing these configuration files.

The chatbot web-application server loads these files at the beginning of its execution using the following code:

JavaScript
require('dotenv').config({ path: './ibm-credentials.env' });

const slack_config = JSON.parse(
    require('fs').readFileSync('slack.json').toString());

var ib_config = JSON.parse(require('fs').
    readFileSync("./conversation.json"));

Creating An Instance of Slack Chatbot

Creating an instance of Slack chatbot is the next initialization phase that must be performed prior to accomplishing the actual message handling tasks. To create an instance of the Slack chatbot and a specific controller, we must implement the following code listed below:

JavaScript
const slackController = Botkit.slackbot(slack_config);
const slackBot = slackController.spawn(slack_config);

The first line in this code implements the Slack chatbot controller instantiation using Botkit object and parameters previously loaded from specific configuration files, passed as an argument of slackbot(slack_config) method. During the second line execution, the specific slackBot object is created by invoking the spawn(slack_config) method of the controller being created.

Instantiating the IBM Watson/Bluemix Assistant

Another task that we must accomplish during the initialization phase is the instantiating of the Watson Assistant object as follows:

JavaScript
const assistant = new AssistantV1({
    version: '2019-02-25',
    iam_apikey: process.env.ASSISTANT_APIKEY,
    url: process.env.ASSISTANT_URL
});

In this case, we create an object of the assistant using the list of parameters values (e.g., credentials and version), loaded from specific configuration file ibm_credentials.env.

Launching the Slackbot Created

To launch the Slackbot, we've already instantiated during the initialization phase, we must execute the following code listed below:

JavaScript
slackBot.startRTM((err, bot, payload) => {
    if (err) {
        throw new Error('Could not connect to Slack');
    }
    slackController.log('Slack connection established.');
});

In this case, we use the slackBot object and invoke startRTM(...) method to launch our Slackbot, providing the connectivity to the Slack Hub. The following method accepts a callback or lambda function as a single argument. In this callback function, we perform the basic exception handling and connection status tasks.

Creating a Listener to Handle Incomming Messages

Finally, what we have to do is to implement a message handler and assign it to the controller being previously created. To do this, we have to use slackController object and invoke the specific slackController.hears(...) message to perform the incoming messages handling. A callback or lambda function is one of the actual arguments of this method. This callback function is invoked every time when new messages arrive from the Slack Hub to the controller via the specific Ngrok local-side connection:

JavaScript
slackController.hears(['.*'], ['direct_message', 'direct_mention'], (bot, message) => {
    bot.startConversation(message, (err, convo) => {
        console.log("question: " + message["text"]);
        assistant.message({
            workspace_id: ib_config.workspace_id,
            input: { 'text': message["text"] }
        }, function (err, response) {
            if (err)
                console.log('error:', err);
            else
                response["output"]["text"].forEach(
                    function (resp) {
                        console.log("response: " + resp);
                        convo.say(resp); });
        });
    });
});

The following callback function receives two parameters as its arguments. The first parameter (i.e., "bot") is an instance of a Slackbot object. The second parameter is the message that was received from Slack. By using bot object, we invoke the startConversation(...) method, passing the message parameter value as the first argument. Also, we define another callback or lambda function, fired when a new message has arrived. This another callback has two arguments such as either an err variable or convo object to provide the chat functionality. Inside this callback, we're implementing a code that uses the previously created assistant object to route incoming messages to IBM Watson Assistant services. Specifically, we're calling the message(...) method that accepts a number of parameters such as a workspace-id and input message, as well as a callback or lambda function to handle the responses from the assistant services. The message(...) method dispatches an incoming message to the assistant services and handles the response by invoking the specific callback method. After a message has been processed by the assistant, we receive the response as an array stored in the response["output"]["text"] variable. After that, we're performing a simple for-each loop to send each response message back to the Slackbot, by invoking convo.say(resp) method.

In general, the following code does nothing, but performing routing of incoming messages from Slack chatbot application console to the specific assistant services, handling the responsing and send the response messages back to Slack chatbot application.

History

  • 25th February, 2019 - Final version of article was published

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)