Skip to content
A framework for creating Webex Teams bots using node and express
JavaScript
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.vscode
docs
lib
quickstart
storage
templates/bothub-template
test
.gitignore
LICENSE
README.md
index.js
package-lock.json
package.json
webhook.js

README.md

webex-node-bot-framework

Webex Teams Bot Framework for Node JS

This project is inspired by, and provides an alternate implementation of, the awesome node-flint framework by Nick Marus. The framework makes it easy to quickly develop a Webex Teams bot, abstracting away some of the complexity of Webex For Developers interfaces, such as registering for events and calling REST APIs. A bot developer can use the framework to focus primarily on how the bot will interact with users in Webex Teams, by writing "handlers" for various message or membership events in spaces where the bot has been added.

The primary change in this implementation is that it is based on the webex-jssdk which continues to be supported as new features and functionality are added to Webex.

For developers who are familiar with flint, or who wish to port existing bots built on node-flint to the webex-node-bot-framework, this implementation is NOT backwards compatible. Please see Migrating from the original flint framework

Version History

Contents

Installation

Via Git

mkdir myproj
cd myproj
git clone https://github.com/webex/webex-node-bot-framework
npm install ./webex-node-bot-framework

Via NPM

mkdir myproj
cd myproj
npm install webex-node-bot-framework

Example Template Using Express

var Framework = require('webex-node-bot-framework'); 
var webhook = require('webex-node-bot-framework/webhook');

var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.json());

// framework options
var config = {
  webhookUrl: 'http://myserver.com/framework',
  token: 'Tm90aGluZyB0byBzZWUgaGVyZS4uLiBNb3ZlIGFsb25nLi4u',
  port: 80
};

// init framework
var framework = new Framework(config);
framework.start();

// An initialized event means your webhooks are all registered and the 
// framework has created a bot object for all the spaces your bot is in
framework.on("initialized", function () {
  framework.debug("Framework initialized successfully! [Press CTRL-C to quit]");
});

// A spawn event is generated when the framework finds a space with your bot in it
// You can use the bot object to send messages to that space
// The id field is the id of the framework
// If addedBy is set, it means that a user has added your bot to a new space
// Otherwise, this bot was in the space before this server instance started
framework.on('spawn', function (bot, id, addedBy) {
  if (!addedBy) {
    // don't say anything here or your bot's spaces will get 
    // spammed every time your server is restarted
    framework.debug(`Framework created an object for an existing bot in a space called: ${bot.room.title}`);
  } else {
    // addedBy is the ID of the user who just added our bot to a new space, 
    // Say hello, and tell users what you do!
    bot.say('Hi there, you can say hello to me.  Don\'t forget you need to mention me in a group space!');
  }
});

var responded = false;
// say hello
framework.hears('hello', function(bot, trigger) {
  bot.say('Hello %s!', trigger.person.displayName);
  responded = true;
});

// Its a good practice to handle unexpected input
framework.hears(/.*/gim, function(bot, trigger) {
  if (!responded) {
    bot.say('Sorry, I don\'t know how to respond to "%s"', trigger.message.text);
  }
  responded = false;
});

// define express path for incoming webhooks
app.post('/framework', webhook(framework));

// start express server
var server = app.listen(config.port, function () {
  framework.debug('Framework listening on port %s', config.port);
});

// gracefully shutdown (ctrl-c)
process.on('SIGINT', function() {
  framework.debug('stoppping...');
  server.close();
  framework.stop().then(function() {
    process.exit();
  });
});

Websocket Example

Buttons and Cards Example

Restify Example

Overview

The framework provides developers with some basic scaffolding to quickly get a bot up and running. Once a framework object is created with a configuration that includes a bot token, calling the framework.start() method kicks of the setup of this scaffolding. The framework registers for all Webex Teams events, and may discover existing Webex Teams spaces that the bot is already a member of.

A bot object is created for each space, and the framework generates a spawn event each time it finds a new one. When all existing bot objects are created the framework generates an initialized event signalling that it is ready to begin "listening" for user input.

// init framework
var framework = new Framework(config);
framework.start();

// An initialized event means your webhooks are all registered and the 
// framework has created bot objects for the spaces your bot was found in
framework.on("initialized", function () {
  framework.debug("Framework initialized successfully! [Press CTRL-C to quit]");
});

// A spawn event is generated when the framework finds a space with your bot in it
// You can use the bot object to send messages to that space
// The id field is the id of the framework
// If addedBy is set, it means that a user has added your bot to a new space
// Otherwise, this bot was in the space before this server instance started
framework.on('spawn', function (bot, id, addedBy) {
  if (!addedBy) {
    // don't say anything here or your bot's spaces will get 
    // spammed every time your server is restarted
    framework.debug(`Framework created an object for an existing bot in a space called: ${bot.room.title}`);
  } else {
    // addedBy is the ID of the user who just added our bot to a new space, 
    // Say hello, and tell users what you do!
    bot.say('Hi there, you can say hello to me.  Don\'t forget you need to mention me in a group space!');
  }
});

