Skip to content

Latest commit

 

History

History
 
 
page_type products languages description urlFragment extensions
sample
office-teams
office
office-365
typescript
nodejs
A task module allows you to create modal popup experiences in your Teams application.
teams-module-node
contentType createdDate
samples
9/17/2018 6:53:22 PM

Microsoft Teams task module - Node.js/TypeScript sample

A task module allows you to create modal popup experiences in your Teams application. Inside the popup, you can run your own custom HTML/JavaScript code, show an <iframe>-based widget such as a YouTube or Microsoft Stream video, or display an Adaptive card.

Task modules build on the foundation of Microsoft Teams tabs: a task module is essentially a tab in a popup window. It uses the same SDK, so if you've built a tab you are already 90% of the way to being able to create a task module.

Try it yourself

This sample is deployed on Microsoft Azure and you can try it yourself by uploading TaskModule.zip to one of your teams and/or as a personal app. (Sideloading must be enabled for your tenant; see step 6 here.) The app is running on the free Azure tier, so it may take a while to load if you haven't used it recently and it goes back to sleep quickly if it's not being used, but once it's loaded it's pretty snappy.

Overview of this sample

This sample app was developed in conjunction with the task module feature itself to exercise as much of it as possible. Here's what's included:

  • A channel tab. Add the app to a team, then add a Task Module tab and choose "Task Module Demo" from the dropdown list.
  • A bot. Add the app to a team, then chat with it (@Task Module)
  • A personal app. When you upload the TaskModule.zip file, choose "Add for you" and "Task Module" will appear in the "..." menu in the Teams app bar. The personal app has both a tab and a bot.

The tab shows how to invoke the task module using the Teams SDK. Source code for the tab is found in TaskModuleTab.ts; the view definition is in taskmodule.pug. This sample app uses Pug (formerly Jade) for HTML rendering.

The following task modules are supported:

The sample app also contains a bot with cards allowing you to invoke these task modules. You can invoke them from an Adaptive card (using the tasks command) or from a Bot Framework thumbnail card (using the bfcard command). RootDialog.ts contains the code for the tasks and bfcard commands, and TeamsBot.ts contains the code for responding to task/fetch and task/submit messages. The task modules when invoked from a bot are the same as for the tab, except for the Adaptive card examples:

  • Adaptive Card - Single returns the results to the conversation as a message.
  • Adaptive Card - Sequence shows how adaptive cards can be chained together: instead of returning the result to the chat, the result is shown in another Adaptive card.

Implementation notes

  • This sample is data-driven as much as possible and shares as much code as possible between the bot and the tabs forms of task module:
  • The logic for handling task/fetch messages is also data-driven, shared across card types (Adaptive and Bot Framework), and supports chaining of Adaptive card task modules. The data-driven approach for card generation combined with the fact that the Adaptive and Bot Framework card schemas are quite different unfortunately means that the way it works is not obvious. Here's how it works:
    • All the task/fetch and task/submit requests and responses are JavaScript objects defined in the fetchTemplates[] collection in CardTemplates.ts and generated in TeamsBot.ts in the onInvoke() function.
    • The custom properties data.taskModule (for Adaptive card Action.Submit buttons) and value.taskModule (for Bot Framework card actions) are used as lookup values to select a specific response from the fetchTemplates[] collection when a task/fetch message is received.
    • Adaptive card chaining — showing multiple adaptive cards in a sequence — is implemented using the data.taskResponse property on an Adaptive card Action.Submit button. With Adaptive Card - Single, the card is rendered with data.taskResponse set to "message" (show a message to the user); for Adaptive Card - Sequence, the same Adaptive card is rendered with data.taskResponse set to "continue" (show another Adaptive card). This is the only difference between fetchTemplates.adaptivecard1 and fetchTemplates.adaptivecard2. The second Adaptive card (cardTemplates.acSubmitResponse in CardTemplates.ts) in the sequence just shows the JSON submitted in the first; its data.taskResponse is set to "final". The logic for handling the various values of data.taskResponse is in TeamsBot.ts. The taskResponse values form a simple "protocol" for responding to the different ways to respond to task/submit messages: do nothing (complete), show a message to the user, load a subsequent adaptive card in a sequence, or load the final adaptive card in a sequence.
  • To avoid hardcoding an appId in customform.pug, the appId is passed in at Pug template rendering time by tabs.ts, the TypeScript which implements the tab routes.
  • Theming and simple keyboard handling for the Esc key are supported.

Bonus features

There's also an actester bot command. It's a handy way of seeing what an Adaptive card looks like in Teams - simply copy/paste the JSON of Adaptive cards, e.g. the Samples page on the Adaptive card site, and the bot will render it as a reply.

Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com.

When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.