Skip to content

Latest commit

 

History

History
255 lines (186 loc) · 10.1 KB

readme-ciscospark.md

File metadata and controls

255 lines (186 loc) · 10.1 KB

Botkit and Cisco Spark

Botkit is designed to ease the process of designing and running useful, creative bots that live inside Cisco Spark.

Botkit features a comprehensive set of tools to deal with Cisco's Spark platform, and allows developers to build interactive bots and applications that send and receive messages just like real humans.

This document covers the Cisco Spark-specific implementation details only. Start here if you want to learn about to develop with Botkit.

Table of Contents

Getting Started

  1. Install Botkit more info here

  2. Create a bot in the Spark for Developers site. You'll receive an access token.

Copy this token, you'll need it!

  1. If you are not running your bot at a public, SSL-enabled internet address, use a tool like ngrok or localtunnel to create a secure route to your development application.
ngrok http 3000
  1. Run your bot application using the access token you received, the base url of your bot application, and a secret which is used to validate the origin of incoming webhooks:
access_token=<MY ACCESS TOKEN> public_address=<https://my_bot_url> secret=<my_secret_phrase> node spark_bot.js
  1. Your bot should now come online and respond to requests! Find it in Cisco Spark by searching for it's name.

Working with Cisco Spark

Botkit receives messages from Cisco Spark using webhooks, and sends messages using their APIs. This means that your bot application must present a web server that is publicly addressable. Everything you need to get started is already included in Botkit.

To connect your bot to Cisco Spark, get an access token here. In addition to the access token, Cisco Spark bots require a user-defined secret which is used to validate incoming webhooks, as well as a public_address which is the URL at which the bot application can be accessed via the internet.

Each time the bot application starts, Botkit will register a webhook subscription. Botkit will automatically manage your bot's webhook subscriptions, but if you plan on having multiple instances of your bot application with different URLs (such as a development instance and a production instance), use the webhook_name field with a different value for each instance.

Bots in Cisco Spark are identified by their email address, and can be added to any space in any team or organization. If your bot should only be available to users within a specific organization, use the limit_to_org or limit_to_domain options. This will configure your bot to respond only to messages from members of the specific organization, or whose email addresses match one of the specified domains.

The full code for a simple Cisco Spark bot is below:

var Botkit = require('./lib/Botkit.js');

var controller = Botkit.sparkbot({
    debug: true,
    log: true,
    public_address: process.env.public_address,
    ciscospark_access_token: process.env.access_token,
    secret: process.env.secret
});


var bot = controller.spawn({
});

controller.setupWebserver(process.env.PORT || 3000, function(err, webserver) {
    controller.createWebhookEndpoints(webserver, bot, function() {
        console.log("SPARK: Webhooks set up!");
    });
});

controller.hears('hello', 'direct_message,direct_mention', function(bot, message) {
    bot.reply(message, 'Hi');
});

controller.on('direct_mention', function(bot, message) {
    bot.reply(message, 'You mentioned me and said, "' + message.text + '"');
});

controller.on('direct_message', function(bot, message) {
    bot.reply(message, 'I got your private message. You said, "' + message.text + '"');
});

Controller Options

When creating the Botkit controller, there are several platform-specific options available.

Botkit.sparkbot

