Botkit is designed to ease the process of designing and running useful, creative bots that live inside Microsoft Teams. For a full list of supported platforms, check out the main Botkit readme
Botkit features a comprehensive set of tools to deal with Microsoft Teams's integration platform, and allows developers to build both custom integrations for their team, as well as public "Microsoft Teams" applications that can be run from a central location, and be used by many teams at the same time.
This document covers the Microsoft Teams-specific implementation details only. Start here if you want to learn about how to develop with Botkit.
Table of Contents
- Getting Started
- Developing with Botkit for Microsoft Teams
- Working with Microsoft Teams
- Developer and Support Community
- About Botkit
- Botkit Documentation Index
Building bots is a fun and rewarding experience, but requires a few technical details be sorted out before you can start poking around inside your robot's brain.
To get started building your bot, you'll need get these three components set up so that they can communicate with each other:
- A Botkit-powered Node.js web app - this is the container inside which your bot brain lives, and where all its capabilities are defined
- The messaging platform - the place users interact with your bot, which provides a set of features, APIs and client applications
- A hosting environment - this gives your bot application a publicly reachable address on the public internet, which allows the messaging platform to communicate with your bot
Getting these elements in place is a multi-step process, but only takes a few minutes, and in most cases, only has to be done once!
The fastest way to get up and running with Botkit for Microsoft Teams is to use Botkit Studio. Botkit Studio will guide you through the process of setting up the Botkit Starter Kit for Microsoft Teams, walk you through the process of configuring the Microsoft Teams and Bot Framework APIs, and deploy your bot to a stable hosting environment so that you can start building right away.
If you are comfortable with developer tools like Git, NPM, and setting up your own web host, or if you want to build your bot on your laptop before making it available on the internet, you can start by cloning the Botkit Starter Kit for Microsoft Teams. The starter kit contains everything you need to build your bot, including a pre-configured Express webserver, customizable webhook endpoints, and a set of example features that provide a great base for your new bot.
Get Botkit Starter Kit for Microsoft Teams
Read our step-by-step guide for configuring your starter kit
If you are excited about building your entire bot from scratch, or if you want to integrate bot functionality into an existing Node application, you can install the Botkit core library directly from NPM.
npm install --save botkit
If you choose to use Botkit's core library directly like this, you'll need to either use Botkit's simple built-in webserver, or configure your own webserver and connect it to Botkit. An example of this can be seen in the starter kit.
(Our step-by-step guide to setting things up is probably still be useful, even for experts.)
The full code for a simple Microsoft Teams bot is below:
var Botkit = require('botkit');
var controller = Botkit.teamsbot({
clientId: process.env.clientId,
clientSecret: process.env.clientSecret,
});
controller.setupWebserver(process.env.PORT || 3000, function(err, webserver) {
controller.createWebhookEndpoints(webserver, function() {
console.log("BOTKIT: 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 + '"');
});
Before your bot application can be used, you must prepare an "App Package" - a zip file containing a JSON file of configuration options, and (optionally) icons for your bot to use inside the Teams interface. This file must then be "sideloaded" into your Microsoft Teams account - this is just a fancy way of saying that you will have to upload this file into a settings page.
The manifest.json file is a hefty document, with lots of options! Here is the full documentation from Microsoft. We highly recommend using Botkit Studio to build your app package, as we have provided an easy to use tool to configure and generate the necessary file!
Here is a COMPLETE SAMPLE
Argument | Description |
---|---|
clientId | The application' client id, provided by Bot Framework |
clientSecret | The application's client secret, provided by Bot Framework |
This function creates a Teams-ready Botkit controller. The values for clientId and clientSecret must be acquired from Bot Framework.
var controller = Botkit.teamsbot({
debug: true,
log: true,
clientId: process.env.clientId,
clientSecret: process.env.clientSecret
});
Argument | Description |
---|---|
options | An object defining options for this specific bot instance - MUST include a serviceUrl. |
This function returns a new instance of the bot. This is used internally by Botkit to respond to incoming events.
When spawning a bot for Microsoft Teams, you must pass in a serviceUrl
field as part of
the options parameter. The serviceUrl can be extracted from the incoming message payload at message.serviceUrl
.
For those curious about this parameter: the serviceUrl is used to construct API calls the bot makes to Microsoft's API endpoints. The endpoint URLs are actually defined dynamically in response to different kinds of incoming messages. This is because Microsoft Teams is just one of a network of Microsoft products that uses the Bot Framework API specification, each one with its own endpoint URLs.
In the event that your bot needs to send outbound messages without first receiving an inbound event from teams,
you should capture and store the serviceUrl value you receive from the bot_channel_join
event, which indicates
that a bot has been added to a new team.
var bot = controller.spawn({serviceUrl: my_team_info.serviceUrl});
In order to receive messages and other events from Microsoft Teams, Botkit must expose multiple web endpoints.
Botkit includes a simple built-in webserver based on Express that is great for getting started. With just a few lines of code, Botkit automatically configure the necessary web endpoints. There are very few options available for the built-in webserver, as it is intended to be used only for stand-alone bots.
If you want your bot application to have additional web features (like tabs), or if you need to add bot functionality to an existing Express website, or if you want to configure your own custom endpoints, we suggest using the Express Webserver component and Incoming Webhook Route from the Botkit Starter Kit as a guide for your custom implementation.
Argument | Description |
---|---|
port | port for webserver |
callback | callback function |
Setup an Express webserver for
use with createWebhookEndpoints()
Argument | Description |
---|---|
webserver | An instance of the Express webserver |
This function configures the route http://_your_server_/teams/receive
to receive incoming event data from Microsoft Teams.
This url should be used when configuring your Bot Framework record.
In addition to sending and receiving chat messages, Botkit bots can use all of the other features in the Microsoft Teams API. With these other features, Botkit bots can send rich attachments with interactive buttons, integrate into the message composer, and expose integrated tab applications that live inside the Teams window and share data with the bot.
Botkit receives and makes available all of the events supported by Microsoft Teams.
The full list and payload schema of these events is available from Microsoft.
These events undergo a normalization process for use inside Botkit,
so that any type of event can be passed to bot.reply()
in order for a normal
message response to be sent. All incoming events will have at least the following fields:
{
type: <type of event>,
user: <microsoft teams user ID>,
channel: <id for channel or 1:1 conversation>,
text: <text of message or primary payload value if present>,
raw_message: <the original event data>
}
Botkit leaves all the native fields intact, so any fields that come in from Teams are still present in the original message.
However, our recommendation for accessing any Teams-native fields is to use the message.raw_message
sub-object
which contains an unmodified version of the event data.
Event | Description |
---|---|
direct_message | the bot received a 1:1 direct message from a user |
direct_mention | the bot was addressed directly in a mult-user channel ("@bot hello!") |
mention | the bot was mentioned by someone in a message ("hello everyone including @bot") |
Event | Description |
---|---|
bot_channel_join | the bot has joined a channel |
user_channel_join | a user has joined a channel |
bot_channel_leave | the bot has left a channel |
user_channel_leave | a user has left a channel |
Event | Description |
---|---|
channelDeleted | a channel was deleted |
channelRenamed | a channel was renamed |
channelCreated | a new channel was created |
Event | Description |
---|---|
invoke | a user clicked an invoke button See Buttons |
composeExtension | user submitted a query with the compose extension See Compose Extensions |
The Microsoft Teams API provides a number of features the bot developer can use to power a useful bot application that operates seamlessly in Teams.
Parameter | Description |
---|---|
conversationId | Contains the unique identifier of a conversation |
userId | The unique identifier for a given user |
cb | Callback function in the form function(err, user_profile) |
getUserById
takes elements from an incoming message object, and returns the user profile data
associated with the message's sender.
controller.hears('who am i', 'direct_message, direct_mention', function(bot, message) {
bot.api.getUserById(message.channel, message.user, function(err, user) {
if (err) {
bot.reply(message,'Error loading user:' + err);
} else {
bot.reply(message,'You are ' + user.name + ' and your email is ' + user.email + ' and your user id is ' + user.id);
}
});
});
Parameter | Description |
---|---|
conversationId | Contains the unique identifier of a conversation |
upn | The User Principal Name of a given team member |
cb | Callback function in the form function(err, user_profile) |
This function is identical to getUserById()
, but instead of fetching the user by the Teams-only user ID, it uses the user's "universal principal name" or "UPN", which defines the account in terms of the broader Microsoft Office ecosystem. This function is useful when connecting users in Microsoft Teams chat with the same users in a Tab Application, as tab applications only expose the upn
value.
The Botkit Starter Kit for Microsoft Teams includes a sample middleware that uses this function to automatically translate the Teams-only ID into a UPN for use with the built-in storage system.
Parameter | Description |
---|---|
conversationId | Contains the unique identifier of a conversation |
cb | Callback function in the form function(err, members) |
This function returns a list of members in the specified channel - either a 1:1 channel, or a multi-user team channel.
This API returns an array of user profile objects identical to those returned by getUserById()
and getUserByUpn()
.
controller.hears('get members','direct_mention,direct_message', function(bot, message) {
bot.api.getConversationMembers(message.channel, function(err, roster) {
if (err) {
bot.reply(message,'Error loading roster: ' + err);
} else {
var list = [];
for (var u = 0; u < roster.length; u++) {
list.push(roster[u].name);
}
bot.reply(message,'Conversation members: ' + list.join(', '));
}
});
});
Parameter | Description |
---|---|
teamId | The unique identifier for a given team |
cb | Callback function in the form function(err, members) |
This function works just like getConversationMembers()
, but returns all members of a team instead of just the members of a
specific channel.
The teamId, when present, can be extracted from a message object at the Teams-specific field message.channelData.team.id
. This field is present in messages that occur in multi-user channels, but not in 1:1 messages and other events.
Note that since the team id is not always part of the incoming message payload, and because all multi-user channel contain all members
of the team, getConversationMembers()
is likely more reliable and easy to use.
controller.hears('roster','direct_mention', function(bot, message) {
bot.api.getTeamRoster(message.channelData.team.id, function(err, roster) {
if (err) {
bot.reply(message,'Error loading roster: ' + err);
} else {
var list = [];
for (var u = 0; u < roster.length; u++) {
list.push(roster[u].name);
}
bot.reply(message,'Team roster: ' + list.join(', '));
}
});
});
Parameter | Description |
---|---|
conversationId | Contains the identifier for the conversation in which the original message occured |
messageId | Contains the unique identifier of message to be replaced |
replacement | A message object which will be used to replace the previous message |
cb | Callback function in the form function(err, results) |
This method allows you to update an existing message with a replacement. This is super handy when responding to button click events, or updating a message with new information.
In order to update a message, you must first capture it's ID. The message id is part of the response passed back from bot.reply or bot.say.
updateMessage()
expects an API-ready message object - the replacement message does not undergo the
normal pre-send transformations that occur during a normal bot.reply or bot.say.
controller.hears('update', 'direct_message,direct_mention', function(bot, message) {
bot.reply(message,'This is the original message', function(err, outgoing_message) {
bot.api.updateMessage(message.channel, outgoing_message.id, {type: 'message', text: 'This message has UPDATED CONTENT'}, function(err) {
if (err) {
console.error(err);
}
});
});
})
Parameter | Description |
---|---|
teamId | The unique identifier for a given team |
cb | Callback function in the form function(err, channels) |
This function returns an array of all the channels in a given team.
The teamId, when present, can be extracted from a message object at the Teams-specific field message.channelData.team.id
. This field is present in messages that occur in multi-user channels, but not in 1:1 messages and other events.
controller.hears('channels','direct_mention', function(bot, message) {
bot.api.getChannels(message.channelData.team.id, function(err, roster) {
if (err) {
bot.reply(message,'Error loading channel list: ' + err);
} else {
var list = [];
for (var u = 0; u < roster.length; u++) {
list.push(bot.channelLink(roster[u]));
}
bot.reply(message,'Channels: ' + list.join(', '));
}
});
});
Parameter | Description |
---|---|
conversationId | Contains the unique identifier of a conversation |
message | The contents of your message |
cb | Callback function in the form function(err, results) |
This function is used to send messages to Teams. It is used internally by Botkit's
bot.say()
function, and is not intended to be used directly by developers.
Parameter | Description |
---|---|
options | an object containing {bot: id, members: [], channelData: {}} |
cb | Callback function in the form function(err, new_conversation_object) |
This function creates a new conversation context inside Teams.
This is used internally by Botkit inside functions like startPrivateConversation()
(to create the 1:1 channel between user and bot). It is not intended to be used directly by developers.
In addition to, or as an alternative to text, messages in Microsoft Teams can include one or more attachments. Attachments appear as interactive cards inside the Teams client, and can include elements such as images, text, structured data, and interactive buttons.
Read the official Teams documentation about message attachments
To use attachments with Botkit, construct an attachment object and add it to the message object. Botkit provides a few helper functions to make creating attachment objects easier.
Parameter | Description |
---|---|
title OR object | string value for the title of the card, OR an object representing all the fields in the card |
subtitle | string value for the subtitle of the card |
text | string value for the text of the card |
images | an array of image objects - {url: string, alt: string} - currently limited to 1 item |
buttons | an array of action objects - {type: string, title: string, value: string} |
tap action | a single of action object that defines the action to take when a user taps anywhere on the card - {type: string, title: string, value: string} |
(See usage notes below)
Parameter | Description |
---|---|
title OR object | string value for the title of the card, OR an object representing all the fields in the card |
subtitle | string value for the subtitle of the card |
text | string value for the text of the card |
images | an array of image objects - {url: string, alt: string} - currently limited to 1 item |
buttons | an array of action objects - {type: string, title: string, value: string} |
tap action | a single of action object that defines the action to take when a user taps anywhere on the card - {type: string, title: string, value: string} |
The attachment building helper functions bot.createHero()
and bot.createThumbnail()
can be used to
quickly create attachment objects for inclusion in a message.
The return value of these functions is an attachment object that can be directly added to the outgoing message object's attachments
array.
In addition, the returned attachment object has a few helper methods of its that allow developers to adjust the values:
Parameter | Description |
---|---|
value | new value for the title field |
Parameter | Description |
---|---|
value | new value for the subtitle field |
Parameter | Description |
---|---|
value | new value for the text field |
Parameter | Description |
---|---|
url | url to image |
alt | alt description for image |
Parameter | Description |
---|---|
type OR button object | type of button OR an button object {type: string, title: string, value: string} |
title | string value for the button title |
value | string for the object payload. |
Parameter | Description |
---|---|
type OR button object | new value for the title field |
title | string value for the action title |
value | string for the object payload. |
Returns the stringified version of the attachment object
These functions can be used in a few different ways:
Create attachment with individual parameters:
var reply = {
text: 'Here is an attachment!',
attachments: [],
}
var attachment = bot.createHero('Title','subtitle','text',[{url:'http://placeimg.com/1900/600'}],[{type:'imBack','title':'Got it','value':'acknowledged'}],{type:'openUrl',value:'http://mywebsite.com'});
reply.attachments.push(attachment);
Create attachment with pre-defined object:
var reply = {
text: 'Here is an attachment!',
attachments: [],
}
var attachment = bot.createHero({
title: 'My title',
subtitle: 'My subtitle',
text: 'My text',
});
reply.attachments.push(attachment);
Create attachment with helper methods:
var reply = {
text: 'Here is an attachment!',
attachments: [],
}
var attachment = bot.createHero();
attachment.title('This is the title');
attachment.text('I am putting some text into a hero card');
attachment.button('imBack','Click Me','I clicked a button!');
attachment.button('openUrl','Link Me','http://website.com');
attachment.button('invoke','Trigger Event',JSON.stringify({'key':'value'}));
reply.attachments.push(attachment);
When sending multiple attachments, you may want to specify the attachmentLayout
attribute
of the message object. Setting attachmentLayout
to carousel
will cause attachments
to be displayed as a carousel, while the default behavior is to use a list layout.
controller.hears('hero', 'direct_mention, direct_message', function(bot, message) {
// this is a sample message object with an attached hero card
var reply = {
"text": "Here is a hero card:",
"attachments": [
{
"contentType": "application/vnd.microsoft.card.hero",
"content": {
"title": "Hero card title",
"subtitle": "Hero card subtitle",
"text": "The text of my hero card"
"images": [
{
"url": "http://placeimg.com/1600/900",
"alt": "An image from placeimg.com"
}
],
}
}
]
};
bot.reply(message,reply);
});
controller.hears('thumbnail', 'direct_mention, direct_message', function(bot, message) {
// this is a sample message object with an attached hero card
var reply = {
"text": "Here is a thumbnail card:",
"attachments": [
{
"contentType": "application/vnd.microsoft.card.thumbnail",
"content": {
"title": "Thumbnail title",
"subtitle": "Thumbnail subtitle",
"text": "The text of my Thumbnail card"
"images": [
{
"url": "http://placeimg.com/900/900",
"alt": "A nice square image from placeimg.com"
}
],
}
}
]
};
bot.reply(message,reply);
});
controller.hears('image', 'direct_mention, direct_message', function(bot, message) {
// this is a sample message object with an attached hero card
var reply = {
"text": "Check out this attached image!",
"attachments": [
{
"contentType": "image/png",
"contentUrl": "http://mywebsite.com/image.png",
}
]
};
bot.reply(message,reply);
});
TODO
Buttons can be included in attachments. There are several types of button that result in different actions.
openUrl
buttons cause a browser to open to a specific web urlinvoke
buttons cause a message to be sent back to your bot applicationimBack
buttons cause the user to "say" something back to the botmessageBack
buttons cause the user to "say" something back to your bot, while displaying a different message for other users to see.
Note that is possible to send an attachment that is empty except for buttons - this can be useful!
To use buttons, build them with the attachment helpers, or construct them in code and include them in your attachment objects, as seen in the examples below:
controller.hears('invoke button', function(bot, message) {
var reply =
{
text: 'This message has an invoke button',
attachments: [
{
"contentType": "application/vnd.microsoft.card.hero",
"content": {
// other card fields here, see above
// title: '...',
// subtitle: '...',
// ...
"buttons": [
{
"type": "invoke",
"title": "Click Me",
"value": "{\"action\":\"click\"}"
}
]
}
]
};
bot.reply(messge, reply);
});
controller.hears('imback button', function(bot, message) {
var reply =
{
text: 'This message has an imBack button',
attachments: [
{
"contentType": "application/vnd.microsoft.card.hero",
"content": {
// other card fields here, see above
// title: '...',
// subtitle: '...',
// ...
"buttons": [
{
"type": "imBack",
"title": "Hello!",
"value": "hello"
}
]
}
]
};
bot.reply(messge, reply);
});
controller.hears('openurl button', function(bot, message) {
var reply =
{
text: 'This message has an openUrl button',
attachments: [
{
"contentType": "application/vnd.microsoft.card.hero",
"content": {
// other card fields here, see above
// title: '...',
// subtitle: '...',
// ...
"buttons": [
{
"type": "openUrl",
"title": "Open Link",
"value": "http://mywebsite.com"
}
]
}
]
};
bot.reply(messge, reply);
});
In addition to buttons, developers can add a "tap action" to a card which will be triggered when a user clicks on any part of the card - sort of like a default action.
Tap actions are defined using the same options as buttons - a card action object
set in the message.tap
field:
var attachment = {
"contentType": "application/vnd.microsoft.card.hero",
"content": {
"title": "Hero card title",
"subtitle": "Hero card subtitle",
"text": "The text of my hero card"
"images": [
{
"url": "http://placeimg.com/1600/900",
"alt": "An image from placeimg.com"
}
],
"tap": {
"type": "imBack",
"value": "That tickles!"
}
}
}
Botkit translates button clicks into invoke
events. To respond to button click events, create one or more handlers for the invoke event.
The message object passed in with the invoke event has a value
field which will match the value
specified when the button was created.
Invoke events can be replied to, or used to start conversations, just like normal message events.
controller.on('invoke', function(bot, message) {
// value is a user-defined object
var value = message.value;
// send a reply to the user
bot.reply(messge,'You clicked a button!');
});
Your bot can @mention another user in a message, which causes their username to be highlighted and a special notification to be sent. Teams mentions are slightly more complex than some other platforms, and require not only a special syntax in the message itself, but also additional fields in the message object. See Microsoft's full docs for user mentions here.
A native Teams user mention requires BOTH:
- The
message.text
field includes the mention in the format "@User Name" - The
message.entities
field includes an array element further defining the mention with the user's name and user ID.
This makes life a bit tricky, because the user name is not part of the incoming message, and requires additional API or DB calls to retrieve. Maintaining the entities field is also annoying!
To make life easier for developers, Botkit supports an easier to use syntax by providing a translation middleware.
This allows developers to create mentions by including a modified mention syntax in the message text only, without having to also
specify the entity field. Botkit uses a "Slack-style" mention syntax: <@USERID>
.
Using this syntax, developers can create inline mentions in response to incoming messages with much less effort:
controller.hears('mention me', function(bot, message) {
bot.reply(message,'I heard you, <@' + message.user +'>!');
});
One of the unique features of Microsoft Teams is support for "compose extensions" - custom UI elements that appear adjacent to the "compose" bar in the Teams client that allow users to create cards of their own using your bot application.
With a compose extension, you can offer users a way to search or create content in your application which is then attached to their message. Compose extensions can live in both multi-user team chats, as well as 1:1 discussions with the bot. They work sort of like web forms - as a user types a query, the compose extension API retrieves results from the application and displays them in the teams UI. When a result is selected, a custom app-defined card is attached to the user's outgoing message. Compose extensions use the same attachment format as normal messages.
To enable a compose extension in your bot app, you must first add a configuration section to your app's manifest file. Luckily, Botkit Studio has a tool for building these manifests. Using it will make your life much easier!
Once configured, whenever a user uses your compose extension, your Botkit application will receive a composeExtension
event. Botkit automatically
makes the user's query available in the message.text
field, and provides a bot.replyToComposeExtension()
function for formatting and delivering the results to Teams.
replyToComposeExtension()
expects the response to be an array of attachments.
controller.on('composeExtension', function(bot, message) {
var query = message.text;
my_custom_search(query).then(function(results) {
// let's format the results an array of hero card attachments
var attachments = [];
for (var r = 0; r < results.length; r++) {
var attachment = bot.createHero(results.title, results.subtitle, results.text);
attachments.push(attachment);
}
// you can use the normal bot.reply function to send back the compose results!
bot.replyToComposeExtension(message, results);
});
});
Tab applications provide the ability to display web content directly in the Teams UI. There are a few different types of tab, and applications can contain multiple tabs. Microsoft has extensive documentation about building tab applications, but the short story is: your bot can include an integrated web app component that interacts with Teams in some neat ways. Microsoft provides an easy to use Javascript library that is used to set tab configuration options, and provide information about the user, team, and channels in which the tab is installed.
Tabs are configured in the manifest.json as part of your app package. Read up on that, or use Botkit Studio to build this file.
The Botkit Starter Kit for Microsoft Teams contains a complete tab application, and demonstrates the interplay between the tab and bot components. This is a great starting point, and gives you all pieces you'd otherwise have to build yourself.
The relevant information about building tabs in a Botkit application are:
- Adding new web endpoints for serving the tab application
- Linking the bot user to the tab user in order to share data
When using the built-in webserver, developers
can add web endpoints to the built in Express webserver inside the setupWebserver()
callback function.
Tabs serve normal webpages, and can live at whatever URI you specify - as long as it matches
the settings in the manifest file.
controller.setupWebserver(3000, function(err, webserver) {
// set up the normal webhooks to receive messages from teams
controller.createWebhookEndpoints(webserver, function() {
console.log("BOTKIT: Webhooks set up!");
});
// create a custom static tab url
webserver.get('/static-tab', function(req, res) {
res.send('This is my static tab url!')
});
});
When using the starter kit, tab urls can be added in the components/routes/teams_tabs.js folder.
Using the Microsoft Teams Javascript library, developers can get access to the active user's "upn" - a user ID that identifies the user in the broader context of Microsoft Office 365.
This is a different user ID than the one used inside Teams chat . A little bit of extra work is necessary to connect the dots between these different account identifiers.
Botkit provides a method, bot.api.getUserByUpn(), that can be used to translate the upn value from the tab
into user id expected by Teams chat. It is also possible to translate a message.user
field into a upn by using bot.api.getUserById(),
the results of which include the upn value.
For these reasons, we recommend using a user's upn
value as the primary key when storing information about a user.
The following example demonstrates using getUserById()
to load a user's upn, then use the upn to load data from
Botkit's built-in storage system. Using the storage system in this way will allow data stored in it to be used by both
the bot and the tab application.
The starter kit implements this automatically using a middleware that automatically translates the user ID into a UPN and pre-loads the user data before firing any handlers. This is a good reference for any customized solution.
controller.hears('save', 'direct_message', function(bot, message) {
var value = 'special value';
// use the microsoft teams API to load user data
bot.api.getUserById(message.channel, message.user, function(err, user_profile) {
// check errors
var upn = user_profile.userPrincipalName;
controller.storage.users.get(upn, function(err, user_data) {
// check errors
// if no user found, create a new record with upn as primary id
if (!user_data) {
user_data = {
id: upn
}
}
// update with new value
user_data.value = value;
// store the user
controller.storage.users.save(user_data);
// send a reply
bot.reply(message,'Saved');
});
});
});
Complete documentation for Botkit can be found on our GitHub page. Botkit Studio users can access the Botkit Studio Knowledge Base for help in managing their Studio integration.
Botkit is made possible with feedback and contributions from the community. A full guide to submitting code, reporting bugs, or asking questions on Github can be found here
- Join our thriving community of Botkit developers and bot enthusiasts at large. Over 4500 members strong, our open Slack group is the place for people interested in the art and science of making bots.
Come to ask questions, share your progress, and commune with your peers!
- We also host a regular meet-up called TALKABOT. Come meet, present, and learn from other bot developers!
Full video of our 2016 conference is available on our Youtube channel.
Botkit is a product of Howdy and made in Austin, TX with the help of a worldwide community of botheads.
- Get Started
- Botkit Studio API
- Function index
- Extending Botkit with Plugins and Middleware
- Storing Information
- Logging
- Platforms
- Contributing to Botkit