Most of the framework's functionality is based around the framework.hears() function. This defines the phrase or pattern the bot is listening for and what actions to take when that phrase or pattern is matched. The framework.hears() function gets a callback that includes three objects: the bot object, and the trigger object, and the id of the framework.

The bot object is a specific instance of the bot class associated with the Webex Teams space that triggered the framework.hears() call.
The trigger object provides details about the message that was sent, and the person who sent it, which caused the framework.hears() function to be triggered.

A simple example of a framework.hears() function setup:

framework.hears(phrase, function(bot, trigger, id) {
  bot.<command>
    .then(function(returnedValue) {
      // do something with returned value
    })
    .catch(function(err) {
      // handle errors
    });
});
  • phrase : This can be either a string or a regex pattern. If a string, the string is matched against the first word in the room message. message. If a regex pattern is used, it is matched against the entire message text.
  • bot : The bot object that is used to execute commands when the phrase is triggered.
  • bot.<command> : The Bot method to execute.
  • then : Node JS Promise keyword that invokes additional logic once the previous command is executed.
  • catch : handle errors that happen at either the original command or in any of the chained 'then' functions.
  • trigger : The object that describes the details around what triggered the phrase.
  • commands : The commands that are ran when the phrase is heard.

Authentication

The token used to authenticate the Framework with the Webex API is passed as part of the options used when instantiating the Framework class. To change or update the token, use the Framework#setWebexToken() method.

Example:

var newToken = 'Tm90aGluZyB0byBzZWUgaGVyZS4uLiBNb3ZlIGFsb25nLi4u';

framework.setWebexToken(newToken)
.then(function(token) {
  console.log('token updated to: ' + token);
});

Storage

The storage system used in the framework is a simple key/value store and resolves around these 3 methods:

  • bot.store(key, value) - Store a value to a bot instance where 'key' is a string and 'value' is a boolean, number, string, array, or object. This does not not support functions or any non serializable data. Returns the a promise with the value.
  • bot.recall(key) - Recall a value by 'key' from a bot instance. Returns a resolved promise with the value or a rejected promise if not found.
  • bot.forget([key]) - Forget (remove) value(s) from a bot instance where 'key' is an optional property that when defined, removes the specific key, and when undefined, removes all keys. Returns a resolved promise if deleted or not found.

When a bot is first spawned, the framework calls the bot.initStorage method which attepts to load any previously existing bot storage elements (if using a persistent storage driver such as MongoStore), or will create an optional initial set of key/value pairs that were specified in the framework's configuration options initBotStorageData element. If this is not set, new bots start off with no key/value pairs until bot.store() is called.

When a bot despawns (is removed from a space), the key/value store for that bot instance will automatically be removed from the store. Framework currently has an in-memory store and a mongo based store. By default, the in-memory store is used. Other backend stores are possible by replicating any one of the built-in storage modules and passing it to the framework.storeageDriver() method.

The MongoStore (and potentially other stores that use a persistent storage mechanism), also support the following methods:

  • initialize() -- this must be called before framework.storageDriver() and framework.start() are called, and will validate that the configuration is correct
  • writeMetrics() -- is a new, optional, method for persistent storage adaptors that can be called to write breadcrumbs into the database that can be used to build reports on the bot's usage

See MongoStore, for details on how to configure this storage adaptor.

The redis adaptor is likely broken and needs to be updated to support the new functions. It would be great if a flint user of redis wanted to contribute!

Bot Accounts

When using "Bot Accounts" the major differences are:

  • Webhooks for message:created only trigger when the Bot is mentioned by name
  • Unable to read messages in rooms using the Webex API

Differences with trigger.args using Framework with a "Bot Account":

The trigger.args array is a shortcut in processing the trigger.text string. It consists of an array of the words that are in the trigger.message string split by one or more spaces. Punctation is included if there is no space between the symbol and the word. With bot accounts, this behaves a bit differently.

  • If defining a framework.hears() using a string (not regex), trigger.args is a filtered array of words from the message that begins after the first match of bot mention.

  • If defining a framework.hears() using regex, the trigger.args array is the entire message.

Framework Reference

Classes

Framework
Bot

Objects

Trigger : object

Trigger Object

Events

"log"

Framework log event.

"stop"

Framework stop event.

"start"

Framework start event.

"initialized"

Framework initialized event.

"roomLocked"

Room Locked event.

"roomUnocked"

Room Unocked event.

"roomRenamed"

Room Renamed event.

"memberEnters"

Member Enter Room event.

"botAddedAsModerator"

Bot Added as Room Moderator.

"botRemovedAsModerator"

Bot Removed as Room Moderator.

"memberAddedAsModerator"

Member Added as Moderator.

"memberRemovedAsModerator"

Member Removed as Moderator.

"memberExits"

Member Exits Room.

"mentioned"

Bot Mentioned.

