Navigation
If you have a bot built using the JS BotFramework SDK, the following will help you update your bot to the Teams AI library.
Since the library builds on top of the BF SDK, much of the bot logic can be directly carried over to the Teams AI app. If you want to start with a new project, set up the Echo bot sample in the quick start guide and jump directly to step 2.
If you want to migrate your existing app start with step 1.
Replace ActivityHandler
with Application
.
+ import { Application, TurnState } from "@microsoft/teams-ai";
- const app = BotActivityHandler();
// Define storage and application
+ const storage = new MemoryStorage();
+ const app = new Application<TurnState>({
storage
});
You may also use the ApplicationBuilder
class to build your Application
. This option provides greater readability and separates the management of the various configuration options (e.g., storage, turn state, AI options, etc).
//// Constructor initialization method
// const app = new Application<TurnState>()
// {
// storage
// };
// Build pattern method
const app = new ApplicationBuilder<TurnState>()
.withStorage(storage)
.build(); // this internally calls the Application constructor
The BotActivityHandler
class derives from the ActivityHandler
class. Each method in the class corresponds to a specific route registration method (handler
) in the Application
object. Here's a simple example:
Given the BotActivityHandler
implementation:
class BotActivityHandler extends ActivityHandler {
constructor() {
this.onMessage(async (context, next) => {
const replyText = `Echo: ${context.activity.text}`;
await context.sendActivity(MessageFactory.text(replyText, replyText));
await next();
});
}
}
This is how a route should be added to the Application
object:
app.activity(ActivityTypes.Message, async (context: TurnContext, state: TurnState) => {
const replyText = `Echo: ${context.activity.text}`;
await context.sendActivity(replyText);
});
The
activity
method is refered as a route registration method. For each method in theActivityHandler
orTeamsActivityHandler
class, there is an equivalent route registration method.
Your existing BF app will probably have different activity handlers implemented. To migrate that over with Teams AI route registration methods see the following.
If your bot derives from the TeamsActivityHandler
refer to the following table to see which method maps to which Application
route registration method.
TeamsActivityHandler method |
Application route registration method |
---|---|
handleTeamsO365ConnectorCardAction |
O365ConnectorCardAction (usage: app.O365ConnectorCardAction(...) ) |
handleTeamsFileConsent |
Either fileConsentAccept or fileConsentDecline |
handleTeamsTaskModuleFetch |
taskModules.fetch (usage: app.taskModules.Fetch(...) ) |
handleTeamsTaskModuleSubmit |
taskModules.submit |
handleTeamsConfigFetch |
taskModules.configFetch |
handleTeamsConfigSubmit |
taskModules.configSubmit |
handleTeamsAppBasedLinkQuery |
messageExtensions.queryLink (usage: app.MessageExtensions.queryLink(...) ) |
handleTeamsAnonymousAppBasedLinkQuery |
messageExtensions.anonymousQueryLink |
handleTeamsMessagingExtensionQuery |
messageExtensions.query |
handlehandleTeamsMessageExtensionSelectItem |
messageExtensions.selectItem |
handleTeamsMessagingExtensionSubmitActionDispatch |
messageExtensions.submitAction |
handleTeamsMessagingExtensionFetchTask |
messageExtensions.fetchTask |
handleTeamsMessagingExtensionConfigurationQuerySettingUrl |
messageExtensions.queryUrlSetting |
handleTeamsMessagingExtensionConfigurationSetting |
messageExtensions.configureSettings |
handleTeamsMessagingExtensionCardButtonClicked |
messageExtensions.handleOnButtonClicked |
handleTeamsSigninVerifyState |
N/A (you should use the built-in user authentication feature instead of handling this manually) |
handleTeamsSigninTokenExchange |
N/A (you should use the built-in user authentication feature instead of handling this manually) |
(Handoff) N/A | handoff (usage: app.handoff(...) ) |
(Feedback loop) N/A | feedbackLoop (usage: app.feedbackLoop(...) ) |
These are the following methods from the TeamsActivityHandler
with their corresponding ConversationUpdateEvent
:
onTeamsChannelCreated
| 'channelCreated'onTeamsChannelDeleted
| 'channelDeleted'onTeamsChannelRenamed
| 'channelRenamed'onTeamsTeamArchived
| 'teamArchived'onTeamsTeamDeleted
| 'teamDeleted'onTeamsTeamHardDeleted
| 'teamHardDeleted'onTeamsChannelRestored
| 'channelRestored'onTeamsTeamRenamed
| 'teamRenamed'onTeamsTeamRestored
| 'teamRestored'onTeamsTeamUnarchived
| 'teamUnarchived'onTeamsMembersAdded
| 'membersAdded'onTeamsMembersRemoved
| 'membersRemoved'
These activities can be handled using the Application.conversationUpdate
method.
For example in the TeamsActivityHandler
:
protected async onTeamsChannelCreated(context: TurnContext): Promise<void> {
// handle teams channel creation.
}
The Application
equivalent using ConversationUpdateEvent
:
app.conversationUpdate("channelCreated", (context: TurnContext, state: TurnState) => {
// handle teams channel creation.
});
Note that the first parameter
event
specifies which conversation update event to handle. It only accepts specific values that can be found through your IDE's intellisense.
TeamsActivityHandler method |
Application route registration method |
---|---|
OnMessage |
message |
OnTeamsMessageUndelete ,` |
messageEventUpdate , with the 'undeleteMessage' TeamsMessageEvent |
OnTeamsMessageEdit |
messageEventUpdate , with the 'editMessage' TeamsMessageEvent |
OnTeamsMessageSoftDelete |
messageEventUpdate , with the 'softDeleteMessage' TeamsMessageEvent |
OnMessageReactionActivity |
messageReactions , with 'reactionsAdded' or 'reactionsRemoved' MessageReactionEvents |
OnTeamsReadReciept |
teamsReadReceipt (no event name required) |
TeamsActivityHandler method |
Application route registration method |
---|---|
OnTeamsMeetingStart |
meetings.start |
OnTeamsMeetingEnd |
meetings.end |
onTeamsMeetingParticipantsJoin |
meetings.participantsJoin |
onTeamsMeetingParticipantsLeave |
meetings.participantsLeave |
If there are activities for which there isn't a corresponding route registration method, you can use the generic route registration method Application.activity
and specify a custom selector function given the activity object as input.