Extending Teams
Extending Teams
App Studio is a Teams app which can be found in the Teams store. Follow this link for direct
download: https://aka.ms/InstallTeamsAppStudio (you can also find the app in the app store).
powershell
mkdir c:/LabFiles/Teams
powershell
cd c:/LabFiles/Teams
powershell
git clone https://github.com/OfficeDev/msteams-samples-hello-world-
csharp.git
powershell
cd c:/LabFiles/Teams/msteams-samples-hello-world-csharp
2. Open the folder in Visual Studio Code by executing the following from the project
directory: code .
3. If Visual Studio code displays a dialog box asking if you want to add required
assets to the project, select Yes.
4. From the Visual Studio Code ribbon, select Terminal > New Terminal.
2. In the app bar, select … More added apps and then select App Studio.
4. You should now see your imported app which you can now select to open.
Now you can modify your app manifest here in App Studio.
1. On the App details page update the following under the App names section:
o Short name: Change to First App
o Full name: Change to Learn Microsoft Teams App
3. Change the Version to 1.0.1.
o Locate the only personal tab in the project, and select … > Edit on that tab.
o Change the tab name to My First Tab.
Once you have the app manifest ready, you will need to download it and then manually upload
it to Teams.
NOTE: Any changes you make in App Studio aren't saved to your project. To update the
project, download the app package from App Studio. To download the project, in the App
Studio navigation pane select Finish > Test and distribute, and then select Download.
WARNING: Be careful if you choose to update the manifest.json file in your project with the
one in the package downloaded from App Studio. The manifest file in your project contains
placeholder strings that are updated by the build and debugging process.
For instance, the {{HOSTNAME}} placeholder is replaced with the app's hosting URL each time
the package is recreated. Because of this, it's not recommended to replace the
existing manifest.json file with the file generated by App Studio.
b. Browse and upload the updated zip package. Open the app and notice it’s
now reflecting the updates you made.
Task 3: Deploying SPFx web part to Microsoft Teams
powershell
mkdir c:/LabFiles/SharePoint
cd c:/LabFiles/SharePoint
3. Make a new directory for your SharePoint project files by executing the following
command:
md SPFxTeamsTab
cd SPFxTeamsTab
npm install -g @microsoft/generator-sharepoint
yo @microsoft/sharepoint
8. Use the following below to complete the prompts that are displayed:
o What is your solution name?: SPFxTeamsTab
o Which baseline packages do you want to target for your
component(s)?: SharePoint Online only (latest)
o Where do you want to place the files?: Use the current folder
o Do you want to allow the tenant admin the choice of being able to deploy
the solution to all sites immediately without running any feature deployment
or adding apps in sites?: Yes
o Will the components in the solution require permissions to access web
APIs that are unique and not shared with other components in the tenant?:
No
o Which type of client-side component to create?: WebPart
o What is your Web Part name?: SPFx Teams Together
o What is your Web Part description?: SPFx Teams Together description
o Which framework would you like to use?: No JavaScript framework
9. After provisioning the folders required for the project, the generator will install all
the dependency packages using NPM.
10. Open the project in Visual Studio Code
code .
"supportedHosts": ["SharePointWebPart"],
"supportedHosts": ["SharePointWebPart", "TeamsTab"],
json
{
"$schema": "https://developer.microsoft.com/json-
schemas/teams/v1.5/MicrosoftTeams.schema.json",
"manifestVersion": "1.5",
"packageName": "{{SPFX_COMPONENT_ALIAS}}",
"id": "{{SPFX_COMPONENT_ID}}",
"version": "0.1",
"developer": {
"name": "Parker Porcupine",
"websiteUrl": "https://contoso.com",
"privacyUrl": "https://contoso.com/privacystatement",
"termsOfUseUrl": "https://contoso.com/servicesagreement"
},
"name": {
"short": "{{SPFX_COMPONENT_NAME}}"
},
"description": {
"short": "{{SPFX_COMPONENT_SHORT_DESCRIPTION}}",
"full": "{{SPFX_COMPONENT_LONG_DESCRIPTION}}"
},
"icons": {
"outline": "{{SPFX_COMPONENT_ID}}_outline.png",
"color": "{{SPFX_COMPONENT_ID}}_color.png"
},
"accentColor": "#004578",
"staticTabs": [
{
"entityId": "com.contoso.personaltab.spfx",
"name": "My SPFx Personal Tab",
"contentUrl":
"https://{teamSiteDomain}/_layouts/15/TeamsLogon.aspx?
SPFX=true&dest=/_layouts/15/teamshostedapp.aspx%3Fteams%26personal
%26componentId={{SPFX_COMPONENT_ID}}%26forceLocale={locale}",
"scopes": [
"personal"
]
}
],
"configurableTabs": [
{
"configurationUrl": "https://{teamSiteDomain}
{teamSitePath}/_layouts/15/TeamsLogon.aspx?
SPFX=true&dest={teamSitePath}/_layouts/15/teamshostedapp.aspx
%3FopenPropertyPane=true%26teams%26componentId={{SPFX_COMPONENT_ID}}
%26forceLocale={locale}",
"canUpdateConfiguration": true,
"scopes": [
"team"
]
}
],
"validDomains": [
"*.login.microsoftonline.com",
"*.sharepoint.com",
"spoprod-a.akamaihd.net",
"resourceseng.blob.core.windows.net"
],
"webApplicationInfo": {
"resource": "https://{teamSiteDomain}",
"id": "00000003-0000-0ff1-ce00-000000000000"
}
}
2. Open the manifest.json file.
This file contains multiple strings that need to be updated to match the SPFx component.
The SPFx component properties are found in the web part manifest
file: ./src/webparts/spFxTeamsTogether/SpFxTeamsTogetherWebPart.manifest.json
Use the following table below to determine the values that should be replaced:
{{SPFX_COMPONENT_ALIAS}} alias
{{SPFX_COMPONENT_NAME}} preconfiguredEntries[0].title
{{SPFX_COMPONENT_SHORT_DESCRIPT preconfiguredEntries[0].descri
ION}} ption
{{SPFX_COMPONENT_LONG_DESCRIPTI preconfiguredEntries[0].descri
ON}} ption
{{SPFX_COMPONENT_ID}} id
NOTE: Make sure you
update {{SPFX_COMPONENT_ID}} in configurableTabs[0].configurationUrl. You will
likely have to scroll your editor to the right to see it. The tokens surrounded by single curly
braces (for example, {teamSiteDomain}) do not need to be replaced.
Make sure to zip just the contents and not the folder itself. This ZIP archive should contain
3 files at the root (2 images and the manifest.json)
1. Open the browser and navigate to your SharePoint Online Tenant-Scoped App
Catalog site.
2. Select the menu item Apps for SharePoint from the left navigation menu.
3. Build the project by opening a command prompt and changing to the root folder
of the project. Then execute the following command:
gulp build
4. Next, create a production bundle of the project by running the following command
on the command line from the root of the project:
gulp bundle --ship
gulp package-solution --ship
This will make the SPFx web part available to all site collections in the tenant,
including those that are behind a Microsoft Teams team.
a. Using the same browser where you are signed in to SharePoint Online,
navigate to https://teams.microsoft.com/. When prompted, load the web client.
b. If you do not have any teams in your tenant, you will be presented with a
dialog to create a team. If you are not prompted with a dialog, select Join or create a
team at the bottom of the list of teams.
2. Install the Microsoft Teams application as a new tab that will expose the SharePoint
Framework web part in Microsoft Teams:
b. Select the General channel.
3. Add a custom tab to the team using the SPFx web part:
d. Select the Microsoft Teams application ZIP file previously created. This is
the file that contains the manifest.json and two image files.
NOTE: After a moment, the application will appear next to your tenant name. You may
need to refresh the page for the app to appear if you are using the browser version of
Microsoft Teams.
7. The next dialog box will confirm the installation of the app. Select Save.
Congratulations!
These lessons show how you can get started quickly with the Microsoft Teams Toolkit for Visual
Studio Code.
NOTE: Due to a bug in the latest Microsoft Teams Toolkit for bot development, you will need
to install version 1.1.2.
1. Open Visual Studio Code and select Extensions on the left Activity Bar.
3. After the latest Microsoft Teams Toolkit is installed, click on the gear icon and
choose Install Another Version.
4. Select 1.1.2.
1. In Visual Studio Code, select Microsoft Teams on the left Activity Bar and
choose Create a new Teams app.
2. When prompted, sign in with your Microsoft 365 development account.
5. Check only the Personal tab option and select Finish at the bottom of the screen
to configure your project.
Once the toolkit configures your project, you will have the components to build a basic
personal tab for Teams. The project directories and files display in the Explorer area of Visual
Studio Code.
NOTE: The toolkit automatically creates scaffolding for you in the src directory based on the
capabilities you added during setup.
For example, if you create a tab during setup the App.js file in the src/components directory is
important because it handles the initialization and routing of your app. It calls the Microsoft
Teams SDK to establish communication between your app and Teams.
App ID
Your Teams app ID is needed to configure your app with App Studio.
1. Open Terminal in Visual Studio Code. From the Visual Studio Code ribbon
select Terminal > New Terminal.
This will build and start a local web server for you to test your app. The command will also
rebuild the application whenever you save a file in your project.
Once complete, there's a Compiled successfully! message in the terminal. Your app should now
be running on https://localhost:3000.
Now that you’ve tested your tab, it’s time to run your app inside Microsoft Teams.
2. To display your app content in Teams, specify that where your app is running
(localhost) is trustworthy:
a. Open a new tab in the same browser window (Google Chrome by default)
which opened after pressing F5.
If your Add button is grayed out, and you receive a warning This app is not from your
organization's app catalog, preventing installation of your Teams App, implement the
following process to insure your Tenant has a Sideloading Policy enabled.
Note that this setting may take a few minutes to become in-effect so you may need to close
your browser, wait 10 minutes, and then repeat from Task 3, Step 1 until your Add button is
enabled:
Access https://admin.teams.microsoft.com
Login as [email protected] with Password of w#!l4ivA5hM?.
In the left menu bar select Teams Apps and then Setup Policies.
Select Global (Org-wide default).
Switch the Upload custom apps toggle from Off to On.
Scroll down and then select Save at bottom of screen.
Review
Utilized Microsoft Teams Toolkit to creates scaffolding and reviewed the result.
Congratulations!
You have successfully completed this exercise. Click Next to advance to the next exercise.
Exercise 3: Creating and using task modules in Microsoft Teams
Task modules allow 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 https://docs.microsoft.com/en-us/adaptive-cards/.
To create a task module, you will need to create a Teams application for displaying Task
modules.
1. Open Visual Studio Code and select Extensions on the left Activity Bar.
typescript
showCardBasedTaskModule() {
let cardJson = {
contentType: "application/vnd.microsoft.card.adaptive",
content: {
type: "AdaptiveCard",
body: [
{
type: "TextBlock",
text: "Here is a ninja cat:",
},
{
type: "Image",
url: "https://adaptivecards.io/content/cats/1.png",
size: "Medium",
},
],
version: "1.0",
},
};
let taskInfo = {
title: null,
height: 510,
width: 430,
url: null,
card: cardJson,
fallbackUrl: null,
completionBotId: null,
};
typescript
render() {
return (
<div>
<button
onClick={this.showCardBasedTaskModule}>ShowCard</button>
</div>
);
}
Now, a card-based task module has been added to the Teams Tab app.
typescript
const TaskModuleIds = {
YouTube: 'YouTube',
AdaptiveCard: 'AdaptiveCard'
};
module.exports.TaskModuleIds = TaskModuleIds;
typescript
class TaskModuleResponseFactory {
static createResponse(taskModuleInfoOrString) {
if (typeof taskModuleInfoOrString === 'string') {
return {
task: {
type: 'message',
value: taskModuleInfoOrString
}
};
}
return {
task: {
type: 'continue',
value: taskModuleInfoOrString
}
};
}
static toTaskModuleResponse(taskInfo) {
return TaskModuleResponseFactory.createResponse(taskInfo);
}
}
module.exports.TaskModuleResponseFactory = TaskModuleResponseFactory;
typescript
const { UISettings } = require('./uisettings');
const { TaskModuleIds } = require('./taskmoduleids');
const TaskModuleUIConstants = {
YouTube: new UISettings(1000, 700, 'YouTube Video',
TaskModuleIds.YouTube, 'YouTube'),
AdaptiveCard: new UISettings(400, 200, 'Adaptive Card: Inputs',
TaskModuleIds.AdaptiveCard, 'Adaptive Card')
};
module.exports.TaskModuleUIConstants = TaskModuleUIConstants;
typescript
class UISettings {
constructor(width, height, title, id, buttonTitle) {
this.width = width;
this.height = height;
this.title = title;
this.id = id;
this.buttonTitle = buttonTitle;
}
}
module.exports.UISettings = UISettings;
5. Open index.js in the service folder, and then add the following code to the end
of the file.
typescript
server.use(express.static('pages'));
typescript
const {
MessageFactory,
TeamsActivityHandler,
CardFactory,
} = require('botbuilder');
const { TaskModuleUIConstants } =
require('./models/TaskModuleUIConstants');
const { TaskModuleIds } = require('./models/taskmoduleids');
const { TaskModuleResponseFactory } =
require('./models/taskmoduleresponsefactory');
const Actions = [
TaskModuleUIConstants.AdaptiveCard,
TaskModuleUIConstants.YouTube
];
handleTeamsTaskModuleFetch(context, taskModuleRequest) {
// Called when the user selects an options from the displayed
HeroCard or
// AdaptiveCard. The result is the action to perform.
return TaskModuleResponseFactory.toTaskModuleResponse(taskInfo);
}
// Return TaskModuleResponse
return {
// TaskModuleMessageResponse
task: {
type: 'message',
value: 'Thanks!'
}
};
}
setTaskInfo(taskInfo, uiSettings) {
taskInfo.height = uiSettings.height;
taskInfo.width = uiSettings.width;
taskInfo.title = uiSettings.title;
}
getTaskModuleAdaptiveCardOptions() {
const adaptiveCard = {
$schema: 'http://adaptivecards.io/schemas/adaptive-
card.json',
version: '1.0',
type: 'AdaptiveCard',
body: [
{
type: 'TextBlock',
text: 'Task Module Invocation from Adaptive Card',
weight: 'bolder',
size: 3
}
],
actions: Actions.map((cardType) => {
return {
type: 'Action.Submit',
title: cardType.buttonTitle,
data: { msteams: { type: 'task/fetch' }, data:
cardType.id }
};
})
};
return CardFactory.adaptiveCard(adaptiveCard);
}
createAdaptiveCardAttachment() {
return CardFactory.adaptiveCard({
version: '1.0.0',
type: 'AdaptiveCard',
body: [
{
type: 'TextBlock',
text: 'Enter Text Here'
},
{
type: 'Input.Text',
id: 'usertext',
placeholder: 'add some text and submit',
IsMultiline: true
}
],
actions: [
{
type: 'Action.Submit',
title: 'Submit'
}
]
});
}
}
module.exports.BotActivityHandler = BotActivityHandler;
1. Open Terminal in Visual Studio Code. From the Visual Studio Code ribbon
select Terminal > New Terminal.
3. Run npm install to install all dependent packages for the Teams tab.
7. Go back to Teams. In the dialog, select Add for me to install your app.
9. Go back to the Visual Studio Code project. Stop the running project by
selecting Ctrl + C.
powershell
ngrok http -host-header=rewrite 3978
This will start ngrok and will tunnel requests from an external ngrok url to your
development machine on port 3978. Copy the https forwarding address. In the example
below that would be https://787b8292.ngrok.io. You will need this later.
3. Run npm install to install all dependent packages for the Teams tab.
8. In App Studio, select the Manifest editor tab, then select the app you just
installed.
10. For the Messaging endpoint URL, use the current https URL you were given
by running ngrok and append it with the path /api/messages. It should look similar
to https://{subdomain}.ngrok.io/api/messages
11. In the app bar, select … More added apps and then select your just installed
app.
12. Type Hello in chat to invoke the task module you just created from the Bot.
Review
In this exercise, you learned how to use task modules to create modal popup experiences in
your Teams application.
Congratulations!
You have successfully completed this exercise. Click Next to advance to the next exercise.
Webhooks can be used to connect web services to channels and teams in Teams.
5. Provide a name. Optionally, upload an image avatar for your webhook and then
click Create.
6. The dialog window will present a unique URL that will map to the
channel. Copy and save the URL—you will need to provide it to the outside service.
powershell
Invoke-RestMethod -Method post -ContentType 'Application/Json' -Body
'{"text":"Hello World!"}' -Uri <YOUR WEBHOOK URL>
2. If the POST succeeds, you should see a simple displayed output by Invoke-
RestMethod.
3. Check the Microsoft Teams channel associated with the webhook URL. You
should see the new card posted to the channel.
Review
In this exercise, you:
Congratulations!
You have successfully completed this exercise. Click Next to advance to the next exercise.
1. In Visual Studio Code, select Microsoft Teams on the left Activity Bar and
choose Create a new Teams app.
2. When prompted, sign in with your Microsoft 365 development account.
1. Open Terminal in Visual Studio Code. From the Visual Studio Code ribbon
select Terminal > New Terminal.
2. Go to the root directory of your app project and run npm install.
3. Run npm start.
2. To display your app content in Teams, specify that where your app is running
(localhost) is trustworthy:
3. Go back to Teams. In the dialog, select Add for me to install your app.
4. Please keep running this app in order to complete the next task.
html
<div>
<h1>Important Contacts</h1>
<ul>
<li>Help Desk: <a
href="mailto:[email protected]">[email protected]</a></li>
<li>Human Resources: <a
href="mailto:[email protected]">[email protected]</a></li>
<li>Facilities: <a
href="mailto:[email protected]">[email protected]</a></li>
</ul>
</div>
2. Add the following rule to App.css so the email links are easier to read no matter
which theme is used.
css
a {
color: inherit;
}
3. Save your changes. Go to your app's tab in Teams to view the new content.
Good apps feel native to Teams, so it's important your tab blends with the Teams theme
your users prefer: default (light), dark, or high contrast. As you might have noticed in the
last screenshot, your tab still has a light background when the client's using the dark theme.
This is not a recommended user experience.
1. Open tab.js with Visual Studio Code, and then insert the following theme
change handler immediately after the microsoftTeams.getContext() call.
typescript
microsoftTeams.registerOnThemeChangeHandler(theme => {
if (theme !== this.state.theme) {
this.setState({ theme });
}
});
let newTheme;
return (
<div style={newTheme}>
<h1>Important Contacts</h1>
<ul>
<li>Help Desk: <a
href="mailto:[email protected]">[email protected]</a></li>
<li>Human Resources: <a
href="mailto:[email protected]">[email protected]</a></li>
<li>Facilities: <a
href="mailto:[email protected]">[email protected]</a></li>
</ul>
</div>
);
}
1. Check your tab in Teams. The appearance should closely match the dark theme.
Well done! You have a Teams app with a personal tab that makes it easier to find important
contacts in your organization.
1. In Visual Studio Code, select Microsoft Teams on the left Activity Bar and
choose Create a new Teams app.
2. When prompted, sign in with your Microsoft 365 development account.
html
<div>
<h1>Important Contacts</h1>
<ul>
<li>Help Desk: <a
href="mailto:[email protected]">[email protected]</a></li>
<li>Human Resources: <a
href="mailto:[email protected]">[email protected]</a></li>
<li>Facilities: <a
href="mailto:[email protected]">[email protected]</a></li>
</ul>
</div>
2. Add the following rule to App.css so the email links are easier to read no matter
which theme is used.
css
a {
color: inherit;
}
javascript
<div>
<h1>Add My Contoso Contacts</h1>
<div>
Select <b>Save</b> to add our organization''s important contacts
to this workspace.
</div>
</div>
javascript
microsoftTeams.settings.setSettings({
"contentUrl": "https://localhost:3000/tab",
"suggestedDisplayName": "Team Contacts"
});
1. Open Terminal in Visual Studio Code. From the Visual Studio Code ribbon
select Terminal > New Terminal.
3. Run npm start.
2. To display your app content in Teams, specify that where your app is running
(localhost) is trustworthy:
Well done! You have a Teams app with a tab for displaying useful content in channels and
chats.
Review
In this exercise, you:
Congratulations!
You have successfully completed this exercise. Click Next to advance to the next exercise.
Messaging extensions allow users to interact with your web service through buttons and
forms in the Microsoft Teams client. They can search, or initiate actions, in an external
system from the compose message area, the command box, or directly from a message.
You can then send the results of that interaction back to the Microsoft Teams client,
typically in the form of a richly formatted card
1. In Visual Studio Code, select Microsoft Teams on the left Activity Bar and
choose Create a new Teams app.
2. When prompted, sign in with your Microsoft 365 development account.
6. Open botActivityHandler to
locate async handleTeamsMessagingExtensionQuery(context, query) method.
powershell
ngrok http -host-header=rewrite 3978
This will start ngrok and will tunnel requests from an external ngrok url to your
development machine on port 3978. Copy the https forwarding address (you will need
this for the next steps). For example, it would be similar to https://787b8292.ngrok.io.
4. For the Messaging endpoint URL, use the current https URL you were given
by running ngrok and append it with the path /api/messages. It should like something
similar to https://{subdomain}.ngrok.io/api/messages.
Build and run the search-based messaging extension
1. Open Terminal in Visual Studio Code. From the Visual Studio Code ribbon
select Terminal > New Terminal.
3. Run npm start.
1. Start debugging the project by selecting the F5 key or select the debug icon in
Visual Studio Code and select the Start Debugging (green arrow) button.
2. Go back to Teams. In the dialog, select Add for me to install your app.
Well done, You now have a search-based Messaging Extensions for searching the registry
for packages matching the search terms.
1. In Visual Studio Code, select Microsoft Teams on the left Activity Bar and
choose Create a new Teams app.
1. Open Terminal in Visual Studio Code. From the Visual Studio Code ribbon
select Terminal > New Terminal.
3. Run npm start.
1. Start debugging the project by selecting the F5 key or select the debug icon in
Visual Studio Code and click the Start Debugging green arrow button.
2. Go back to Teams. In the dialog, select Add for me to install your app.
Well done, You have a action-based Messaging Extensions for submitting a compose
message to your bot.
Review
In this exercise, you:
Congratulations!
You have successfully completed this exercise. Click Next to advance to the next exercise.
Conversational bots allow users to interact with your web service through text, interactive
cards, and task modules. They're incredibly flexible — conversational bots can be scoped to
handling a few simple commands or complex, artificial-intelligence-powered and natural-
language-processing virtual assistants. They can be one aspect of a larger application, or
completely stand-alone.
1. In Visual Studio Code, select Microsoft Teams on the left Activity Bar and
choose Create a new Teams app.
2. When prompted, sign in with your Microsoft 365 development account.
Note: A conversation is a series of messages sent between your bot and one or more users.
There are three kinds of conversations (also called scopes) in Teams:
- **teams**: Also called channel conversations, visible to all members of the
channel.
- **personal**: Conversations between bots and a single user.
- **groupChat**: Chat between a bot and two or more users. Also enables your bot
in meeting chats.
powershell
ngrok http -host-header=rewrite 3978
This will start ngrok and will tunnel requests from an external ngrok url to your
development machine on port 3978. Copy the https forwarding address. In the example
below that would be https://787b8292.ngrok.io. You will need this later.
2. Reture to Visual Studio Code, for the Messaging endpoint, use the current
https URL you were given by running ngrok and append it with the path
/api/messages. It should like something
work https://{subdomain}.ngrok.io/api/messages.
1. Open Terminal in Visual Studio Code. From the Visual Studio Code ribbon
select Terminal > New Terminal.
2. Run npm install to install all dependent packages for the Teams tab.
5. Go back to Teams. In the dialog, you could select Add for me to install the bot
as a personal bot, or you select Add to a team or Add to a chat to install the bot as a a
group/channel bot.
7. Go back to the Visual Studio Code project. Stop the running project by
selecting Ctrl + C.
javascript
const conversationReferences = {};
const botActivityHandler = new BotActivityHandler(conversationReferences);
3. Add the following code to end of index.js file.
javascript
// Listen for incoming notifications and send proactive messages to
users.
server.get('/api/notify', async (req, res) => {
for (const conversationReference of
Object.values(conversationReferences)) {
await adapter.continueConversation(conversationReference, async
turnContext => {
// If you encounter permission-related errors when sending
this message, see
// https://aka.ms/BotTrustServiceUrl
await turnContext.sendActivity('proactive hello');
});
}
res.setHeader('Content-Type', 'text/html');
res.writeHead(200);
res.write('<html><body><h1>Proactive messages have
been sent.</h1></body></html>');
res.end();
});
javascript
constructor(conversationReferences) {
super();
// Dependency injected dictionary for storing ConversationReference
objects used in NotifyController to proactively message users
this.conversationReferences = conversationReferences;
await next();
});
/* Conversation Bot */
/* Teams bots are Microsoft Bot Framework bots.
If a bot receives a message activity, the turn handler sees that
incoming activity
and sends it to the onMessage activity handler.
Learn more: https://aka.ms/teams-bot-basics.
TurnContext.removeRecipientMention(context.activity);
switch (context.activity.text.trim()) {
case 'Hello':
await this.mentionActivityAsync(context);
break;
default:
// By default for unknown activity sent by user show
// a card with the available actions.
const value = { count: 0 };
const card = CardFactory.heroCard(
'Lets talk...',
null,
[{
type: ActionTypes.MessageBack,
title: 'Say Hello',
value: value,
text: 'Hello'
}]);
await context.sendActivity({ attachments: [card] });
break;
}
await next();
});
/* Conversation Bot */
}
javascript
addConversationReference(activity) {
const conversationReference =
TurnContext.getConversationReference(activity);
this.conversationReferences[conversationReference.conversation.id] =
conversationReference;
}
For this Cloud Slice version the Resource Group has been created for you. You can skip
this step and proceed to Create the service plan
The resource group and the service plan aren't strictly necessary, but they allow you to
conveniently release the resources you create. This is good practice for keeping your
resources organized and manageable.
2. Sign in with [email protected] and e#BdhDB01!.
3. Select Create.
c. Name. Enter the name for the service plan. An example could
be TeamsServicePlan. Remember that the name must be unique, within the group.
h. Select Create. It may take a few minutes to create the app service plan.
The plan will be listed in the resource group.
The bot channels registration registers your web service as a bot with the Bot Framework,
provided you have a Microsoft App Id and App password (client secret).
2. In the search box enter "bot". And in the drop-down list, select Bot Channels
Registration.
3. Select the Create button.
powershell
ngrok http -host-header=rewrite 3978
This will start ngrok and will tunnel requests from an external ngrok url to your
development machine on port 3978. Copy the https forwarding address. In the example
below that would be https://787b8292.ngrok.io. You will need this later.
6. Reture to Visual Studio Code, for the Messaging endpoint, use the current
https URL you were given by running ngrok and append it with the path
/api/messages. It should like something
work https://{subdomain}.ngrok.io/api/messages.
7. Click Microsoft App ID and password and then Create New.
8. Click Create App ID in the App Registration Portal link.
9. In the displayed App registration window, click the New registration tab in
the upper left.
10. Enter the name of the bot application you are registering, we
used BotTeamsAuth (you need to select your own unique name).
12. Click the Register button. Once completed, Azure displays the Overview page
for the application.
b. Add a description to identify this secret from others you might need to create for this
app.
d. Click Add.
e. Copy the client secret and save it to a file.
16. Click OK.
After Azure has created the registration resource it will be included in the resource group
list.
Once your bot channels registration is created, you'll need to enable the Teams channel.
Note: The Bot Channels Registration resource will show the Global region even if you
selected West US. This is expected.
You need an identity provider that can be used for authentication. In this procedure you'll
use an Azure AD provider; other Azure AD supported identity providers can also be used.
a. Name. Enter the name for the application. An example could be BotTeamsIdentity.
Remember that the name must be unique.
a. Select Web.
d. Select Register.
5. Once it is created, Azure displays the Overview page for the app. Copy and
save the following information to a file:
a. The Application (client) ID value. You'll use this value later as the Client ID when
you register this Azure identity application with your bot.
b. The Directory (tenant) ID value. You'll also use this value later as the Tenant ID to
register this Azure identity application with your bot.
6. In the left panel, select Certificates & secrets to create a client secret for your
application.
b. Add a description to identify this secret from others you might need to create for this
app, such as Bot identity app in Teams.
d. Select Add.
e. Before leaving this page, record the secret. You'll use this value later as the Client
secret when you register your Azure AD application with your bot.
Configure the identity provider connection and register it with the bot
a. Name. Enter a name for the connection. You'll use this name in your bot in the
appsettings.json file. For example BotTeamsAuthADv2.
c. Client id. Enter the Application (client) ID that you recorded for your Azure identity
provider app in the steps above.
d. Client secret. Enter the secret that you recorded for your Azure identity provider
app in the steps above.
f. Tenant ID, enter the Directory (tenant) ID that you recorded earlier for your Azure
identity app or common depending on the supported account type selected when you
created the identity provider app. To decide which value to assign follow these criteria:
6. Select Save.
1. Select the connection entry to open the connection you just created.
2. Select Test Connection at the top of the Service Provider Connection Setting
panel.
3. The first time you do this will open a new browser window asking you to select
an account. Select the one you want to use.
4. Next, you'll be asked to allow to the identity provider to use your data
(credentials). The following image is an example:
5. Select Accept.
The connection name is used by the bot code to retrieve user authentication tokens.
a. Set bot App ID to the bot App ID you saved at the time of the bot channel
registration.
b. Set bot App Password to the customer secret you saved at the time of the bot
channel registration.
7. In Visual Studio Code, open .env file, append the following content to the end
of the file, please set \<your-connection-name> to the name of the identity provider
connection you added to the bot channel registration.
connectionName=<your-connection-name>
8. Open index.js in the root folder, and then relace content with the following
code.
javascript
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// Create adapter.
// See https://aka.ms/about-bot-adapter to learn more about adapters.
const adapter = new BotFrameworkAdapter({
appId: process.env.BotId,
appPassword: process.env.BotPassword
});
javascript
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
async onContinueDialog(innerDc) {
const result = await this.interrupt(innerDc);
if (result) {
return result;
}
async interrupt(innerDc) {
if (innerDc.context.activity.type === ActivityTypes.Message) {
const text = innerDc.context.activity.text.toLowerCase();
if (text === 'logout') {
// The bot adapter encapsulates the authentication
processes.
const botAdapter = innerDc.context.adapter;
await botAdapter.signOutUser(innerDc.context,
this.connectionName);
await innerDc.context.sendActivity('You have been signed
out.');
return await innerDc.cancelAllDialogs();
}
}
}
}
module.exports.LogoutDialog = LogoutDialog;
javascript
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
this.initialDialogId = MAIN_WATERFALL_DIALOG;
}
/**
* The run method handles the incoming activity (in the form of a
DialogContext) and passes it through the dialog system.
* If no dialog is active, it will start the default dialog.
* @param {*} dialogContext
*/
async run(context, accessor) {
const dialogSet = new DialogSet(accessor);
dialogSet.add(this);
async promptStep(stepContext) {
return await stepContext.beginDialog(OAUTH_PROMPT);
}
async loginStep(stepContext) {
// Get the token from the previous step. Note that we could also
have gotten the
// token directly from the prompt itself. There is an example of
this in the next method.
const tokenResponse = stepContext.result;
if (tokenResponse) {
await stepContext.context.sendActivity('You are now logged
in.');
return await stepContext.prompt(CONFIRM_PROMPT, 'Would you
like to view your token?');
}
await stepContext.context.sendActivity('Login was not successful
please try again.');
return await stepContext.endDialog();
}
async displayTokenPhase1(stepContext) {
await stepContext.context.sendActivity('Thank you.');
async displayTokenPhase2(stepContext) {
const tokenResponse = stepContext.result;
if (tokenResponse) {
await stepContext.context.sendActivity(`Here is your token ${
tokenResponse.token }`);
}
return await stepContext.endDialog();
}
}
module.exports.MainDialog = MainDialog;
12. Open the botActivityHandler.js file and replace the content with the following
code.
javascript
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
await next();
});
}
module.exports.BotActivityHandler = BotActivityHandler;
13. Create a file named DialogBot.js in root folder, and add the following code to
the file.
javascript
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
await next();
});
}
/**
* Override the ActivityHandler.run() method to save state changes
after the bot logic completes.
*/
async run(context) {
await super.run(context);
// Save any state changes. The load happened during the execution
of the Dialog.
await this.conversationState.saveChanges(context, false);
await this.userState.saveChanges(context, false);
}
}
module.exports.DialogBot = DialogBot;
14. From the Visual Studio Code ribbon, select Terminal > New Terminal.
18. In Visual Studio Code, select the F5 key to launch a Teams web client.
19. Go back to Teams. In the dialog, you could select Add for me to install the bot
as a personal bot, or you select Add to a team or Add to a chat to install the bot as a a
group/channel bot.
Review
In this exercise, you:
Congratulations!
You have successfully completed Lab 04, to mark the lab as complete click End.
PreviousEnd