Argument Description
public_address required the root url of your application (https://mybot.com)
ciscospark_access_token required token provided by Cisco Spark for your bot
secret required secret for validating webhooks originate from Cisco Spark
webhook_name optional name for webhook configuration on Cisco Spark side. Providing a name here allows for multiple bot instances to receive the same messages. Defaults to 'Botkit Firehose'
limit_to_org optional organization id in which the bot should exist. If user from outside org sends message, it is ignored
limit_to_domain optional email domain (@howdy.ai) or array of domains [@howdy.ai, @botkit.ai] from which messages can be received
var controller = Botkit.sparkbot({
    debug: true,
    log: true,
    public_address: 'https://mybot.ngrok.io',
    ciscospark_access_token: process.env.access_token,
    secret: 'randomstringofnumbersandcharacters12345',
    webhook_name: 'dev',
    limit_to_org: 'my_spark_org_id',
    limit_to_domain: ['@howdy.ai','@cisco.com'],
});

Spark Specific Events

All events listed here should be expected, in the format resource.event - for example, rooms.created.

In addition, the following custom Botkit-specific events are fired:

Event Description
direct_message Bot has received a message as a DM
direct_mention Bot has been mentioned in a public space
self_message Bot has received a message it sent
user_space_join a user has joined a space in which the bot is present
bot_space_join the bot has joined a new space
user_space_leave a user has left a space in which the bot is present
bot_space_leave the bot has left a space

Message Formatting

Cisco Spark supports both a text field and a markdown field for outbound messages. Read here for details on Cisco Spark's markdown support.

To specify a markdown version, add it to your message object:

bot.reply(message,{text: 'Hello', markdown: '*Hello!*'});

Attaching Files

Files can be attached to outgoing messages in one of two ways.

Specify URL

If the file you wish to attach is already available online, simply specify the URL in the files field of the outgoing message:

bot.reply(message,{text:'Here is your file!', files:['http://myserver.com/file.pdf']});

Send Local File

If the file you wish to attach is present only on the local server, attach it to the message as a readable stream:

var fs = require('fs');
bot.reply(message,{text: 'I made this file for you.', files:[fs.createReadStream('./newfile.txt')]});

Receiving files

Your bot may receive messages with files attached. Attached files will appear in an array called message.original_message.files.

Botkit provides 2 methods for retrieving information about the file.

bot.retrieveFileInfo(url, cb)

Parameter Description
url url of file from message.original_message.files
cb callback function in the form function(err, file_info)

The callback function will receive an object with fields like filename, content-type, and content-length.

controller.on('direct_message', function(bot, message) {
    bot.reply(message, 'I got your private message. You said, "' + message.text + '"');
    if (message.original_message.files) {
        bot.retrieveFileInfo(message.original_message.files[0], function(err, file_info) {
            bot.reply(message,'I also got an attached file called ' + file_info.filename);
        });
    }
});

bot.retrieveFile(url, cb)

Parameter Description
url url of file from message.original_message.files
cb callback function in the form function(err, file_content)

The callback function will receive the full content of the file.

controller.on('direct_message', function(bot, message) {
    bot.reply(message, 'I got your private message. You said, "' + message.text + '"');
    if (message.original_message.files) {
        bot.retrieveFileInfo(message.original_message.files[0], function(err, file_info) {
            if (file_info['content-type'] == 'text/plain') {
                bot.retrieveFile(message.original_message.files[0], function(err, file) {
                    bot.reply(message,'I got a text file with the following content: ' + file);
                });
            }
        });
    }
});

Starting Direct Messages

Cisco Spark's API provides several ways to send private messages to users - by the user's email address, or by their user id. These may be used in the case where the user's email address is unknown or unavailable, or when the bot should respond to the actor instead of the sender of a message.

For example, a bot may use these methods when handling a bot_space_join event in order to send a message to the user who invited the bot (the actor) instead of the bot itself (the sender).

NOTE: Core functions like bot.startPrivateConversation() work as expected, and will create a direct message thread with the sender of the incoming_message.

bot.startPrivateConversationWithPersonId()

Parameter Description
personId the personId of the user to whom the bot should send a message
cb callback function in the form function(err, file_content)

Use this function to send a direct message to a user by their personId, which can be found in message and event payloads at the following location:

var personId = message.original_message.actorId;

bot.startPrivateConversationWithActor())

Parameter Description
incoming_message a message or event that has an actorId defined in message.original_message.actorId
cb callback function in the form function(err, file_content)
controller.on('bot_space_join', function(bot, message) {
  bot.startPrivateConversationWithActor(message, function(err, convo) {
    convo.say('The bot you invited has joined the channel.');
  });
});