"message"

Message Recieved.

"files"

File Recieved.

"spawn"

Bot Spawned.

"despawn"

Bot Despawned.

Framework

Kind: global class
Properties

Name Type Description
id string Framework UUID
active boolean Framework active state
initialized boolean Framework fully initialized
isBotAccount boolean Is Framework attached to Webex using a bot account?
isUserAccount boolean Is Framework attached to Webex using a user account?
person object Framework person object
email string Framework email
webex object The Webex JSSDK instance used by Framework

new Framework(options)

Creates an instance of the Framework.

Param Type Description
options Object Configuration object containing Framework settings.

Example

var options = {
  webhookUrl: 'http://myserver.com/framework',
  token: 'Tm90aGluZyB0byBzZWUgaGVyZS4uLiBNb3ZlIGFsb25nLi4u'
};
var framework = new Framework(options);

framework.options : object

Options Object

Kind: instance namespace of Framework
Properties

Name Type Default Description
token string Webex Token.
[webhookUrl] string URL that is used for Webex API to send callbacks. If not set events are received via websocket
[webhookSecret] string If specified, inbound webhooks are authorized before being processed. Ignored if webhookUrl is not set.
[maxStartupSpaces] number 100 If specified, the maximum number of spaces with our bot that the framework will discover during startup. Max value for this parameter is 1000. Setting this emulates the legacy flint startup behavior, otherwise bots are discovered "just in time" if they are messaged in existing spaces or added to new spaces, which is closer to the way webex teams clients also work. See the Spawn Event docs to discover how to handle them differently
[messageFormat] string "text" Default Webex message format to use with bot.say().
[initBotStorageData] object {} Initial data for new bots to put into storage.
[id] string "random" The id this instance of Framework uses.
[webhookRequestJSONLocation] string "body" The property under the Request to find the JSON contents.
[removeWebhooksOnStart] Boolean true If you wish to have the bot remove all account webhooks when starting. Ignored if webhookUrl is not set.

framework.setWebexToken(token) ⇒ Promise.<String>

Tests, and then sets a new Webex Token.

Kind: instance method of Framework

Param Type Description
token String New Webex Token for Framework to use.

Example

framework.setWebexToken('Tm90aGluZyB0byBzZWUgaGVyZS4uLiBNb3ZlIGFsb25nLi4u')
  .then(function(token) {
     console.log('token updated to: ' + token);
  });

framework.stop() ⇒ Promise.<Boolean>

Stop Framework.

Kind: instance method of Framework
Example

framework.stop();

framework.start() ⇒ Promise.<Boolean>

Start Framework.

Kind: instance method of Framework
Example

framework.start();

framework.restart() ⇒ Promise.<Boolean>

Restart Framework.

Kind: instance method of Framework
Example

framework.restart();

framework.hears(phrase, action, [helpText], [preference]) ⇒ String

Add action to be performed when bot hears a phrase.

Kind: instance method of Framework

Param Type Default Description
phrase Regex | String The phrase as either a regex or string. If regex, matches on entire message.If string, matches on first word.
action function The function to execute when phrase is matched. Function is executed with 2 variables. Trigger and Bot. The Trigger Object contains information about the person who entered a message that matched the phrase. The Bot Object is an instance of the Bot Class as it relates to the room the message was heard.
[helpText] String The string of text that describes how this command operates.
[preference] Number 0 Specifies preference of phrase action when overlapping phrases are matched. On multiple matches with same preference, all matched actions are excuted. On multiple matches with difference preference values, only the lower preferenced matched action(s) are executed.

Example

// using a string to match first word and defines help text
framework.hears('/say', function(bot, trigger, id) {
  bot.say(trigger.args.slice(1, trigger.arges.length - 1));
}, '/say <greeting> - Responds with a greeting');

Example

// using regex to match across entire message
framework.hears(/(^| )beer( |.|$)/i, function(bot, trigger, id) {
  bot.say('Enjoy a beer, %s! 🍻', trigger.person.displayName);
});

framework.clearHears(id) ⇒ null

Remove a "framework.hears()" entry.

Kind: instance method of Framework

Param Type Description
id String The "hears" ID.

Example

// using a string to match first word and defines help text
var hearsHello = framework.hears('/framework', function(bot, trigger, id) {
  bot.say('Hello %s!', trigger.person.displayName);
});
framework.clearHears(hearsHello);

framework.showHelp([header], [footer]) ⇒ String

Display help for registered Framework Commands.

Kind: instance method of Framework

Param Type Default Description
[header] String Usage: String to use in header before displaying help message.
[footer] String Powered by Webex Node Bot Framework - https://github.com/webex/webex-node-bot-framework String to use in footer before displaying help message.

Example

framework.hears('/help', function(bot, trigger, id) {
  bot.say(framework.showHelp());
});

framework.setAuthorizer(Action) ⇒ Boolean

Attaches authorizer function.

Kind: instance method of Framework

