Overview

Task modules enable us to implement modal popup experiences in MS Teams applications. In this article, we will create task modules in a custom Microsoft Teams app using Yo Teams.

Task Modules overview

Task modules help to implement popup in MS Teams applications. Inside the popup you can run any of the below,
  • Custom HTML and JavaScript code
  • Iframe based widgets
  • Adaptive cards
From the MS Teams' point of view, task modules can be considered as a tab inside a popup. The task modules can be invoked from any of the below,
  • Channel and personal tab: Any button or link can invoke a task module by opening a popup.
  • Bot: Button on cards sent from the bot can invoke a task module.
  • Deeplink: You can compose a deeplink to invoke a task module.
Prerequisites
Install below to get started,
  • Node.js - v10.* or higher
  • NPM (gets installed with Node.js) - v6.* or higher
  • Gulp - v4.* or higher
  • Yeoman - v3.* or higher
  • Yeoman Generator for Microsoft Teams - v2.13.0 or higher
  • Visual Studio Code
Install Yeoman, Gulp, and Typescript compiler globally with NPM.
  1. npm install yo gulp-cli typescript -g
Install generator-teams globally with NPM.
  1. npm install generator-teams -g
If you wish to install preview version of the generator, use the below command.
  1. npm install generator-teams@preview --g

Implement task modules with Yo Teams

Let us generate a solution with Yo Teams.
On the command prompt, type the below command.
  1. yo teams
Follow the wizard to set up the solution.
Develop Task Modules For MS Teams With Yo Teams
On the command prompt, type code . to open the solution in visual studio code.

Use the latest version of Teams manifest and SDK

Run the below command to ensure the project is using the latest version of Teams manifest & SDK.
  1. npm i @microsoft/teams-js
Modifications to manifest.json
Under the manifest folder, open the manifest.json file and make the below changes,
  • Change the $schema property to https://developer.microsoft.com/en-us/json-schemas/teams/v1.7/MicrosoftTeams.schema.json
  • Change the manifestVersion property to 1.7.
Modifications to gulp.config.js
Under the root folder, open the gulp.config.js file and make below changes,
Add the following to the SCHEMAS property.
  1. {
  2. version: "1.7",
  3. schema: "https://developer.microsoft.com/en-us/json-schemas/teams/v1.7/MicrosoftTeams.schema.json"
  4. }

Test the personal tab

Before customizing the tab, let us test it without any customizations applied.
From the command prompt, navigate to the root folder for the project and execute the below command:
  1. gulp ngrok-serve
Develop Task Modules For MS Teams With Yo Teams
Open a browser and navigate to the ngrok URL displayed in the console:
Develop Task Modules For MS Teams With Yo Teams
Update the URL in the browser to load the tab created from the scaffolding process.
Develop Task Modules For MS Teams With Yo Teams
Now, let us try to load the tab in MS Teams. In the browser, navigate to here.
Using the app bar navigation menu, select the More added apps button. Then select More apps.
Develop Task Modules For MS Teams With Yo Teams
Select Upload a custom app > Upload for me or my teams.
Upload the app package (a ZIP file) from the project's ./package folder.
Develop Task Modules For MS Teams With Yo Teams
Click Add.
Develop Task Modules For MS Teams With Yo Teams
The app will be displayed in MS Teams as below,
Develop Task Modules For MS Teams With Yo Teams

Adaptive Cards

Adaptive Cards are a cross-product specification for various Microsoft products including Bots, Outlook, Teams, and Windows. An Adaptive Card is represented as a JSON object. The JSON string defines all the controls, text, and actions that the hosting application will use to render the card.
Below is a JSON example of an Adaptive Card that contains an input box and a single submit button,
  1. {
  2. "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  3. "type": "AdaptiveCard",
  4. "version": "1.0",
  5. "body": [
  6. {
  7. "type": "Container",
  8. "items": [
  9. {
  10. "type": "TextBlock",
  11. "text": "YouTube Video Selector",
  12. "weight": "bolder",
  13. "size": "extraLarge"
  14. }
  15. ]
  16. },
  17. {
  18. "type": "Container",
  19. "items": [
  20. {
  21. "type": "TextBlock",
  22. "text": "Enter the ID of a YouTube video to show in the task module player.",
  23. "wrap": true
  24. },
  25. {
  26. "type": "Input.Text",
  27. "id": "youTubeVideoId",
  28. "value": ""
  29. }
  30. ]
  31. }
  32. ],
  33. "actions": [
  34. {
  35. "type": "Action.Submit",
  36. "title": "Update"
  37. }
  38. ]
  39. }
Add above json content by creating a file at src\app\scripts\youTubePlayerTab\YouTubeSelectorCard.json

Using Adaptive Cards in Microsoft Teams task modules

Once we have an Adaptive card ready, we will create a task module to display it and handle the submission action.
Open the file src\app\scripts\youTubePlayerTab\YouTubePlayerTab.tsx
Update the render method as below,
  1. public render() {
  2. return (
  3. <Provider theme={this.state.theme}>
  4. <Flex column gap="gap.smaller">
  5. <Header>Task Module Demo</Header>
  6. <Text>YouTube Video ID:</Text>
  7. <Input value={this.state.youTubeVideoId} disabled></Input>
  8. <Button content="Change Video ID (AdaptiveCard)" onClick={this.onChangeVideoAdaptiveCard}></Button>
  9. <Button content="Show Video" primary onClick={this.onShowVideo}></Button>
  10. <Text content="(C) Copyright Contoso" size="smallest"></Text>
  11. </Flex>
  12. </Provider>
  13. );
  14. }
Implement onChangeVideoAdaptiveCard method as below,
  1. private onChangeVideoAdaptiveCard = (event: React.MouseEvent<HTMLButtonElement>): void => {
  2. // load adaptive card
  3. const adaptiveCard: any = require("./YouTubeSelectorCard.json");
  4. // update card with current video ID
  5. adaptiveCard.body.forEach((container: any) => {
  6. if (container.type === "Container") {
  7. container.items.forEach((item: any) => {
  8. if (item.id && item.id === "youTubeVideoId") {
  9. item.value = this.state.youTubeVideoId;
  10. }
  11. });
  12. }
  13. });
  14. const taskModuleInfo = {
  15. title: "YouTube Video Selector",
  16. card: adaptiveCard,
  17. width: 350,
  18. height: 250
  19. };
  20. const submitHandler = (err: string, result: any): void => {
  21. this.setState(Object.assign({}, this.state, {
  22. youTubeVideoId: result.youTubeVideoId
  23. }));
  24. };
  25. microsoftTeams.tasks.startTask(taskModuleInfo, submitHandler);
  26. }
Implement onShowVideo method as below,
  1. private onShowVideo = (event: React.MouseEvent<HTMLButtonElement>): void => {
  2. const taskModuleInfo = {
  3. title: "YouTube Player",
  4. url: this.appRoot() + `/youTubePlayerTab/player.html?vid=${this.state.youTubeVideoId}`,
  5. width: 1000,
  6. height: 700
  7. };
  8. microsoftTeams.tasks.startTask(taskModuleInfo);
  9. }
  10. private appRoot(): string {
  11. if (typeof window === "undefined") {
  12. return "https://{{HOSTNAME}}";
  13. } else {
  14. return window.location.protocol + "//" + window.location.host;
  15. }
  16. }
Test the solution
On the command prompt, type below command.
  1. gulp ngrok-serve
Develop Task Modules For MS Teams With Yo Teams

Summary

Task modules enable us to implement modal popup experiences in MS Teams applications. Yo Teams helps to build task modules with ease.
References
The code developed during this article can be found here.