page_type | description | products | languages | extensions | urlFragment | ||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
sample | This sample shows how a bot can proactively start and manage tab-based conversations in Microsoft Teams for support inquiries. |
|
|
| officedev-microsoft-teams-samples-bot-tab-conversations-csharp |
This sample explores proactive conversations using a Teams bot, where inquiries are created and displayed within a support tab, allowing users to interact via adaptive cards. It supports tab-based interactions, API call authorization based on team membership, and offers both channel and personal tab experiences.
Please see the Code Tours section for in-depth explanation of the sample.
- Conversational tabs/Sub-entity conversations
- Personal tabs
- Proactive conversation creation from a Bot
- Authorization of API calls based on user's Team membership
sequenceDiagram actor User as User participant External as External Service Note over External: Simple website in our POC participant ChannelTab as Support Department Channel Tab participant ChannelPosts as Team Channel Posts participant PersonalTab as Personal Tab participant Bot as Teams App Bot participant Service as Service participant DataStore as Data Store participant Graph as Graph API Note over Bot,Service: App Installation Bot ->> Service: Bot context, for future proactive messages Service ->> DataStore: Store bot context Note over User,DataStore: Create a Tab User ->> ChannelTab: Adds Tab ChannelTab ->> Service: Save support department tab details Service ->> Graph: Ensure user is a member of the relevant Team Graph ->> Service: Service ->> DataStore: Get bot context for channel alt Bot context exists DataStore ->> Service: Bot Context Data Service ->> DataStore: Store support department details DataStore ->> Service: Success Service ->> ChannelTab: Create tab else Bot context missing DataStore ->> Service: No bot context error Service ->> ChannelTab: Channel bot context not found error message end ChannelTab ->> User: Error or tab created successfully Note over External,DataStore: Post a new inquiry External ->> Service: Creates a new inquiry for a support department Service ->> DataStore: Support department details and bot context DataStore ->> Service: Service ->> Bot: Bot context and inquiry details Bot ->> ChannelPosts: Inquiry posted to Team Bot ->> Service: Inquiry conversation reference Service ->> DataStore: Store inquiry conversation reference Service ->> External: Success Note over User,DataStore: Open Support Department User ->> ChannelTab: Opens Channel Tab ChannelTab ->> Service: Get inquiries Service ->> DataStore: Support department inquiries DataStore ->> Service: Service ->> Graph: Ensure user is a member of the Support Department Team Graph ->> Service: Service ->> ChannelTab: Support department inquiries ChannelTab ->> User: Display list of support department inquiries User ->> ChannelTab: Select single inquiry, open details ChannelTab ->> Service: Get single inquiry Service ->> DataStore: Single inquiry DataStore ->> Service: Service ->> Graph: Ensure user is a member of the Support Department Team Graph ->> Service: Service ->> ChannelTab: Single inquiry ChannelTab ->> User: Display single support department inquiry Note over User,DataStore: Open Personal Tab User ->> PersonalTab: Opens Personal Tab PersonalTab ->> Service: Get all support departments Service ->> DataStore: All support department inquiries DataStore ->> Service: Service ->> Graph: Get user's Teams Graph ->> Service: Service ->> PersonalTab: Filter support department inquiries to user's Teams PersonalTab ->> User: Display list of all support departments and top inquiries
- Make sure you have an active Azure subscription.
- Make sure Publish to organization's app store is available in Teams. Publish a custom app to publish the custom app.
- Install Visual Studio or Visual Studio Code to run and debug the sample code.
- .NET Core SDK version 6.0
- dev tunnel or ngrok latest version or equivalent tunneling solution
- Teams Microsoft Teams is installed and you have an account
- Teams Toolkit for Visual Studio
##Run the app (Using Teams Toolkit for Visual Studio)
The simplest way to run this sample in Teams is to use Teams Toolkit for Visual Studio.
1.Install Visual Studio 2022 Version 17.10 Preview 4 or higher Visual Studio 2.Install Teams Toolkit for Visual Studio Teams Toolkit extension 3.In the debug dropdown menu of Visual Studio, select Dev Tunnels > Create A Tunnel (set authentication type to Public) or select an existing public dev tunnel. 4.In the debug dropdown menu of Visual Studio, select default startup project > Microsoft Teams (browser) 5.In Visual Studio, right-click your TeamsApp project and Select Teams Toolkit > Prepare Teams App Dependencies 6.Using the extension, sign in with your Microsoft 365 account where you have permissions to upload custom apps. 7.Select Debug > Start Debugging or F5 to run the menu in Visual Studio. 8.In the browser that launches, select the Add button to install the app to Teams.
If you do not have permission to upload custom apps (sideloading), Teams Toolkit will recommend creating and using a Microsoft 365 Developer Program account - a free program to get your own dev environment sandbox that includes Teams.
- Set-up, deploy and sideload the app to a channel. *Create new channel and
- When the app is installed to the team the bot will automatically gather the required info to create proactive conversations later.
- First create your new channel then proceed.
- In a channel, click '+ Add a tab', and add a new Conversational Tab.
- Configure your tab, by adding a Department name and Department description, then click Save.
- The first time running this application you will need to consent twice. Once to use the app initially, and once to call the API. If you see "We need you to consent to complete that action.", ensure that your pop-up blocker isn't blocking a consent dialog.
- In your tab you will see the department details, but there will be no inquires.
- Open up the external admin page at
<<tunnel-url>>/admin
. This page is a stand-in for an external service that might want to connect into teams, e.g. a job posting board who wants to post new applications.- In the external admin page, select a support department and add a new inquiry.
- In the channel, you will see a new conversation. The conversation will be an Adaptive Card that will link to the inquiry in the tab.
- In the tab, you will see the inquiry details and you can use Open conversation to open the conversation to the side. And messages posted here, will be visible in the conversation in that channel.
- If you navigate Back you can see all the inquiries.
There is also a personal tab that will list inquires from all the support departments from all the channels you have access to.
- After installing the app in the personal scope, open the app.
- Once authenticated, the app will list all the support departments from any channel you are a member of. Up to five inquiries from each support department will be listed.
- Clicking on the -> Arrow will open the inquiry details. From the detail page you can open the channel conversation about the inquiry.
Run Ngrok
- Run ngrok and point it to the port the Web App is listening on. Note the port will change depending on how you are deploying.
ngrok http 44326 --host-header="localhost:44326"# For Visual Studio
Alternatively, you can also use the
dev tunnels
. Please follow Create and host a dev tunnel and host the tunnel with anonymous user access command as shown below:devtunnel host -p 44326 --allow-anonymous
- Make sure to copy and save the
https
url (it should look likehttps://<randomsubdomain>.ngrok-free.app
if you are using Ngrok and if you are using dev tunnels then your URL will be like:https://<randomsubdomain>.devtunnels.ms
).
Create an Microsoft Entra ID app registration in Azure Portal and also create Azure bot in Azure Portal or in Developer Portal for Microsoft Teams.
- Set the 'Messaging endpoint' for your Azure Bot with
https://<your application domain>/api/messages
like your ngrok URLhttps://xxxxx.ngrok-free.app
or dev tunnels URL like :https://XXXXXX.devtunnels.ms
. - Note: if you restart Ngrok you may have to update the messaging endpoint domain URL aginn in your Azure Bot for local running
- Ensure that you've enabled the Teams Channel
- Set the 'Messaging endpoint' for your Azure Bot with
Update the Microsoft Entra ID App to enable Teams SSO
When creating the Bot above, an Microsoft Entra ID app should either have been created for you, or you should have chosen an Microsoft Entra ID app to associate with the bot.
The updates below will allow for us to authenticate and authorize API calls to limit data returned to only channels the user is a member of.
Follow the instructions, to expose an Microsoft Entra ID API, creating an Application ID URI, scopes, etc.
Once you have followed those instructions, you need to configure the Web authentication platform for the application. Ensure that you have added the
redirect URI
in this formathttps://<<fully-qualified-domain-name.com>>/auth-end
like your ngrok URL 'https://xxxxx-590a-c1b2.ngrok-free.app/auth-end'Ensure the following API permissions are granted to the app for Microsoft Graph access -
email
,offline_access
,openid
,profile
,Team.ReadBasic.All
Note: if you restart Ngrok you may have to update any fully qualified domain name you have set in your Microsoft Entra ID App
Setup for code
Clone the repository
git clone https://github.com/OfficeDev/Microsoft-Teams-Samples.git
Run the bot from a terminal or from Visual Studio:
A) From a terminal, navigate to
Source\ConversationalTabs.Web
# run the bot dotnet run
B) Or from Visual Studio
- Launch Visual Studio
- File -> Open -> Project/Solution
- Navigate to
samples\bot-tab-conversations\csharp\Source\ConversationalTabs.Web
folder - Select
Microsoft.Teams.Samples.ConversationalTabs.Web.csproj
file - Press
F5
to run the project
In
appSettings.json
and.env
file replace:<<tunnel-url>>
with your tunnel URL minus the https://.<<aad-id>>
with your Microsoft Entra ID Application (Client) Id.<<aad-client-secret>>
with the client secret you created above.<<tenant-id>>
with the directory id received via creating Microsoft Entra ID app registration in your Azure Portal.<<teams-app-store-app-id>>
with the App ID assigned to the app in the Teams Admin Center or provided when your app passes validation. If you are sideloading the app you can use the appId from the manifest file, but please note that deep linking may not work when sideloading.
Setup Manifest for Teams
- Edit the
manifest.json
contained in theManifest
folder to replace your Microsoft App Id (that was created when you registered your bot earlier) everywhere you see the place holder string<<aad-id>>
(depending on the scenario the Microsoft App Id may occur multiple times in themanifest.json
) - Edit the
manifest.json
for<<tunnel-url>>
with base Url domain. E.g. if you are using ngrok it would behttps://1234.ngrok-free.app
then your domain-name will be1234.ngrok-free.app
and if you are using dev tunnels then your domain will be like:12345.devtunnels.ms
. Replace it at all the places you see in yourmainfest.json
.
- Edit the
Deploying
- There are detailed instructions for deploying locally below.
Sideloading the App
- Create a zip containing
manifest.json
,colorIcon.png
andoutlineIcon.png
fromSource\ConversationalTabs.Web\appPackage
. - You can upload you app by following these instructions
- Create a zip containing
Note: If you are facing any issue in your app, please uncomment this line and put your debugger for local debug.
When the solution is run on a local web browser (anywhere outside of Teams), it will load a spinner. Instead side-load the application to a teams client, or open up
<<tunnel-url>>/admin
to open the admin pageSometimes, the "Open Details" button on a new inquiry's Adaptive Card may not navigate to a the channel tab. This is due to side-loaded apps not having a consistent entityId. This makes deeplinking difficult. If this happens you can open the inquiry in the tab directly. If you have submitted the app to either your Org App Store or the Teams App Store you must set the
<<teams-app-store-app-id>>
in appsettings.json to the App ID value as shown in the Teams Admin Center.Private channels do not support bots at the moment, therefore this app is not supported on private channels.
If in the personal app a user opens a conversation from a channel they are not a member of, the conversation will fail to show. This is not an issue in our sample as we filter support departments based on Team membership.
App shows "We need you to consent to complete that action." but provides no action: your pop -up blocker might be blocking a consent dialog from opening, be sure to allow pop-ups from Teams.
This repository uses VSCode Code Tours to explain how the code works.
The tour files can be found in the .tours
directory.
- Project Structure
- The sample contains 3 projects
Web
- Exposes REST APIs for documents and signing scenarios supported in this POC.Web\ClientApp
contains the Front End code to support document sharing in a meeting via share to stage.
Domain
- Contains the business logic to support the REST APIs.Infrastructure
- FulfilsDomain
's dependencies like data repositories, graph support needed.
- The sample contains 3 projects
- Point tunnel to port 44326: Eg.
ngrok http 44326 --host-header="localhost:44326"
- Open the solution in Visual Studio.
- Ensure the start-up project is set to
Microsoft.Teams.Samples.ConversationalTabs.Web
- Start Debugging using IIS Express
- Point tunnel to port 5001: Eg.
ngrok http -host-header=rewrite 5001
- In a terminal, navigate to
Source\ConversationalTabs.Web
- Run
dotnet run
Note the below instructions are using Podman, but Docker's commands are similar. There are instructions for setting up Podman on WSL2 here
- From this directory build the Docker image
podman build -f Deployment/Dockerfile --ignorefile Deployment/.dockerignore ./Source
- Wait for the container to build
- Run
podman images
to view available images, copy the Image ID - Point tunnel to port 8080: Eg.
ngrok http -host-header=rewrite 8080
- Run
podman run -d -p 8080:80 --name ConversationalTabs <IMAGE_ID>
to start the container - Open http://localhost:8080/ to view the service running