Microsoft.TeamsFx
2.5.0
Prefix Reserved
dotnet add package Microsoft.TeamsFx --version 2.5.0
NuGet\Install-Package Microsoft.TeamsFx -Version 2.5.0
<PackageReference Include="Microsoft.TeamsFx" Version="2.5.0" />
paket add Microsoft.TeamsFx --version 2.5.0
#r "nuget: Microsoft.TeamsFx, 2.5.0"
// Install Microsoft.TeamsFx as a Cake Addin #addin nuget:?package=Microsoft.TeamsFx&version=2.5.0 // Install Microsoft.TeamsFx as a Cake Tool #tool nuget:?package=Microsoft.TeamsFx&version=2.5.0
TeamsFx .NET SDK
A NuGet package for Blazor projects which aims to reduce the developer tasks of implementing identity and access to cloud resources.
TeamsFx SDK for JavaScript/TypeScript | API reference documentation
Getting started
Build Teams apps with Blazor and the TeamsFx .NET SDK using Teams Toolkit. Visit the documentation to learn more.
Prerequisites
- Install the
ASP.NET and web development
workload using the Visual Studio Installer. - Launch Visual Studio and create a new Blazor project.
Usage
How to get the package
- Right-click on the project in Visual Studio and choose Manage NuGet Packages.
- Search for
Microsoft.TeamsFx
and add it to the Blazor project.
Alternately, you can use the Package Manager.
> Install-Package Microsoft.TeamsFx
How to choose version
For .NET 5 projects (VS 2019): Choose version < 0.3.0-rc. For .NET 6 projects (VS 2022): Choose version >= 0.3.0-rc.
Using Teams User Credential in Teams Tab app
- Add authentication options in appsettings.{Environment}.json file.
"TeamsFx": {
"Authentication": {
"ClientId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"ClientSecret": "xxx", // 'User Secrets' is a better place to store secret string.
"OAuthAuthority": "https://login.microsoftonline.com/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
}
- Add
TeamsFx
to services during startup.
public void ConfigureServices(IServiceCollection services)
{
...
services.AddTeamsFx(Configuration.GetSection("TeamsFx"));
}
- Add the required namespaces to the
_Imports.razor
file.
@using Microsoft.TeamsFx
- Inject the registered TeamsFx services for any page that needs them.
@inject TeamsFx teamsfx
@inject TeamsUserCredential teamsUserCredential
- Call
teamsUserCredential.GetTokenAsync()
to get access token or passteamsUserCredential
to other functions.
try
{
await teamsUserCredential.GetTokenAsync(
new TokenRequestContext(new string[] { "User.Read" }),
new System.Threading.CancellationToken());
}
catch (ExceptionWithCode e)
{
if (e.Code == ExceptionCode.UiRequiredError)
{
// show login button to let user consent
}
else
{
throw;
}
}
Using Graph Service with Teams User Credential in Teams Tab app
Follow the above
Using Teams User Credential in Teams Tab app
to createTeamsUserCredential
.Add
@using Microsoft.Graph
to any page that needs the Graph service.Initialize a Graph Service Client with credential and scopes.
string _scope = "User.Read"; var client = new GraphServiceClient(teamsUserCredential, new string[] { _scope });
To make requests against the service, you could follow the guide. For instance, if you wish to get user profile, you could call
graph.Me.GetAsync();
Using Conversation Bot for Command and Response
Add your command handler class which implements the
ITeamsCommandHandler
interface.- Define your trigger patters in the
TriggerPatterns
property, you can useStringTrigger
orRegExpTrigger
. - Handle your command in
HandleCommandAsync
function, and return anActivityCommandResponse
orTextommandResponse
object as the command response.
public class SampleCommandHandler : ITeamsCommandHandler { // Define your trigger patterns public IEnumerable<ITriggerPattern> TriggerPatterns => new List<ITriggerPattern> { new StringTrigger("helloworld") }; // Handle your command and send response to Teams chat public async Task<ICommandResponse> HandleCommandAsync(ITurnContext turnContext, CommandMessage message, CancellationToken cancellationToken = default) { // TODO: provide your implementation here. return new TextCommandResponse("This is a sample response!"); } }
- Define your trigger patters in the
Initialize the command bot and register your commands in your app's startup (usually it's in
Program.cs
orStartup.cs
)builder.Services.AddSingleton<SampleCommandHandler>(); builder.Services.AddSingleton(sp => { var options = new ConversationOptions() { // NOTE: you need to register your CloudAdapter into your service before conversation bot initialization. Adapter = sp.GetService<CloudAdapter>(), Command = new CommandOptions() { Commands = new List<ITeamsCommandHandler> { sp.GetService<SampleCommandHandler>() } } }; return new ConversationBot(options); });
Use the conversation bot in your bot controller
namespace SampleTeamsApp.Controllers { using Microsoft.AspNetCore.Mvc; using Microsoft.Bot.Builder; using Microsoft.Bot.Builder.Integration.AspNet.Core; using Microsoft.TeamsFx.Conversation; [Route("api/messages")] [ApiController] public class BotController : ControllerBase { private readonly ConversationBot _conversation; private readonly IBot _bot; public BotController(ConversationBot conversation, IBot bot) { _conversation = conversation; _bot = bot; } [HttpPost] public async Task PostAsync(CancellationToken cancellationToken = default) { await (_conversation.Adapter as CloudAdapter).ProcessAsync ( Request, Response, _bot, cancellationToken ); } } }
Using Conversation Bot for Notification
Initialize your own bot adapter and the
ConversationBot
in your app's startup (usually it's inProgram.cs
orStartup.cs
)// Create the Conversation with notification feature enabled. builder.Services.AddSingleton(sp => { var options = new ConversationOptions() { // NOTE: you need to register your CloudAdapter into your service before conversation bot initialization. Adapter = sp.GetService<CloudAdapter>(), Notification = new NotificationOptions { BotAppId = botAppId, // Your bot app ID }, }; return new ConversationBot(options); });
Reference the conversation bot in your bot message controller/handler to ensure it's initialized before handling any bot message
namespace SampleTeamsApp.Controllers { using Microsoft.AspNetCore.Mvc; using Microsoft.Bot.Builder; using Microsoft.Bot.Builder.Integration.AspNet.Core; using Microsoft.TeamsFx.Conversation; [Route("api/messages")] [ApiController] public class BotController : ControllerBase { private readonly ConversationBot _conversation; private readonly IBot _bot; public BotController(ConversationBot conversation, IBot bot) { _conversation = conversation; _bot = bot; } [HttpPost] public async Task PostAsync(CancellationToken cancellationToken = default) { await (_conversation.Adapter as CloudAdapter).ProcessAsync ( Request, Response, _bot, cancellationToken ); } } }
Send notification (called by your own controller or trigger)
public async Task NotifyAsync(ConversationBot conversation, CancellationToken cancellationToken) { var pageSize = 100; string continuationToken = null; do { var pagedInstallations = await conversation.Notification.GetPagedInstallationsAsync(pageSize, continuationToken, cancellationToken); continuationToken = pagedInstallations.ContinuationToken; var installations = pagedInstallations.Data; foreach (var installation in installations) { await installation.SendMessage("Hello.", cancellationToken); // Or, send adaptive card (need to build your own card object) // await installation.SendAdaptiveCard(cardObject, cancellationToken); } } while (!string.IsNullOrEmpty(continuationToken)); }
Using Conversation Bot for Adaptive Card Actions
Add your adaptive card action handler class which implements the
IAdaptiveCardActionHandler
interface.- Set the
TriggerVerb
property, the value should be the same as theverb
property of theAction.Execute
action. - Handle your action in
HandleActionInvokedAsync
function, and return anInvokeResponse
as the action response.
public class DoStuffActionHandler : IAdaptiveCardActionHandler { /// <summary> /// A global unique string associated with the `Action.Execute` action. /// The value should be the same as the `verb` property which you define in your adaptive card JSON. /// </summary> public string TriggerVerb => "doStuff"; /// <summary> /// Indicate how your acrion response card is sent in the conversation. /// By default, the response card can only be updated for the interactor who trigger the action. /// </summary> public AdaptiveCardResponse AdaptiveCardResponse => AdaptiveCardResponse.ReplaceForInteractor; public async Task<InvokeResponse> HandleActionInvokedAsync(ITurnContext turnContext, object cardData, CancellationToken cancellationToken = default) { // Send invoke response with text message return InvokeResponseFactory.TextMessage("[ACK] Successfully!"); /** * If you want to send invoke response with adaptive card, you can: * * return InvokeResponseFactory.AdaptiveCard(JsonConvert.DeserializeObject(<your-card-json>)); */ /** * If you want to send invoke response with error message, you can: * * return InvokeResponseFactory.ErrorResponse(InvokeResponseErrorCode.BadRequest, "The incoming request is invalid."); */ } }
- Set the
Initialize your own bot adapter and the
ConversationBot
in your app's startup (usually it's inProgram.cs
orStartup.cs
)// create action handler instance builder.Services.AddSingleton<DoStuffActionHandler>(); // create conversation bot with adaptive card action feature enabled. builder.Services.AddSingleton(sp => { var options = new ConversationOptions() { // NOTE: you need to register your CloudAdapter into your service before conversation bot initialization. Adapter = sp.GetService<CloudAdapter>(), CardAction = new CardActionOptions() { Actions = new List<IAdaptiveCardActionHandler> { sp.GetService<DoStuffActionHandler>() } } }; return new ConversationBot(options); });
Reference the conversation bot in your bot message controller/handler to ensure it's initialized before handling any bot message
namespace SampleTeamsApp.Controllers { using Microsoft.AspNetCore.Mvc; using Microsoft.Bot.Builder; using Microsoft.Bot.Builder.Integration.AspNet.Core; using Microsoft.TeamsFx.Conversation; [Route("api/messages")] [ApiController] public class BotController : ControllerBase { private readonly ConversationBot _conversation; private readonly IBot _bot; public BotController(ConversationBot conversation, IBot bot) { _conversation = conversation; _bot = bot; } [HttpPost] public async Task PostAsync(CancellationToken cancellationToken = default) { await (_conversation.Adapter as CloudAdapter).ProcessAsync ( Request, Response, _bot, cancellationToken ); } } }
SDK Upgrade Steps
Upgrade from 0.1.0-rc to 0.3.0 (For projects created by Visual Studio 2019 toolkit)
If there is an existing project created in VS2019, you can use the following steps to upgrade:
Open project in VS2022 and change project target framework to ".NET 6".
Upgrade dependencies:
Microsoft.TeamsFx.SimpleAuth
to0.1.2
,Newtonsoft.Json
to13.0.1
,Microsoft.Graph
to4.12.0
,Microsoft.Fast.Components.FluentUI
to1.1.0
.Add following lines in appsettings.{Environment}.json file after "ALLOWED_APP_IDS".
"ALLOWED_APP_IDS": "...",
"TeamsFx": {
"Authentication": {
"ClientId": "value copied from CLIENT_ID",
"SimpleAuthEndpoint": "value copied from TAB_APP_ENDPOINT",
"InitiateLoginEndpoint": "{value copied from TAB_APP_ENDPOINT}/auth-start.html"
}
}
- Add following lines in
Startup.cs
.
public void ConfigureServices(IServiceCollection services)
{
...
services.AddTeamsFx(Configuration.GetSection("TeamsFx"));
}
and remove following 2 lines.
services.AddScoped<TeamsFx>();
services.AddScoped<TeamsUserCredential>();
- Remove following codes in
Welcome.razor
.
var clientId = Configuration.GetValue<string>("CLIENT_ID");
var endpoint = MyNavigationManager.BaseUri;
await teamsfx.SetLogLevelAsync(LogLevel.Verbose);
await teamsfx.SetLogFunctionAsync(printLog);
AuthenticationConfiguration authentication = new AuthenticationConfiguration(clientId: clientId, simpleAuthEndpoint: endpoint, initiateLoginEndpoint: endpoint + "auth-start.html");
Configuration configuration = new Configuration(authentication);
await teamsfx.LoadConfigurationAsync(configuration);
...
private void printLog(LogLevel level, string message)
{
Console.WriteLine(message);
}
Upgrade from 0.3.0-rc to 0.4.0-rc (For projects created by Visual Studio 2022 17.1 Preview toolkit)
If there is an existing project created in VS2022 17.1 Preview, you can use the following steps to upgrade:
- In
appsettings.{Environment}.json
file:
- Add
OAuthAuthority
underTeamsFx:Authentication
and copy the value fromOAUTH_AUTHORITY
. - Remove the line
"SimpleAuthEndpoint": "https://localhost:port/"
. - Remove lines of configuration starting with "CLIENT_ID", "IDENTIFIER_URI", "TAB_APP_ENDPOINT", "OAUTH_AUTHORITY", "AAD_METADATA_ADDRESS", "ALLOWED_APP_IDS".
- Remove the Nuget dependency package "Microsoft.TeamsFx.SimpleAuth".
- In Solution Explorer:
- Right click project file and choose "Manage User Secrets".
- Change key name "CLIENT_SECRET" to "TeamsFx:Authentication:ClientSecret".
Upgrade from 1.1.0 to 1.2.0 (Update projects to use TeamsJS V.2.0)
Teams Toolkit provides users with a template TeamsJSBlazorInterop.js
, which consists of multiple commonly used Teams JS SDK API. Users can add more APIs if needed. As suggested, even if you intend your app to only run in Teams (and not Outlook and the Microsoft 365 app), best practice is to start referencing the latest TeamsJS (v.2.0 or later) as soon as convenient, in order to benefit from the latest improvements, new features, and support (even for Teams-only apps).
Starting from TeamsFx .NET SDK 1.2.0, TeamsJS V2 are referenced. Though previously scaffolded projects still work with TeamsFx .NET SDK 1.2.0, we suggest you replace the TeamsJSBlazorInterop.js
under ./wwwroot/js
with the latest one from here. Two APIs in the file are updated with new function name to align with renamed TeamsJS APIs. initializeWithContext()
is removed.
Original Function | New Function |
---|---|
setFrameContext() | setCurrentFrame() |
registerChangeSettingHandler() | registerChangeConfigHandler() |
For more APIs, please visit the TeamsJS documentation to learn more.
Upgrade from 1.x.x to 2.0.0
In this release, TeamsFx SDK add supports for Graph SDK v5 and remove frameworkreference
. auth-start.html
and auth-end.html
are removed from SDK, and added to templates. You could use the following steps to upgrade existing projects.
Upgrade package dependencies in
{{ProjectName}}.csproj
.<PackageReference Include="Microsoft.Graph" Version="5.6.0" /> <PackageReference Include="Microsoft.TeamsFx" Version="2.0.0" />
If you are using class
User
, add@using Microsoft.Graph.Models
to the top of the file.Update requests to Microsoft Graph as follows.
// Previous var Profile = await graph.Me.Request().GetAsync(); var photoStream = await graph.Me.Photo.Content.Request().GetAsync(); // Now var Profile = await graph.Me.GetAsync(); var photoStream = await graph.Me.Photo.Content.GetAsync();
Download
auth-start.html
andauth-end.html
from GitHub Repo to{ProjectDirectory}/wwwroot
.Update
appsetting.json
andappsettings.Development.json
to addInitiateLoginEndpoint
.{ "TeamsFx": { "Authentication": { "ClientId": "$clientId$", "ClientSecret": "$client-secret$", "InitiateLoginEndpoint": "$TAB_ENDPOINT$/auth-start.html", //New Line "OAuthAuthority": "$oauthAuthority$" } } }
Update
azure.bicep
under{ProjectDirectory}/infra
.// Previous resource webApp 'Microsoft.Web/sites@2021-02-01' = { kind: 'app' location: location name: webAppName properties: { serverFarmId: serverfarm.id httpsOnly: true siteConfig: { appSettings: [ { name: 'WEBSITE_RUN_FROM_PACKAGE' value: '1' } { name: 'TeamsFx__Authentication__ClientId' value: tabAadAppClientId } { name: 'TeamsFx__Authentication__ClientSecret' value: tabAadAppClientSecret } { name: 'TeamsFx__Authentication__OAuthAuthority' value: uri(tabAadAppOauthAuthorityHost, tabAadAppTenantId) } ] ftpsState: 'FtpsOnly' } } } // Updated resource webApp 'Microsoft.Web/sites@2021-02-01' = { kind: 'app' location: location name: webAppName properties: { serverFarmId: serverfarm.id httpsOnly: true siteConfig: { ftpsState: 'FtpsOnly' } } } resource webAppConfig 'Microsoft.Web/sites/config@2021-02-01' = { name: '${webAppName}/appsettings' properties: { WEBSITE_RUN_FROM_PACKAGE: '1' TeamsFx__Authentication__ClientId: tabAadAppClientId TeamsFx__Authentication__ClientSecret: tabAadAppClientSecret TeamsFx__Authentication__InitiateLoginEndpoint: 'https://${webApp.properties.defaultHostName}/auth-start.html' TeamsFx__Authentication__OAuthAuthority: uri(tabAadAppOauthAuthorityHost, tabAadAppTenantId) } }
[Optional] Update
teamsapp.local.yml
as follows.- uses: file/updateJson # Generate runtime appsettings to JSON file with: target: ./appsettings.Development.json appsettings: TeamsFx: Authentication: ClientId: ${{AAD_APP_CLIENT_ID}} ClientSecret: ${{SECRET_AAD_APP_CLIENT_SECRET}} InitiateLoginEndpoint: ${{TAB_ENDPOINT}}/auth-start.html # New line OAuthAuthority: ${{AAD_APP_OAUTH_AUTHORITY}}
Configure Logging
ILogger
is used to print logs. You can configure logging in appsettings.{Environment}.json. Visit the ASP.NET documentation to learn more
Bot
Will be supported in the future.
Data Collection.
The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the repository. There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft's privacy statement. Our privacy statement is located at https://go.microsoft.com/fwlink/?LinkID=824704. You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices.
Code of Conduct
This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.
Contributing
There are many ways in which you can participate in the project, for example:
- Submit bugs and feature requests, and help us verify as they are checked in
- Review source code changes
If you are interested in fixing issues and contributing directly to the code base, please see the Contributing Guide.
Reporting Security Issues
Please do not report security vulnerabilities through public GitHub issues.
Instead, please report them to the Microsoft Security Response Center (MSRC) at https://msrc.microsoft.com/create-report.
If you prefer to submit without logging in, send email to secure@microsoft.com. If possible, encrypt your message with our PGP key; please download it from the the Microsoft Security Response Center PGP Key page.
You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at microsoft.com/msrc.
Trademarks
This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft's Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party's policies.
License
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the MIT license.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net6.0
- Microsoft.AspNetCore.Components.Web (>= 6.0.0)
- Microsoft.Bot.Builder (>= 4.22.7)
- Microsoft.Bot.Builder.Dialogs (>= 4.22.7)
- Microsoft.Extensions.Http (>= 6.0.0)
- Microsoft.Extensions.Logging (>= 6.0.0)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 6.0.0)
- Microsoft.Extensions.Options.DataAnnotations (>= 6.0.0)
- Microsoft.Graph (>= 5.6.0)
- Microsoft.Identity.Client (>= 4.61.3)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on Microsoft.TeamsFx:
Package | Downloads |
---|---|
Hexalith.Infrastructure.TeamsBot
Hexalith is a set of libraries to build a micro-service architecture. |
|
Hexalith.Infrastructure.MicrosoftSemanticKernel
Hexalith is a set of libraries to build a micro-service architecture. |
GitHub repositories (1)
Showing the top 1 popular GitHub repositories that depend on Microsoft.TeamsFx:
Repository | Stars |
---|---|
microsoft/hack-together-teams
HackTogether: The Microsoft Teams Global Hack | Register, Hack, Win 👇
|
Version | Downloads | Last updated |
---|---|---|
2.5.0 | 12,414 | 7/22/2024 |
2.5.0-rc | 102 | 7/19/2024 |
2.4.1 | 44,102 | 4/24/2024 |
2.4.1-rc | 126 | 4/23/2024 |
2.4.0 | 22,068 | 12/25/2023 |
2.4.0-rc | 437 | 12/18/2023 |
2.3.0 | 7,533 | 11/13/2023 |
2.3.0-rc | 735 | 10/25/2023 |
2.2.1-rc | 450 | 10/19/2023 |
2.2.0 | 19,589 | 8/30/2023 |
2.2.0-rc | 457 | 8/17/2023 |
2.1.0 | 18,249 | 5/30/2023 |
2.1.0-rc | 529 | 4/25/2023 |
2.0.0 | 4,122 | 4/24/2023 |
2.0.0-rc | 479 | 4/18/2023 |
1.2.1 | 70,092 | 1/11/2023 |
1.2.0 | 3,660 | 12/19/2022 |
1.2.0-rc.2 | 1,289 | 11/9/2022 |
1.2.0-rc | 473 | 10/20/2022 |
1.1.0 | 6,949 | 8/16/2022 |
1.0.0 | 8,068 | 6/23/2022 |
0.5.0 | 4,275 | 5/27/2022 |
0.5.0-rc | 628 | 5/24/2022 |
0.4.1-rc | 3,017 | 2/22/2022 |
0.4.0-rc | 782 | 2/9/2022 |
0.3.1 | 1,855 | 1/28/2022 |
0.3.0-rc | 1,650 | 11/22/2021 |
0.2.0-rc | 843 | 10/27/2021 |
0.1.0-rc | 3,511 | 9/1/2021 |