Moxtra Bot SDK
Moxtra Bot SDK will ease and streamline the Bot development for Moxtra's business collaboration platform. The design allows developers to focus on application logic instead of APIs for sending and receiving data payload.
const MoxtraBot = ; const bot = client_id: 'YOUR_CLIENT_ID' client_secret: 'YOUR_CLIENT_SECRET' api_endpoint: 'https://apisandbox.moxtra.com/v1'; bot;
Core Concepts | Installation | Getting Started | Account Linking | Documentation | Examples | License |
---|
Core Concepts
- Definitions:
- Bot application (the 3rd party Bot) has a corresponding bot app configuration in Moxtra.
- Each bot app is identified by client_id in the message event.
Bot app
becomes a bot user (an org user) once thebot app
is enabled in an org. This bot user is identified by org_id in the message event.
- Bot lifecycle:
- Partner Admin creates a bot app configuration via Partner Admin Console
- An Org Admin enables this
bot app
via Org Admin Console or API, thisbot app
becomes a bot user inside this org. A bot_enabled event gets generated.- When the Org Admin disabled this
bot app
via Org Admin Console or API, a bot_disabled event gets generated.- Binder users of the same org as the binder owner can then add this bot user into the binder. A bot_installed event gets generated.
- When the bot user leaves the binder, a bot_uninstalled event gets generated.
-
Each received message event has the corresponding binder_id, client_id, and org_id, which are encapsulated in the
Chat
object.Bot application
can use client_id, org_id, and timestamp to generate a signature signed with client_secret to create abot user
access_token. -
Each
POST
message event from Moxtra hasx-moxtra-signature
header set as HMA-SHA1 hash of the message content signed withclient_secret
-
Different message event has the corresponding object in the event; however, the basic message structure remains the same. Below shows a
Comment
message event format:
message_id: 'MESSAGE_ID' message_type: 'comment_posted' binder_id: 'BINDER_ID' client_id: 'CLIENT_ID' org_id: 'ORG_ID' event: timestamp: 'TIMESTAMP' user: id: 'USER_ID' name: 'USERNAME' comment: id: 'COMMENT_ID' text: 'TEXT MESSAGE' audio: 'AUDIO MESSAGE' target: id: 'BINDER_ID' object_type: 'binder'
Installation
$ npm install moxtra-bot-sdk --save
You can also check out Moxtra Bot SDK directly from Git. If you want to use the example code and included bots, it may be preferable to use Github over NPM.
git clone https://github.com/Moxtra/moxtra-bot-sdk-nodejs.git
Getting Started
-
After MoxtraBot is installed via NPM, create a new bot instance using your
client_id
andclient_secret
obtained from your Manage Bots in Partner Admin Console in thebot app
creation. -
Set correct API endpoint for different environment:
[Sandbox] api_endpoint:
'https://apisandbox.moxtra.com/v1'
[Production] api_endpoint:'https://api.moxtra.com/v1'
const MoxtraBot = ; const bot = client_id: 'YOUR_CLIENT_ID' client_secret: 'YOUR_CLIENT_SECRET' api_endpoint: 'https://apisandbox.moxtra.com/v1';
- Subscribe to messages with the
bot.on()
method for various events: message, bot_enabled, bot_disabled, bot_installed, bot_uninstalled, postback, and account_link.
bot; bot; bot; bot; bot;
Other message events are page_created, file_uploaded, page_annotated, todo_created, todo_completed and meet_recording_ready.
- Subscribe to messages with the
bot.hears()
method using regular expression or exact keyword match:
bot;
- Reply to messages using the
chat
object:
bot;
- Obtain access_token
bot;
- Set access_token before sending message
chat;
- Send Text
chat;
- Send RichText (in BBCode style)
chat;
- Send JSON (in key-value style along with a pre-configured or an on-demand template)
const fields =title: 'BBCode Info'from: usernameinfo: textimage_url: 'https://www.bbcode.org/images/lubeck_small.jpg';chat;
- Upload File or Add Audio Comment for audio file (audio/x-m4a, audio/3gpp)
var options = {};optionsfile_path = `/examples/Upload/start.png`;optionsaudio_path = `/examples/Upload/test_comment.3gpp`;chat;
- Matching keywords for more than once:
If there are more than one keyword matches in bot.hears()
, the same handler as well as bot.on('message') event handler would get invoked. By checking chat.condition
to determine whether to handle in this situation. You can turn off the generic handler in case there are keywords matches via bot.setGenericHandling(false);
chat.condition.match
- the word that matches the regular expression or the whole keyword
chat.condition.primatches
- the number of times that match happened before
bot
- Add
POSTBACK
button to the reply:
buttons
array
Setting desired buttons in an array which would form buttons in a single column layout
POSTBACK
object
type - "postpack"
text - required text shown on the button
payload - optional info to carry back; if not specified, it's "MOXTRABOT_text in uppercase"A single string can also turn into a button object; for example 'Not Sure?' becomes
{
type: 'postpack',
text: 'Not Sure?',
payload: 'MOXTRABOT_NOT SURE?"
}
var buttons = type: 'postback' text: 'Sure!' 'Not Sure?'; chat;
or
chat;
or
chat;
- Handle postback event:
The postback event gets triggered when the POSTBACK
button is tapped. The corresponding postback:TEXT gets triggered as well.
bot; bot;
- Set up Express server:
You can setup your own preferred web application framework as well as endpoints for handling GET
and POST
methods. In the example, we use Express
to showcase how it is to be done and using /webhooks
as the endpoints.
const express = ;const bodyParser = ; const app = ; const MoxtraBot = ; const bot = client_id: 'YOUR_CLIENT_ID' client_secret: 'YOUR_CLIENT_SECRET' api_endpoint: 'https://apisandbox.moxtra.com/v1'; app;app; // handle account_linkapp; // handle message eventsapp;
Account Linking
- Link Moxtra account with the 3rd party service through Account Linking flow:
- User sends a request to Bot (Bot application), which requires access to a 3rd party service that needs user's authorization. Bot does not have prior user account linking info with the 3rd party service.
- Bot sends
ACCOUNT_LINK
button back to Moxtra chat.- User clicks the button and a JSON web token sends back to Bot via the
GET
method.- Bot verifies the token using
client_secret
as the key and decodes the token; Bot obtains user_id, username, binder_id, client_id, and org_id via handling the bot.on('account_link') event.- Bot needs to check whether the user_id having the corresponding access_token from the 3rd party service in case
ACCOUNT_LINK
button might be tapped more than once or by different users in a group chat. If no, next OAuth2 authorization flow would then follows.- After obtaining the access_token from the 3rd party service, Bot needs to complete the original request.
- Add
ACCOUNT_LINK
button:
var buttons = type: 'account_link' text: 'Sign In' ; chat;
- Handle account_link event:
bot;
- Setup OAuth2 configuration and handle OAuth2 flow:
const OAuth2 = ; const config = client_id: "YOUR_CLIENT_ID" client_secret: "YOUR_CLIENT_SECRET" api_endpoint: "https://apisandbox.moxtra.com/v1" oauth2_client_id: "SERVICE_OAUTH2_CLIENT_ID" oauth2_client_secret: "SERVICE_OAUTH2_CLIENT_SECRET" oauth2_endpoint: "SERVICE_OAUTH2_ENDPOINT" oauth2_auth_path: "SERVICE_OAUTH2_AUTH_PATH" oauth2_token_path: "SERVICE_OAUTH2_TOKEN_PATH" oauth2_redirect_uri: "SERVICE_OAUTH2_DIRECT_URI"; ...const oauth2 = bot config; // OAuth2 request flowapp; // OAuth2 callback to obtain access_tokenapp;
- Obtain
access_token
via catching access_token event
// after doing OAuth2 against the 3rd party service to obtain a user level access_tokenbot;
Documentation
MoxtraBot Class
new MoxtraBot(configuration)
configuration key |
Type | Required |
---|---|---|
client_id |
string | Y |
client_secret |
string | Y |
api_endpoint |
string | N |
Creates a new MoxtraBot
instance.
MoxtraBot API
.on(event, callback (parameters) )
Subscribe to the message event emitted by the bot, and a callback gets invoked with the parameter pertaining to the event type. Available events are:
Event | Callback Parameters | Description |
---|---|---|
bot_enabled | Chat object - chat.bot | Org Admin enabled the bot app in one org |
bot_disabled | Chat object - chat.bot | Org Admin disabled the bot app from the org |
bot_installed | Chat object - chat.bot | A binder user added the bot user in the binder |
bot_uninstalled | Chat object - chat.bot | A binder user removed the bot user from the binder |
message | Chat object - chat.comment | The Bot application received a text message from the user by commenting in a binder |
postback | Chat object - chat.postback | The Bot application received a postback call from the user after clicking a POSTBACK button |
account_link | Request, Response, JSON Web Token content | The Bot application received an account_link call from the user after clicking an ACCOUNT_LINK button |
page_created | Chat object - chat.page | The Bot application received a message that a page was created in the binder |
file_uploaded | Chat object - chat.file | The Bot application received a message that a file was uploaded in the binder |
page_annotated | Chat object - chat.annotate | The Bot application received a message that an annotation was created on a page in the binder |
todo_created | Chat object - chat.todo | The Bot application received a message that a todo item was created in the binder |
todo_completed | Chat object - chat.todo | The Bot application received a message that a todo item was completed in the binder |
meet_recording_ready | Chat object - chat.meet | The Bot application received a message that a meet recording was ready in the binder |
Example:
bot; bot; bot;
.hears(patterns, callback (chat) )
Using pattern matching mechanism to handle desired message. The patterns
param can be a string, a regex or an array of both strings and regexs that find matching against the received message. If a match was found, the callback gets invoked. At the same time, message
event also gets fired. chat.condition
needs to be checked in such case.
Param | Type | Required |
---|---|---|
patterns |
string, regex or mixed array | Y |
callback (chat) |
function | Y |
Example:
bot;
Chat Class and API
new Chat(bot)
Chat instance is created in the callback for each type of message event except account_link. Therefore, chat.binder_id, chat.user_id, chat.username, chat.client_id, and chat.org_id as well as the corresponding event object are pre-populated.
A typical Chat
instance has the following structure:
moxtrabot: MoxtraBot instance data: raw message event data binder_id: 'BINDER_ID' client_id: 'CLIENT_ID' org_id: 'ORG_ID' access_token: access_token for sending message condition: match: 'MATCHED_KEYWORD' primatches: NUMBER_OF_MATCHES_BEFORE user_id: 'USER_ID' username: 'USERNAME' // for bot_installed event bot: id: 'BOT_ID' name: 'BOT_NAME' // for message event comment: id: 'COMMENT_ID' text: 'TEXT MESSAGE' audio: 'AUDIO MESSAGE' // for postback event postback: text: 'POSTBACK_TEXT' payload: 'POSTBACK_PAYLOAD' // for page_created and page_annotated event page: id: 'PAGE_ID' type: 'PAGE_TYPE' // for file_uploaded event file: id: 'FILE_ID' name: 'FILE_NAME' // for todo_created and todo_completed event todo: id: 'TODO_ID' name: 'TODO_ITEM_NAME' // for meet_recording_ready event meet: id: 'MEET_ID' topic: 'MEET_TOPIC' start_time: 'MEET_START_TIME' end_time: 'MEET_END_TIME' recording_url: 'MEET_RECORDING_URL' // sendText API { } // sendRichText API { } // sendJSON API { } // send API { } // sendRequest API { } // uploadRequest API { } // getBinderInfo API { }
buttons
buttons
is a string, button, or mixed array. A typical button
object structure is as follows:
type: 'postback | account_link' text: 'BUTTON_TEXT' payload: 'BUTTON_PAYLOAD'
options
options
is an object that specify on-demand action type, fields_template array - which is used in sendJSON()
, file_path for uploading a file attachment, and audio_path for adding audio comment for audio file (audio/x-m4a, audio/3gpp). A typical options
has the following structure:
action: 'chat | page | todo' fields_template: template_type: 'text | richtext | page' template: 'TEMPLATE' file_path: 'UPLOAD FILE PATH' audio_path: 'AUDIO COMMENT FILE PATH'
Example:
const fields = title: 'BBCode Info' from: 'USERNAME' info: 'TEXT' image_url: 'https://www.bbcode.org/images/lubeck_small.jpg'; const options = action: 'page' fields_template: template_type: 'page' template: '<p><image src="{{image_url}}" height="36" width="36"/><br/>' + '<div>Title: {{title}}<br/>From: {{from}}<br/>Message: {{info}}</div></p>' ;
.sendText(text, buttons, options)
Send a text message to Binder along with optional buttons
and options
.
Param | Type | Required |
---|---|---|
text |
string | Y |
buttons |
string, button or mixed array | N |
options |
options object | N |
Example:
const username = chatusername; var buttons = type: 'postback' text: 'Sure!' 'Not Sure?'; chat;
.sendRichText(richtext, buttons, text, options)
Send a richtext (in BBCode style) message along with optional buttons
, text
and options
.
If action
is todo, text
is set as todo item name and richtext
message as todo comment.
Param | Type | Required |
---|---|---|
richtext |
string | Y |
buttons |
string, button or mixed array | N |
text |
string | N , Y for action is todo |
options |
options object | N |
Example:
const username = chatusername;const text = chatcommenttext; const richtext = '[table][tr][th][center]BBCode Info[/center][/th][/tr]' + '[tr][td][img=50x25]https://www.bbcode.org/images/lubeck_small.jpg[/img][/td][/tr]' + '[tr][td]From: [i]' + username + '[/i][/td][/tr]' + '[tr][td][color=Red]' + text + '[/color][/td][/tr][/table]'; chat;
.sendJSON(fields, buttons, options)
Send a JSON object fields
(in key-value style along with a pre-configured or an on-demand template) message along with optional buttons
and options
.
Param | Type | Required |
---|---|---|
fields |
fields object | Y |
buttons |
string, button or mixed array | N |
options |
options object | N |
Example:
const username = chatusername;const text = chatcommenttext; const fields = title: 'BBCode Info' from: username info: text image_url: 'https://www.bbcode.org/images/lubeck_small.jpg';const options = action: 'page' fields_template: template_type: 'page' template: '<p><image src="{{image_url}}" height="36" width="36"/><br/>' + '<div>Title: {{title}}<br/>From: {{from}}<br/>Message: {{info}}</div></p>' ; chat;
.send(message, options)
Send a complete message along with options
. The message structure is shown as follows:
message: text: 'TEXT' richtext: 'RICHTEXT' fields: FIELDS action: 'chat | page | todo' buttons: type: 'postback | account_link' text: 'TEXT' payload: 'PAYLOAD'
.sendRequest(body, path, method)
This is the root API for sending API request to Moxtra. access_token
in the chat
has to present to send the request.
Param | Type | Required |
---|---|---|
body |
string | Y |
path |
string | N , default is '/messages' |
method |
string | N , default is 'POST' |
.uploadRequest(body, file_path, audio_path)
This is the API for uploading file and adding audio comment to Moxtra. access_token
in the chat
has to present to send the request.
Param | Type | Required |
---|---|---|
body |
string | N |
file_path |
string | N , file path |
audio_path |
string | N , audio file path for audio file (audio/x-m4a, audio/3gpp) |
.getBinderInfo()
This API is to get a particular binder information. binder_id
has to be set prior to making the api call.
Example:
var chat = bot; // obtain access_token bot;
Result:
"code": "RESPONSE_SUCCESS" "data": "id": "BiHGjPE2ZbsHyhVujuU4TUL" "name": "test bot" "created_time": 1487787567445 "updated_time": 1491598936463 "total_comments": 0 "total_members": 8 "total_pages": 0 "total_todos": 0 "revision": 884 "thumbnail_uri": "https://www.moxtra.com/board/BiHGjPE2ZbsHyhVujuU4TUL/4" "conversation": false "users": "restricted": false "team": false "description": "" "feeds_timestamp": 1491598936463 "status": "BOARD_MEMBER" "last_feed": null "binder_email": "b2f583d00339e44d0b2d02f9d50f352fa" "tags": null "unread_feeds": 0 "pages":
Examples
Check the examples
directory to see more samples of:
- An echo bot
- A bot using regular expression to capture text message
- A bot sending RichText message
- A bot sending Fields message
- A bot uploading file and adding audio comment
- A bot handling Account Link with OAuth2
To run the examples, make sure to complete the bot creation on MoxtraBot configuration and setup required configurations. For example, to run Echo example using the following command:
$ node examples/Echo
License
MIT