From 4521f8fdcd59a6a5a8589188e4a1737c32e79b80 Mon Sep 17 00:00:00 2001 From: Matt Buck Date: Fri, 18 Mar 2016 17:22:19 -0500 Subject: [PATCH 1/9] Update app.json for Heroku --- app.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app.json b/app.json index b83c517..bf541da 100644 --- a/app.json +++ b/app.json @@ -1,9 +1,9 @@ { - "name": "API.AI with Slack integration", - "description": "Api.ai Slack integration allows you to create Slack bots with natural language understanding based on Api.ai technology.", - "repository": "https://github.com/api-ai/api-ai-slack-bot", - "logo": "https://console.api.ai/api-client/assets/img/logo-black.png", - "keywords": ["api.ai", "slack", "natural language"], + "name": "Burner connection to Api.ai via Slack", + "description": "This is a slackbot that enables connecting Burner telephone numbers to the Api.ai platform. Incoming SMS messages to your Burner line can be answered by an Api.ai intelligent agent via Burner's Slack connection.", + "repository": "https://github.com/voxable-labs/burner-sms-api-ai-slackbot", + "logo": "https://avatars1.githubusercontent.com/u/15236552?v=3&s=200", + "keywords": ["api.ai", "slack", "natural language", "slackbot", "burner", "voxable"], "env": { "accesstoken": { "description": "Client access token for Api.ai", From 1cb9d989301377b736457fa78b4a551449e623f0 Mon Sep 17 00:00:00 2001 From: Matt Buck Date: Fri, 18 Mar 2016 17:43:27 -0500 Subject: [PATCH 2/9] Enable responding to Burner's slackbot We parse the original SMS message and return number out of Burner's slackbot message, pass the original message to Api.ai, then append the return number to the speech response from Api.ai so that it's returned to the correct user. --- src/index.js | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/index.js b/src/index.js index 3083604..7200544 100644 --- a/src/index.js +++ b/src/index.js @@ -46,7 +46,7 @@ function isDefined(obj) { return obj != null; } -controller.hears(['.*'], ['direct_message', 'direct_mention', 'mention', 'ambient'], function (bot, message) { +controller.hears(['.*'], ['bot_message'], function (bot, message) { try { if (message.type == 'message') { @@ -61,11 +61,23 @@ controller.hears(['.*'], ['direct_message', 'direct_mention', 'mention', 'ambien var requestText = decoder.decode(message.text); requestText = requestText.replace("’", "'"); + var burnerMesageRegex = /Inbound message from \+(\d*):\s(.*)/; + var returnNumber = ''; + var smsMessage; + + // Parse the SMS message and return number out of Burner's slackbot message + if ((smsMessage = burnerMesageRegex.exec(requestText)) !== null) { + returnNumber = '@' + smsMessage[1]; + requestText = smsMessage[2]; + + console.log('returnNumber', returnNumber); + console.log('requestText', requestText); + } + var channel = message.channel; var messageType = message.event; var botId = "<@" + bot.identity.id + ">"; - console.log(requestText); console.log(messageType); if (requestText.indexOf(botId) > -1) { @@ -85,7 +97,8 @@ controller.hears(['.*'], ['direct_message', 'direct_mention', 'mention', 'ambien console.log(response); if (isDefined(response.result)) { - var responseText = response.result.fulfillment.speech; + // Preface the response with the appropriate return SMS number. + var responseText = returnNumber + ' ' + response.result.fulfillment.speech; var action = response.result.action; if (isDefined(responseText)) { From 2c6888f27ded6c30cbb9d7f34d97a1a9bf762e57 Mon Sep 17 00:00:00 2001 From: Matt Buck Date: Fri, 18 Mar 2016 17:49:26 -0500 Subject: [PATCH 3/9] Shorten the app.son name and description --- app.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app.json b/app.json index bf541da..d35be7e 100644 --- a/app.json +++ b/app.json @@ -1,6 +1,6 @@ { - "name": "Burner connection to Api.ai via Slack", - "description": "This is a slackbot that enables connecting Burner telephone numbers to the Api.ai platform. Incoming SMS messages to your Burner line can be answered by an Api.ai intelligent agent via Burner's Slack connection.", + "name": "Burner to Api.ai via Slack", + "description": "A slackbot that enables connecting Burner lines to the Api.ai platform via Burner's Slack connection.", "repository": "https://github.com/voxable-labs/burner-sms-api-ai-slackbot", "logo": "https://avatars1.githubusercontent.com/u/15236552?v=3&s=200", "keywords": ["api.ai", "slack", "natural language", "slackbot", "burner", "voxable"], From 71d146d86b0015c75672940a5641e0396a56ea69 Mon Sep 17 00:00:00 2001 From: Matt Buck Date: Fri, 18 Mar 2016 17:50:41 -0500 Subject: [PATCH 4/9] Change the app.json name so that it makes sense on the deploy page --- app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app.json b/app.json index d35be7e..f843bba 100644 --- a/app.json +++ b/app.json @@ -1,5 +1,5 @@ { - "name": "Burner to Api.ai via Slack", + "name": "Burner to Api.ai slackbot", "description": "A slackbot that enables connecting Burner lines to the Api.ai platform via Burner's Slack connection.", "repository": "https://github.com/voxable-labs/burner-sms-api-ai-slackbot", "logo": "https://avatars1.githubusercontent.com/u/15236552?v=3&s=200", From 695ab4dab65b25cbe18d51446b4fe9e70c776a3b Mon Sep 17 00:00:00 2001 From: Matt Buck Date: Fri, 18 Mar 2016 18:43:26 -0500 Subject: [PATCH 5/9] Change the contact info in the Dockerfile --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index e03a3b5..d2a95e2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ FROM node:5.3.0 -MAINTAINER xVir +MAINTAINER Matt Buck RUN mkdir -p /usr/app/src WORKDIR /usr/app From 40cc3960157a13de4ef73867040bcf034a8073a0 Mon Sep 17 00:00:00 2001 From: Matt Buck Date: Fri, 18 Mar 2016 18:45:20 -0500 Subject: [PATCH 6/9] Skip Burner confirmation messages Burner will always respond with "Sent text to NUMBER" after sending an SMS. The responder bot should ignore these messages, otherwise the Api.ai agent gets stuck in a "slot filling" conversation attempting to send a text message itself. --- src/index.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/index.js b/src/index.js index 7200544..ebaefb0 100644 --- a/src/index.js +++ b/src/index.js @@ -56,6 +56,10 @@ controller.hears(['.*'], ['bot_message'], function (bot, message) { else if (message.text.indexOf("<@U") == 0 && message.text.indexOf(bot.identity.id) == -1) { // skip other users direct mentions } + else if (message.text.includes("Sent text to")) { + // skip sent text confirmations from Burner + console.log('Skipping Burner response.'); + } else { var requestText = decoder.decode(message.text); From 59c338824abf5cb84bd197151b83db6e7351e6db Mon Sep 17 00:00:00 2001 From: Matt Buck Date: Fri, 18 Mar 2016 20:08:50 -0500 Subject: [PATCH 7/9] Update the README --- README.md | 133 +++++++++--------------------------------------------- 1 file changed, 22 insertions(+), 111 deletions(-) diff --git a/README.md b/README.md index 6da1c49..995e047 100644 --- a/README.md +++ b/README.md @@ -1,125 +1,36 @@ -# Api.ai Slack Integration +# Intelligent SMS bot via Burner, Slack, and Api.ai ## Overview -Api.ai Slack integration allows you to create Slack bots with natural language understanding based on Api.ai technology. +By making use of [Burner's Slack connection](http://www.burnerapp.com/slack/) and [Api.ai's Slack integration](https://docs.api.ai/docs/slack-integration), you can easily create an intelligent SMS bot. -[![Deploy to Heroku](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy) -To launch a bot, you’ll need the Linux OS. To launch it in other operating systems, use [Docker Toolbox](https://www.docker.com/products/docker-toolbox). +![burner api-ai slackbot mp4](https://cloud.githubusercontent.com/assets/2220/13895572/a82a92ba-ed42-11e5-8960-8dc91471d64a.gif) -Api.ai documentation: +What's happening above: -- [How to create an Api.ai agent](https://docs.api.ai/docs/get-started#step-1-create-agent) -- [How to obtain Api.ai authentication keys](https://docs.api.ai/docs/authentication) +* A user sends a text to our Burner line. +* The Burner Slack connection posts the SMS in our Slack channel. +* Our slackbot receives the SMS, parses out the sending phone number and message, and passes these on to our Api.ai agent. +* Our Api.ai agent sends back a response, which our slackbot duly posts in the Slack channel, prepended with the number that sent the SMS. +* The Burner Slack connection sends an SMS back to the user. -You’ll need 3 keys: +## Getting Started -- Client access token for Api.ai -- Subscription key for Api.ai -- Slack bot API token +1. [Create an Api.ai agent.](https://docs.api.ai/docs/get-started#step-1-create-agent) +2. [Activate the general knowledge domain for your agent.](https://docs.api.ai/docs/domains) +3. [Obtain your Api.ai authentication keys.](https://docs.api.ai/docs/authentication) +4. [Create a new slackbot.](https://slack.com/apps/A0F7YS25R-bots) +5. [Obtain your Slackbot's API token.](https:/lslack.com/apps/manage/A0F7YS25R-bots) +6. [Enable the Slack connection for your Burner line.](http://www.burnerapp.com/slack/) +7. Click the handy "Deploy to Heroku" button below to deploy the bot to Heroku. -To obtain a Slack bot API token, create a new bot integration here: https://slack.com/apps/A0F7YS25R-bots. + [![Deploy to Heroku](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy) -## Bot Launch +8. Enter the credentials you gathered above in the "New App" screen and click the "Create App" button. -To launch the bot, use one of the following commands: +You're all set! Try texting a question to your Burner line, and you should get a response. -**For background launch mode (-d parameter):** +## Credits -```sh -docker run -d --name slack_bot \ - -e accesstoken="api.ai access key" \ - -e subscriptionkey="api.ai subscription key" \ - -e slackkey="slack bot key" \ - api-ai/api-ai-slack-bot -``` - -**For interactive launch mode (-it parameter):** - -```sh -docker run -it --name slack_bot \ - -e accesstoken="Api.ai client access key" \ - -e subscriptionkey="Api.ai subscription key" \ - -e slackkey="Slack bot user key" \ - api-ai/api-ai-slack-bot -``` - -To stop the bot from running in the interactive mode, press CTRL+C. - -In the background mode, you can control the bot’s state via simple commands: - - -- `docker start slack_bot` -- `docker stop slack_bot`, - -where `slack_bot` is the container name from the `run` command. - -## Custom Bot Launch - -If you want to customize your bot behavior, follow the steps below. - -1. Clone the repository https://github.com/xVir/api-ai-slack-bot - -2. Change the code to `index.js` - -3. In the Docker, use the `run` command specifying the full path to the directory containing the `index.js` file: - -```sh -docker run -d --name slack_bot \ - -e accesstoken="Api.ai client token" \ - -e subscriptionkey="Api.ai Subscription key" \ - -e slackkey="Slack bot user key" \ - -v /full/path/to/your/src:/usr/app/src \ - api-ai/api-ai-slack-bot -``` - -## Code Notes - -Bot implementation is based on the Slack Botkit: https://github.com/howdyai/botkit. - -Message processing is done by the following code: - -```javascript -controller.hears(['.*'],['direct_message','direct_mention','mention', 'ambient'], function(bot,message) { - console.log(message.text); - if (message.type == "message") { - if (message.user == bot.identity.id) { - // message from bot can be skipped - } - else { - var requestText = message.text; - var channel = message.channel; - if (!(channel in sessionIds)) { - sessionIds[channel] = uuid.v1(); - } - var request = apiAiService.textRequest(requestText, { sessionId: sessionIds[channel] }); - request.on('response', function (response) { - console.log(response); - if (response.result) { - var responseText = response.result.fulfillment.speech; - if (responseText) { - bot.reply(message, responseText); - } - } - }); - request.on('error', function (error) { - console.log(error); - }); - request.end(); - } - } -}); -``` - -This code extracts the text from each message: - -`var requestText = message.text;` - -And sends it to Api.ai: - -`var request = apiAiService.textRequest(requestText, { sessionId: sessionIds[channel] });` - -If a non-empty response is received from Api.ai, the bot will respond with the received text: - -`bot.reply(message, responseText);` +This is a fork of [Api.ai's Slack integration](https://github.com/api-ai/api-ai-slack-bot), with [minimal modifications](https://github.com/voxable-labs/burner-sms-api-ai-slackbot/pull/1) needed to make the magic happen with Burner. \ No newline at end of file From cffb7cc571ccb67f54f9d9e4bd155df178d4a16e Mon Sep 17 00:00:00 2001 From: Matt Buck Date: Fri, 18 Mar 2016 20:09:42 -0500 Subject: [PATCH 8/9] Point the modifications link in the README at the diff --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 995e047..f6517fd 100644 --- a/README.md +++ b/README.md @@ -33,4 +33,4 @@ You're all set! Try texting a question to your Burner line, and you should get a ## Credits -This is a fork of [Api.ai's Slack integration](https://github.com/api-ai/api-ai-slack-bot), with [minimal modifications](https://github.com/voxable-labs/burner-sms-api-ai-slackbot/pull/1) needed to make the magic happen with Burner. \ No newline at end of file +This is a fork of [Api.ai's Slack integration](https://github.com/api-ai/api-ai-slack-bot), with [minimal modifications](https://github.com/voxable-labs/burner-sms-api-ai-slackbot/pull/1/files) needed to make the magic happen with Burner. \ No newline at end of file From d6e6278eeb032b8eff0b451ece318d8dd9ecac3c Mon Sep 17 00:00:00 2001 From: Matt Buck Date: Fri, 18 Mar 2016 20:11:00 -0500 Subject: [PATCH 9/9] Point the modification link in the README at the specific file --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f6517fd..24e5610 100644 --- a/README.md +++ b/README.md @@ -33,4 +33,4 @@ You're all set! Try texting a question to your Burner line, and you should get a ## Credits -This is a fork of [Api.ai's Slack integration](https://github.com/api-ai/api-ai-slack-bot), with [minimal modifications](https://github.com/voxable-labs/burner-sms-api-ai-slackbot/pull/1/files) needed to make the magic happen with Burner. \ No newline at end of file +This is a fork of [Api.ai's Slack integration](https://github.com/api-ai/api-ai-slack-bot), with [minimal modifications](https://github.com/voxable-labs/burner-sms-api-ai-slackbot/pull/1/files#diff-1fdf421c05c1140f6d71444ea2b27638) needed to make the magic happen with Burner. \ No newline at end of file