Param Type Description
Action function The function to execute when phrase is matched to authenticate a user. The function is passed the bot, trigger, and id and expects a return value of true or false.

Example

function myAuthorizer(bot, trigger, id) {
  if(trigger.personEmail === 'john@test.com') {
    return true;
  }
  else if(trigger.personDomain === 'test.com') {
    return true;
  }
  else {
    return false;
  }
}
framework.setAuthorizer(myAuthorizer);

framework.clearAuthorizer() ⇒ null

Removes authorizer function.

Kind: instance method of Framework
Example

framework.clearAuthorizer();

framework.storageDriver(Driver) ⇒ Promise.<Boolean>

Defines storage backend.

Kind: instance method of Framework
Returns: Promise.<Boolean> - - True if driver loaded succesfully

Param Type Description
Driver function The storage driver.

Example

// define memory store (default if not specified)
framework.storageDriver(new MemStore());

framework.use(path) ⇒ Boolean

Load a Plugin from a external file.

Kind: instance method of Framework

Param Type Description
path String Load a plugin at given path.

Example

framework.use('events.js');

Example

// events.js
module.exports = function(framework) {
  framework.on('spawn', function(bot) {
    console.log('new bot spawned in room: %s', bot.myroom.title);
  });
  framework.on('despawn', function(bot) {
    console.log('bot despawned in room: %s', bot.myroom.title);
  });
  framework.on('messageCreated', function(message, bot) {
    console.log('"%s" said "%s" in room "%s"', message.personEmail, message.text, bot.myroom.title);
  });
};

Bot

Kind: global class
Properties

Name Type Description
id string Bot UUID
active boolean Bot active state
person object Bot's Webex Person Object
email string Bot email
room object Bot's Webex Room object
membership object Bot's Webex Membership object
isLocked boolean If bot is locked
isModerator boolean If bot is a moderator
isGroup boolean If bot is in Group Room
isDirect boolean If bot is in 1:1/Direct Room
isDirectTo string Recipient Email if bot is in 1:1/Direct Room
lastActivity date Last bot activity

new Bot(framework, options, webex)

Creates a Bot instance that is then attached to a Webex Team Room.

Param Type Description
framework Object The framework object this Bot spawns under.
options Object The options of the framework object this Bot spawns under.
webex Object The webex sdk of the framework object this Bot spawns under.

bot.exit() ⇒ Promise.<Boolean>

Instructs Bot to exit from room.

Kind: instance method of Bot
Example

bot.exit();

bot.add(email(s), [moderator]) ⇒ Promise.<Array>

Instructs Bot to add person(s) to room.

Kind: instance method of Bot
Returns: Promise.<Array> - Array of emails added

Param Type Description
email(s) String | Array Email Address (or Array of Email Addresses) of Person(s) to add to room.
[moderator] Boolean Add as moderator.

Example

// add one person to room by email
bot.add('john@test.com');

Example

// add one person as moderator to room by email
bot.add('john@test.com', true)
  .catch(function(err) {
    // log error if unsuccessful
    console.log(err.message);
  });

Example

// add 3 people to room by email
bot.add(['john@test.com', 'jane@test.com', 'bill@test.com']);

bot.remove(email(s)) ⇒ Promise.<Array>

Instructs Bot to remove person from room.

Kind: instance method of Bot
Returns: Promise.<Array> - Array of emails removed

Param Type Description
email(s) String | Array Email Address (or Array of Email Addresses) of Person(s) to remove from room.

Example

// remove one person to room by email
bot.remove('john@test.com');

Example

// remove 3 people from room by email
bot.remove(['john@test.com', 'jane@test.com', 'bill@test.com']);

bot.getModerators() ⇒ Promise.<Array>

Get room moderators.

Kind: instance method of Bot
Example

bot.getModerators()
  .then(function(moderators) {
    console.log(moderators);
  });

bot.newRoom(name, emails, isTeam) ⇒ Promise.<Bot>

Create new room with people by email

Kind: instance method of Bot

Param Type Description
name String Name of room.
emails Array Emails of people to add to room.
isTeam Boolean - Create a team room (if bot is already in a team space)

bot.newTeamRoom(name, emails) ⇒ Promise.<Bot>

Create new Team Room

This can also be done by passing an optional boolean isTeam param to the newRoom() function, but this function is also kept for compatibility with node-flint

Kind: instance method of Bot

Param Type Description
name String Name of room.
emails Array Emails of people to add to room.

bot.moderateRoom() ⇒ Promise.<Bot>

Enable Room Moderation.

This function will not work when framework was created using a bot token, it requires an authorized user token

Kind: instance method of Bot
Example

bot.moderateRoom()
  .then(function(err) {
    console.log(err.message)
  });

bot.unmoderateRoom() ⇒ Promise.<Bot>

Disable Room Moderation.

This function will not work when framework was created using a bot token, it requires an authorized user token

Kind: instance method of Bot
Example

