Create your Slack bot with Conversation API & Node-RED

At IBM Watson, we’re always happy to continuously improve ourselves and bring new features to our users. As such, we released recently our Conversation API out of experimental use. If you’re not aware of it, Conversation allows you to identify intents and entities from a text.

You can integrate it in many use cases but the most used one is obviously messaging bot and it’s everywhere:

So why has this usage became so trendy? Many hypotheses are possible:

  • Users spend most of their time only on few applications (chat-based, games)
  • They don’t want to install an app just to get their ticket or contact support
  • It’s more natural for them to write to companies in the same way they write to their friends in their favorite applications

I recommend that you read this article where Gaurav Sharma compiled a lot of information about bot usage:

After all this interesting data, what about creating your own bot for Slack using Conversation API and Node-RED?

If you don’t have a Node-RED app deployed, read my previous tutorial:

First, let’s be sure you have the Watson Conversation node (not the experimental one) in your Node-RED app:

In case, you don’t have them, restart your application in Bluemix or locally, it will fetch the updates of Watson nodes.

There are different integrations with the Slack API, from the simplest one to the most customised. Today we will focus on the “slash command” one. It allows you to have a dedicated command that will trigger a webhook to our Node-RED app. In practice, users would write something like in this image where /watson is the command name and the rest of the message is the payload sent to your webhook.

We’re going now to create our slack command, so click on the image to create one:

Click here to create your own slack command

Don’t worry, it will be available to your team by default. You can open it for other teams by following Slack documentation. Choose your command name and add it to your team:

You’ll get an example of a payload sent to your server. Remember to verify the token bundled in the payload is the same as was written on that page to be sure Slack sent you the message and not someone else. You can regenerate it on Slack website if your token is compromised.

Put the URL to your Bluemix Node-RED app URL with /watson-slack in the end. Don’t forget to set the URL on https and save the settings.

Now time to grab our Conversation credentials. If you don’t already have an instance of Watson Conversation API, click on this image:

Once the instance has been created, you should have a “launch tool” button on the manage page where you have been redirected. Log in with your Bluemix credentials and create your workspace (you can name it as you want). A workspace will group all intents, entities, and dialog flows related to each other.

For this tutorial, we will focus on intents, which represents possible actions asked by the user. Let’s create two intents named departure_time and arrival_time, which represent actions of asking departure and arrival times of a flight:

We ask you to write at least 5 sentences to get acceptable identification by our artificial intelligence. Of course, more sentences and diverse words will provide you with better accuracy. You can copy the sentences that I wrote on the screenshot.

After creating these intents, you can click on the top right conversation icon. You have to wait for the loading message to be clear to start using your freshly trained instance.

The console will give you the most accurate intent for each message

The console will give you the most relevant intent for each message. If you think the current result doesn’t suit your need, add sentences to retrain the instance to be more accurate.

Now time to create a flow in Node-RED. Drag an HTTP input, a debug, a switch and two HTTP response nodes:

  • HTTP input: request handler, which is the webhook needed for Slack
  • Debug: plugged at the end of the HTTP input node to see what Slack is sending us
  • Switch: verify if the token provided is the same as the one given by Slack and trigger one action or the other
  • HTTP response: answers Slack with an empty answer (no impact but needed)

After deploying, trigger a webhook call by sending a message to your Slack bot as shown earlier:

/watson what’s the weather in Paris
You can write any sentence, it doesn’t have impact of the rest of tutorial

In your Node-RED app debug sidebar, you should see a similar payload. Now we will need an answer from Watson Conversation if the token provided is right otherwise we skip this step.

{
“token”: “SECRET”,
“team_id”: “T12345”,
“team_domain”: “myteamslack”,
“channel_id”: “C1234567”,
“channel_name”: “test-conversation”,
“user_id”: “U12345”,
“user_name”: “yrezgui”,
“command”: “/watson”,
“text”: “hello again”,
“response_url”: “https://hooks.slack.com/commands/T12345/12345/demo"
}

You can see in this payload, we have a response_url attribute. It’s used in the case your processing of the message is taking more than 3 seconds, you would have to send an HTTP POST request to this URL, which is not for Conversation API. You can read more about it here.

We have to drag a Conversation and two Function nodes. We will pick the text message from the payload, analyze it with Conversation API and prepare an answer based on the result of our instance. Your flow should look like this one now:

For the first Function node, copy the code to pick the text:

msg.payload = msg.payload.text;
return msg;

For the Conversation node, paste your credentials from the Bluemix dashboard and the workspace id from the Conversation tool:

And finally for the last Function node, let’s have a look first to a Conversation API answer (shorten JSON than actual one):

{
“input”: {
“text”: “Hey Watson, departure time please”
},
“intents”: [
{
“intent”: “departure_time”,
“confidence”: 0.9781078054955197
},
{
“intent”: “arrival_time”,
“confidence”: 0.02189219450448029
}
]
}

We can see from the text sent to the API, it recognized departure_time as the first and most relevant intent found in the message. In a production app, this is where you would trigger your internal business logic as gathering client information, get current flight information, etc. In this case, we’re just answering static content to make it simple. So let’s write the code to answer our user:

We save all these nodes by deploying them and write to your bot in Slack:

Amazing, you did it!

Now you can train more your Conversation instance or customise your Node-RED flow by integrating it with other APIs. Don’t hesitate to add some Debug nodes to help you figure out the input/output of each other nodes.

If you have any question related to Watson APIs, feel free to reach out to me on twitter: @yrezgui