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 page -
Sometimes, 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