bot.unmoderateRoom()
  .then(function(err) {
    console.log(err.message)
  });

bot.moderatorSet(email(s)) ⇒ Promise.<Bot>

Assign Moderator in Room

This function will not work when framework was created using a bot token, it requires an authorized user token

Kind: instance method of Bot

Param Type Description
email(s) String | Array Email Address (or Array of Email Addresses) of Person(s) to assign as moderator.

Example

bot.moderatorSet('john@test.com')
  .then(function(err) {
    console.log(err.message)
  });

bot.moderatorClear(email(s)) ⇒ Promise.<Bot>

Unassign Moderator in Room

This function will not work when framework was created using a bot token, it requires an authorized user token

Kind: instance method of Bot

Param Type Description
email(s) String | Array Email Address (or Array of Email Addresses) of Person(s) to unassign as moderator.

Example

bot.moderatorClear('john@test.com')
  .then(function(err) {
    console.log(err.message)
  });

bot.implode() ⇒ Promise.<Boolean>

Remove a room and all memberships.

Kind: instance method of Bot
Example

framework.hears('/implode', function(bot, trigger) {
  bot.implode();
});

bot.say([format], message) ⇒ Promise.<Message>

Send text with optional file to room.

Kind: instance method of Bot

Param Type Default Description
[format] String text Set message format. Valid options are 'text' or 'markdown'.
message String | Object Message to send to room. This can be a simple string, or a object for advanced use.

Example

// Simple example
framework.hears('/hello', function(bot, trigger) {
  bot.say('hello');
});

Example

// Simple example to send message and file
framework.hears('/file', function(bot, trigger) {
  bot.say({text: 'Here is your file!', file: 'http://myurl/file.doc'});
});

Example

// Markdown Method 1 - Define markdown as default
framework.messageFormat = 'markdown';
framework.hears('/hello', function(bot, trigger) {
  bot.say('**hello**, How are you today?');
});

Example

// Markdown Method 2 - Define message format as part of argument string
framework.hears('/hello', function(bot, trigger) {
  bot.say('markdown', '**hello**, How are you today?');
});

Example

// Mardown Method 3 - Use an object (use this method of bot.say() when needing to send a file in the same message as markdown text.
framework.hears('/hello', function(bot, trigger) {
  bot.say({markdown: '*Hello <@personEmail:' + trigger.personEmail + '|' + trigger.personDisplayName + '>*'});
});

Example

// Send an Webex card by providing a fully formed message object.
framework.hears('/card please', function(bot, trigger) {
  bot.say({       
     // Fallback text for clients that don't render cards is required
     markdown: "If you see this message your client cannot render buttons and cards.",
     attachments: [{
       "contentType": "application/vnd.microsoft.card.adaptive",
       "content": myCardsJson
    }]
   });

bot.reply(replyTo, message, [format]) ⇒ Promise.<Message>

Send a threaded message reply

NOTE: Posting a threaded message response via API is currently a Webex EFT feature. This method WILL FAIL if your application identity is not configured for EFT access

Kind: instance method of Bot

Param Type Default Description
replyTo Object Message or attachmentAction object to send to reply to.
message String | Object Message to send to room. This can be a simple string, or a object for advanced use.
[format] String text Set message format. Valid options are 'text' or 'markdown'.

Example

// Simple example
framework.hears('/hello', function(bot, trigger) {
  bot.reply(trigger.message, 'hello back at you');
});

Example

// Markdown Method 1 - Define markdown as default
framework.messageFormat = 'markdown';
framework.hears('/hello', function(bot, trigger) {
  bot.reply(trigger.message, '**hello**, How are you today?');
});

Example

// Markdown Method 2 - Define message format as part of argument string
framework.hears('/hello', function(bot, trigger) {
  bot.reply(trigger.message, '**hello**, How are you today?', 'markdown');
});

Example

// Mardown Method 3 - Use an object (use this method of bot.reply() when needing to send a file in the same message as markdown text.
framework.hears('/hello', function(bot, trigger) {
  bot.reply(trigger.message, {markdown: '*Hello <@personEmail:' + trigger.personEmail + '|' + trigger.personDisplayName + '>*'});
});

Example

// Reply to a card when a user hits an action.submit button
framework.on('attachmentAction', function(bot, trigger) {
  bot.reply(trigger.attachmentAction, 'Thanks for hitting the button');
});

bot.dm(person, [format], message) ⇒ Promise.<Message>

Send text with optional file in a direct message. This sends a message to a 1:1 room with the user (creates 1:1, if one does not already exist)

Kind: instance method of Bot

Param Type Default Description
person String Email or personId of person to send Direct Message.
[format] String text Set message format. Valid options are 'text' or 'markdown'.
message String | Object Message to send to room. This can be a simple string, or a object for advanced use.

Example

// Simple example
framework.hears('dm me', function(bot, trigger) {
  bot.dm(trigger.person.id, 'hello');
});

Example

// Simple example to send message and file
framework.hears('dm me a file', function(bot, trigger) {
  bot.dm(trigger.person.id, {text: 'Here is your file!', file: 'http://myurl/file.doc'});
});

Example

// Markdown Method 1 - Define markdown as default
framework.messageFormat = 'markdown';
framework.hears('dm me some rich text', function(bot, trigger) {
  bot.dm(trigger.person.id, '**hello**, How are you today?');
});

Example

// Markdown Method 2 - Define message format as part of argument string
framework.hears('dm someone', function(bot, trigger) {
  bot.dm('john@doe.com', 'markdown', '**hello**, How are you today?');
});

Example

// Mardown Method 3 - Use an object (use this method of bot.dm() when needing to send a file in the same message as markdown text.
framework.hears('dm someone', function(bot, trigger) {
  bot.dm('someone@domain.com', {markdown: '*Hello <@personId:' + trigger.person.id + '|' + trigger.person.displayName + '>*'});
});

bot.sendCard(cardJson, fallbackText) ⇒ Promise.<Message>

Send a Webex Teams Card to room.

Kind: instance method of Bot
See

Param Type Description
cardJson Object The card JSON to render. This can come from the Webex Buttons and Cards Designer.
fallbackText String Message to be displayed on client's that can't render cards.

Example

// Simple example
framework.hears('card please', function(bot, trigger) {
  bot.SendCard(
   {
      "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
      "type": "AdaptiveCard",
      "version": "1.0",
      "body": [
          {
              "type": "ColumnSet",
              "columns": [
                  {
                      "type": "Column",
                      "width": 2,
                      "items": [
                          {
                              "type": "TextBlock",
                              "text": "Card Sample",
                              "weight": "Bolder",
                              "size": "Medium"
                          },
                          {
                              "type": "TextBlock",
                              "text": "What is your name?",
                              "wrap": true
                          },
                          {
                              "type": "Input.Text",
                              "id": "myName",
                              "placeholder": "John Doe"
                          }
                      ]
                  }
              ]
          }
      ],
      "actions": [
          {
              "type": "Action.Submit",
              "title": "Submit"
          }
      ]
   },
   "This is the fallback text if the client can't render this card");
 });

bot.uploadStream(filename, stream) ⇒ Promise.<Message>

Upload a file to a room using a Readable Stream

Kind: instance method of Bot

Param Type Description
filename String File name used when uploading to room
stream Stream.Readable Stream Readable

Example

framework.hears('/file', function(bot, trigger) {

  // define filename used when uploading to room
  var filename = 'test.png';

  // create readable stream
  var stream = fs.createReadStream('/my/file/test.png');

  bot.uploadStream(filename, stream);
});

bot.messageStreamRoom(roomId, message) ⇒ Promise.<Message>

Streams message to a room.

Kind: instance method of Bot

Param Type Description
roomId String Webex Teams Room ID
message Object Message Object

Example

var roomId = 'Tm90aGluZyB0byBzZWUgaGVyZS4uLiBNb3ZlIGFsb25nLi4u';
var text = 'Hello';
var filename = 'test.png';
var stream = fs.createReadStream(filename);
var message = { 'text': text, 'filename': filename, 'stream': stream };
bot.messageStreamRoom(roomId, message)
  .then(function(message) {
    console.log('Message sent: %s', message.txt);
  })
  .catch(function(err){
    console.log(err);
  });

bot.upload(filepath) ⇒ Promise.<Message>

Upload a file to room.

Kind: instance method of Bot

Param Type Description
filepath String File Path to upload

Example

framework.hears('/file', function(bot, trigger) {
  bot.upload('test.png');
});

bot.censor(messageId) ⇒ Promise.<Message>

Remove Message By Id.

Kind: instance method of Bot

Param Type
messageId String

bot.roomRename(title) ⇒ Promise.<Room>

Set Title of Room.

Kind: instance method of Bot

Param Type
title String

Example

bot.roomRename('My Renamed Room')
  .then(function(err) {
    console.log(err.message)
  });

bot.getMessages(count) ⇒ Promise.<Array>

Get messages from room. Returned data has newest message at bottom.

This function will not work when framework was created using a bot token, it requires an authorized user token

Kind: instance method of Bot

Param Type Description
count Integer - count of messages to return (max 10)

Example

bot.getMessages(5).then(function(messages) {
  messages.forEach(function(message) {
    // display message text
    if(message.text) {
      console.log(message.text);
    }
  });
});

bot.store(key, value) ⇒ Promise.<String> | Promise.<Number> | Promise.<Boolean> | Promise.<Array> | Promise.<Object>

Store key/value data.

Kind: instance method of Bot

Param Type Description
key String Key under id object
value String | Number | Boolean | Array | Object Value of key

bot.recall([key]) ⇒ Promise.<String> | Promise.<Number> | Promise.<Boolean> | Promise.<Array> | Promise.<Object>

Recall value of data stored by 'key'.

Kind: instance method of Bot

Param Type Description
[key] String Key under id object (optional). If key is not passed, all keys for id are returned as an object.

bot.forget([key]) ⇒ Promise.<String> | Promise.<Number> | Promise.<Boolean> | Promise.<Array> | Promise.<Object>

Forget a key or entire store.

Kind: instance method of Bot

Param Type Description
[key] String Key under id object (optional). If key is not passed, id and all children are removed.

Trigger : object

Trigger Object

Kind: global namespace
Properties

Name Type Description
type string type of trigger - message or attachmentAction
id string Message or attachentAction ID
message object message that caused this trigger (if type is 'message')
phrase string | regex Matched lexicon phrase if any
args array Filtered array of words in message text.
attachmentAction object attachmentAction that caused this trigger (if type is 'attachmentAction')
person object Person object associated with user that sent the message or action
personId string ID of person

"log"

Framework log event.

Kind: event emitted
Properties

Name Type Description
message string Log Message

"stop"

Framework stop event.

Kind: event emitted
Properties

Name Type Description
id string Framework UUID

"start"

Framework start event.

Kind: event emitted
Properties

Name Type Description
id string Framework UUID

"initialized"

Framework initialized event.

Kind: event emitted
Properties

Name Type Description
id string Framework UUID

"roomLocked"

Room Locked event.

Kind: event emitted
Properties

Name Type Description
bot object Bot Object
id string Framework UUID

"roomUnocked"

Room Unocked event.

Kind: event emitted
Properties

Name Type Description
bot object Bot Object
id string Framework UUID

"roomRenamed"

Room Renamed event.

Kind: event emitted
Properties

Name Type Description
bot object Bot Object
id string Framework UUID

"memberEnters"

Member Enter Room event.

Kind: event emitted
Properties

Name Type Description
bot object Bot Object
membership object Membership Object
id string Framework UUID

"botAddedAsModerator"

Bot Added as Room Moderator.

Kind: event emitted
Properties

Name Type Description
bot object Bot Object
id string Framework UUID

"botRemovedAsModerator"

Bot Removed as Room Moderator.

Kind: event emitted
Properties

Name Type Description
bot object Bot Object
id string Framework UUID

"memberAddedAsModerator"

Member Added as Moderator.

Kind: event emitted
Properties

Name Type Description
bot object Bot Object
membership object Membership Object
id string Framework UUID

"memberRemovedAsModerator"

Member Removed as Moderator.

Kind: event emitted
Properties

Name Type Description
bot object Bot Object
membership object Membership Object
id string Framework UUID

"memberExits"

Member Exits Room.

Kind: event emitted
Properties

Name Type Description
bot object Bot Object
membership object Membership Object
id string Framework UUID

"mentioned"

Bot Mentioned.

Kind: event emitted
Properties

Name Type Description
bot object Bot Object
trigger object Trigger Object
id string Framework UUID

"message"

Message Recieved.

Kind: event emitted
Properties

Name Type Description
bot object Bot Object
trigger object Trigger Object
id string Framework UUID

"files"

File Recieved.

Kind: event emitted
Properties

Name Type Description
bot object Bot Object
trigger trigger Trigger Object
id string Framework UUID

"spawn"

Bot Spawned.

Kind: event emitted
Properties

Name Type Description
bot object Bot Object
id string Framework UUID
addedBy string ID of user who added bot to space if available. Bots are typically spawned in one of three ways: 1) When the framework first starts it can look for up to options.maxStartupSpaces spaces that our bot is already part of. When discovered a new bot is spawned. No addedBy parameter will be passed in this case and the framework.initialized variable will be false. 2) After the framework has started if a user sends a message to a bot in an existing space that was not discovered during startup, a bot object is spawned for the "just in time" discovered space. Developers should never assume that all possible spaces were discovered during the framework's startup. No addedBy parameter will be passed in this case and the framework.initialized variable will be true. 3) After the framework has started, if a user adds our bot to a new space a membership:created event occurs which also spawns a bot. The framework will inlcude the addedBy parameter and framework.initialized will be true. A best practice In these cases, is to include application logic for the bot to "introduce itself" and/or do something with the information about the user who created the bot's membership

Example

// DM the user who added bot to a group space
framework.on('spawn', function(bot, flintId, addedBy) {
    if (!addedById) {
     // don't say anything here or your bot's spaces will get
     // spammed every time your server is restarted
     framework.debug(`Framework spawned a bot object in existing
        space: ${bot.room.title}`);
  } else {
    if ((bot.room.type === 'group') && (addedBy)) {
      bot.dm(addedBy, `I see you added me to the the space "${bot.room.title}", ` +
        `but I am not allowed in group spaces.  We can talk here if you like.`);
      bot.exit();
    } else {
      bot.say(`Thanks for adding me to this space.  Here is what I can do...`);
    }
  }
});

"despawn"

Bot Despawned.

Kind: event emitted
Properties

Name Type Description
bot object Bot Object
id string Framework UUID
id string ID of user who removed the bot (if available)

Storage Driver Reference

MongoStore

Kind: global class

new MongoStore(config)

Creates an instance of the Mongo Storage Adaptor. This storage adaptor uses a Mongo database that allows bot storage information to persist across server restarts. It has been tested with cloud mongo db conections and requires mondodb driver 3.4 or greater.

Param Type Description
config Object Configuration object containing mongo db and collection settings.

Example

var config = {
  mongoUri: 'mongodb://[username:password@]host1[:port1][,...hostN[:portN]][/[database][?options]]',
  storageCollectionName: 'webexBotFrameworkStorage'
};
let MongoStore = require('webex-node-bot-framework/storage/mongo');
let mongoStore = new MongoStore(config);

mongoStore.config : object

Options Object

Kind: instance namespace of MongoStore
Properties

Name Type Default Description
mongoUri string URI to connect to Mongo. This is typically in the format of:\n mongodb+srv://[username:password@]host1[:port1][,...hostN[:portN]][/[database][?options]], ie: mongodb+srv://myUser:secretPassw0rd@cluster#-area.mongodb.net/myClusterDBName?retryWrites=true&w=majority`, see: https://docs.mongodb.com/manual/reference/connection-string/
[storageCollectionName] string "webexBotFramworkStorage" Mongo collection name for bot.store,recall (will be created if does not exist)
[initBotStorageData] object {} Object with any default key/value pairs that a new bot should get upon creation
[metricsCollectionName] string Mongo collection name for bot.writeMetric() (will be created if set, but does not exist), bot.writeMetric() calls will fail if this is not set
[singleInstance] Boolean false Optimize bot.recall() speed if the bot is only running a single instance. Data is still written to db, but lookups are done from local memory Should be used with caution!

mongoStore.initialize() ⇒ Promise.<Boolean>

Initializes the connection to the db. Call this, and wait for the return before setting the framework's storage adaptor, and then calling framework.start()

Kind: instance method of MongoStore
Returns: Promise.<Boolean> - - True if setup
Example

// Wait for the connection to the DB to initialize before setting the
 // framework's storage driver and starting framework
 mongoStore.initialize()
   .then(() => framework.storageDriver(mongoStore))
   .then(() => framework.start())
   .catch((e) => {
     console.error(`Initialization with mongo storage failed: ${e.message}`)
     process.exit(-1);
  });

mongoStore.getName() ⇒ string

Get the storage adaptor's name

Kind: instance method of MongoStore
Returns: string - - storage adaptor name

mongoStore.initStorage(id, initBotStorageData) ⇒ Promise.<Object>

Called by the framework, when a bot is spawned, this function reads in any existng bot configuration from the DB or creates the default one if none is found

In general bot developers should not need to call this method

Kind: instance method of MongoStore
Returns: Promise.<Object> - - bot's initial or previously stored config data

Param Type Description
id String Room/Conversation/Context ID
initBotStorageData object data to initialize a new bot with

mongoStore.store(id, key, value) ⇒ Promise.<String> | Promise.<Number> | Promise.<Boolean> | Promise.<Array> | Promise.<Object>

Store key/value data.

This method is exposed as bot.store(key, value);

Kind: instance method of MongoStore
Returns: Promise.<String> | Promise.<Number> | Promise.<Boolean> | Promise.<Array> | Promise.<Object> - -- stored value

Param Type Description
id String Room/Conversation/Context ID
key String Key under id object
value String | Number | Boolean | Array | Object Value of key

mongoStore.recall(id, [key]) ⇒ Promise.<String> | Promise.<Number> | Promise.<Boolean> | Promise.<Array> | Promise.<Object>

Recall value of data stored by 'key'.

This method is exposed as bot.recall(key, value);

Kind: instance method of MongoStore
Returns: Promise.<String> | Promise.<Number> | Promise.<Boolean> | Promise.<Array> | Promise.<Object> - -- recalled value

Param Type Description
id String Room/Conversation/Context ID
[key] String Key under id object (optional). If key is not passed, all keys for id are returned as an object.

mongoStore.forget(id, [key]) ⇒ Promise.<String> | Promise.<Number> | Promise.<Boolean> | Promise.<Array> | Promise.<Object>

Forget a key or entire store.

This method is exposed as bot.forget(key, value);

Kind: instance method of MongoStore

Param Type Description
id String Room/Conversation/Context ID
[key] String Key to forget (optional). If key is not passed, all stored configs are removed.

mongoStore.writeMetric(bot, appData, actor) ⇒ Promise.<Object>

Write a metrics object to the database

This method is exposed as bot.writeMetric(appData, actor);

Kind: instance method of MongoStore
Returns: Promise.<Object> - - final data object written

Param Type Description
bot object bot that is writing the metric
appData object app specific metric data.
actor object | string user that triggered the metric activity

License

The MIT License (MIT)

Copyright (c) 2016-2020

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

You can’t perform that action at this time.