Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 23 additions & 7 deletions src/Microsoft.Agents.SDK.sln
Original file line number Diff line number Diff line change
Expand Up @@ -71,17 +71,17 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Agents.Builder.Te
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Agents.State.Tests", "tests\Microsoft.Agents.State.Tests\Microsoft.Agents.State.Tests.csproj", "{71813B2D-D6A8-4388-9541-9B1287C93F19}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Agents.Hosting.AspNetCore.Tests", "tests\Microsoft.Agents.Hosting.AspNetCore\Microsoft.Agents.Hosting.AspNetCore.Tests.csproj", "{7D1A1CE5-6D9B-4D31-AC77-C3B1787F575D}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Agents.Hosting.AspNetCore.Tests", "tests\Microsoft.Agents.Hosting.AspNetCore\Microsoft.Agents.Hosting.AspNetCore.Tests.csproj", "{7D1A1CE5-6D9B-4D31-AC77-C3B1787F575D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Agents.Authentication.Msal.Tests", "tests\Microsoft.Agents.Authentication.Msal.Tests\Microsoft.Agents.Authentication.Msal.Tests.csproj", "{B9AD64EF-EA22-4CAC-B89B-03CEE46CFF4F}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Agents.Authentication.Msal.Tests", "tests\Microsoft.Agents.Authentication.Msal.Tests\Microsoft.Agents.Authentication.Msal.Tests.csproj", "{B9AD64EF-EA22-4CAC-B89B-03CEE46CFF4F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Agents.TestSupport", "tests\Microsoft.Agents.TestSupport\Microsoft.Agents.TestSupport.csproj", "{8DF6799A-AB3E-49A9-9A2A-8BBED20AB0BC}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Agents.TestSupport", "tests\Microsoft.Agents.TestSupport\Microsoft.Agents.TestSupport.csproj", "{8DF6799A-AB3E-49A9-9A2A-8BBED20AB0BC}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions", "Extensions", "{927E4F54-6FBC-4390-BF64-BF3C1874C1AB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Agents.Extensions.SharePoint", "libraries\Extensions\Microsoft.Agents.Extensions.SharePoint\Microsoft.Agents.Extensions.SharePoint.csproj", "{A8EDAEA3-4057-4862-BC92-F9CFA645246A}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Agents.Extensions.SharePoint", "libraries\Extensions\Microsoft.Agents.Extensions.SharePoint\Microsoft.Agents.Extensions.SharePoint.csproj", "{A8EDAEA3-4057-4862-BC92-F9CFA645246A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Agents.Extensions.Teams", "libraries\Extensions\Microsoft.Agents.Extensions.Teams\Microsoft.Agents.Extensions.Teams.csproj", "{348A61E5-E16A-47ED-B621-F2C61E1E316D}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Agents.Extensions.Teams", "libraries\Extensions\Microsoft.Agents.Extensions.Teams\Microsoft.Agents.Extensions.Teams.csproj", "{348A61E5-E16A-47ED-B621-F2C61E1E316D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CopilotStudioClient", "CopilotStudioClient", "{295CD61D-DB20-4DF5-A917-2665DB79A6E4}"
EndProject
Expand All @@ -95,12 +95,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TeamsConversationSsoQuickst
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AgentToAgent", "AgentToAgent", "{E87BA6D5-6007-408C-B01A-916F3F86F28A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Agent1", "samples\AgentToAgent\Agent1\Agent1.csproj", "{7B41FB1B-F45C-41B7-B064-EB1BECB5BD49}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Agent1", "samples\AgentToAgent\Agent1\Agent1.csproj", "{7B41FB1B-F45C-41B7-B064-EB1BECB5BD49}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Agent2", "samples\AgentToAgent\Agent2\Agent2.csproj", "{D13DF019-D0FF-400F-AFD3-05B62C8C6FA6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoSignIn", "samples\Authorization\AutoSignIn\AutoSignIn.csproj", "{6DFD9752-2D4B-4CE7-B9D6-42E7DB1A9A7D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EchoAgent", "samples\EchoAgent\EchoAgent.csproj", "{A45D3004-BEC0-4320-84CC-8ED471D4C3B2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StreamingMessageAgent", "samples\StreamingMessageAgent\StreamingMessageAgent.csproj", "{39EE2E61-D48F-4FF1-9C81-D98554587F0C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StreamingAgent1", "samples\AgentToAgent\StreamingAgent1\StreamingAgent1.csproj", "{0D042B49-6059-487F-B449-2C098433977C}"
Expand All @@ -113,7 +115,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DialogRootBot", "samples\Co
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DialogSkillBot", "samples\Compat\SkillsDialog\DialogSkillBot\DialogSkillBot.csproj", "{AD401416-D318-1F5D-AD79-EEF717EF8155}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Agents.Authentication.Tests", "tests\Microsoft.Agents.Authentication.Tests\Microsoft.Agents.Authentication.Tests.csproj", "{2D522479-7808-6236-5B86-F9653C2F2D0A}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Agents.Authentication.Tests", "tests\Microsoft.Agents.Authentication.Tests\Microsoft.Agents.Authentication.Tests.csproj", "{2D522479-7808-6236-5B86-F9653C2F2D0A}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Teams", "Teams", "{7B116E04-6BB0-46B4-B055-D85443A27822}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HeaderPropagation", "samples\Teams\HeaderPropagation\HeaderPropagation.csproj", "{51269A39-C6D5-436C-80F6-7C1644FDA696}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Authorization", "Authorization", "{0F9D3F0D-C131-4D3B-A86F-59CC781E8A02}"
EndProject
Expand Down Expand Up @@ -293,6 +299,14 @@ Global
{2D522479-7808-6236-5B86-F9653C2F2D0A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2D522479-7808-6236-5B86-F9653C2F2D0A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2D522479-7808-6236-5B86-F9653C2F2D0A}.Release|Any CPU.Build.0 = Release|Any CPU
{51269A39-C6D5-436C-80F6-7C1644FDA696}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{51269A39-C6D5-436C-80F6-7C1644FDA696}.Debug|Any CPU.Build.0 = Debug|Any CPU
{51269A39-C6D5-436C-80F6-7C1644FDA696}.Release|Any CPU.ActiveCfg = Release|Any CPU
{51269A39-C6D5-436C-80F6-7C1644FDA696}.Release|Any CPU.Build.0 = Release|Any CPU
{72503E70-31C3-82E3-1E1D-52A6B0C5A808}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{72503E70-31C3-82E3-1E1D-52A6B0C5A808}.Debug|Any CPU.Build.0 = Debug|Any CPU
{72503E70-31C3-82E3-1E1D-52A6B0C5A808}.Release|Any CPU.ActiveCfg = Release|Any CPU
{72503E70-31C3-82E3-1E1D-52A6B0C5A808}.Release|Any CPU.Build.0 = Release|Any CPU
{E951C602-E9ED-F77D-8FC9-5272DB90D1DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E951C602-E9ED-F77D-8FC9-5272DB90D1DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E951C602-E9ED-F77D-8FC9-5272DB90D1DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand Down Expand Up @@ -363,6 +377,8 @@ Global
{087CEF80-A51A-77C6-227D-7AF40A1E0770} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{AD401416-D318-1F5D-AD79-EEF717EF8155} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{2D522479-7808-6236-5B86-F9653C2F2D0A} = {AD743B78-D61F-4FBF-B620-FA83CE599A50}
{7B116E04-6BB0-46B4-B055-D85443A27822} = {674A812C-7287-4883-97F9-697D83750648}
{51269A39-C6D5-436C-80F6-7C1644FDA696} = {7B116E04-6BB0-46B4-B055-D85443A27822}
{0F9D3F0D-C131-4D3B-A86F-59CC781E8A02} = {674A812C-7287-4883-97F9-697D83750648}
{E951C602-E9ED-F77D-8FC9-5272DB90D1DD} = {674A812C-7287-4883-97F9-697D83750648}
{A6785A2A-A4C2-8F38-E9BB-4C5FD229F1F9} = {674A812C-7287-4883-97F9-697D83750648}
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
49 changes: 49 additions & 0 deletions src/samples/Teams/HeaderPropagation/AppManifest/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/teams/v1.16/MicrosoftTeams.schema.json",
"manifestVersion": "1.16",
"version": "1.0.0",
"id": "<<AAD_APP_CLIENT_ID>>",
"packageName": "com.Microsoft.Agents.Extensions.Teams.HeaderPropagation",
"developer": {
"name": "Microsoft",
"websiteUrl": "https://example.azurewebsites.net",
"privacyUrl": "https://example.azurewebsites.net/privacy",
"termsOfUseUrl": "https://example.azurewebsites.net/termsofuse"
},
"icons": {
"outline": "outline.png",
"color": "color.png"
},
"name": {
"short": "Header Propagation",
"full": "Header Propagation"
},
"description": {
"short": "Teams bot with header propagation.",
"full": "This sample demonstrates how to enable the header propagation feature in a Teams bot."
},
"accentColor": "#FFFFFF",
"bots": [
{
"botId": "<<AAD_APP_CLIENT_ID>>",
"scopes": [
"personal"
],
"isNotificationOnly": false,
"supportsCalling": false,
"supportsVideo": false,
"supportsFiles": false
}
],
"permissions": [
"identity",
"messageTeamMembers"
],
"validDomains": [
"token.botframework.com"
],
"webApplicationInfo": {
"id": "<<AAD_APP_CLIENT_ID>>",
"resource": "api://botid-<<AAD_APP_CLIENT_ID>>"
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions src/samples/Teams/HeaderPropagation/ConversationStateExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using Microsoft.Agents.Builder.State;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not clear what is going on here, Why do you need this?

using Microsoft.Agents.Core.Models;

namespace HeaderPropagation;

public static class ConversationStateExtensions
{
public static void SaveActivity(this ConversationState state, IActivity activity)
{
state.SetValue($"history/{activity.Id}", activity);
}

public static IActivity GetActivity(this ConversationState state, string activityId)
{
return state.GetValue<IActivity>($"history/{activityId}");
}
}
27 changes: 27 additions & 0 deletions src/samples/Teams/HeaderPropagation/HeaderPropagation.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<LangVersion>latest</LangVersion>
<ImplicitUsings>disable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<Compile Remove="wwwroot\**" />
<Content Remove="wwwroot\**" />
<EmbeddedResource Remove="wwwroot\**" />
<None Remove="wwwroot\**" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\libraries\Authentication\Authentication.Msal\Microsoft.Agents.Authentication.Msal.csproj" />
<ProjectReference Include="..\..\..\libraries\Hosting\AspNetCore\Microsoft.Agents.Hosting.AspNetCore.csproj" />
<ProjectReference Include="..\..\..\libraries\Extensions\Microsoft.Agents.Extensions.Teams\Microsoft.Agents.Extensions.Teams.csproj" />
</ItemGroup>

<ItemGroup>
<Content Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>
50 changes: 50 additions & 0 deletions src/samples/Teams/HeaderPropagation/MyAgent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using Microsoft.Agents.Builder;
using Microsoft.Agents.Builder.App;
using Microsoft.Agents.Builder.State;
using Microsoft.Agents.Core.Models;
using Microsoft.Agents.Extensions.Teams.App;
using System.Threading.Tasks;
using System.Threading;

namespace HeaderPropagation;

public class MyAgent : AgentApplication
{
public MyAgent(AgentApplicationOptions options) : base(options)
{
RegisterExtension(new TeamsAgentExtension(this), (ext) =>
{
ext.OnMessageEdit(OnMessageEditAsync);
});
OnConversationUpdate(ConversationUpdateEvents.MembersAdded, WelcomeMessageAsync);
OnActivity(ActivityTypes.Message, OnMessageAsync, rank: RouteRank.Last);
}

private async Task OnMessageEditAsync(ITurnContext turnContext, ITurnState turnState, CancellationToken cancellationToken)
{
var prevActivity = turnState.Conversation.GetActivity(turnContext.Activity.Id);

await turnContext.SendActivityAsync($"Activity '{prevActivity.Id}' modified from '{prevActivity.Text}' to '{turnContext.Activity.Text}'", cancellationToken: cancellationToken);
}

private async Task WelcomeMessageAsync(ITurnContext turnContext, ITurnState turnState, CancellationToken cancellationToken)
{
foreach (ChannelAccount member in turnContext.Activity.MembersAdded)
{
if (member.Id != turnContext.Activity.Recipient.Id)
{
await turnContext.SendActivityAsync(MessageFactory.Text("Hello and Welcome!"), cancellationToken);
}
}
}

private async Task OnMessageAsync(ITurnContext turnContext, ITurnState turnState, CancellationToken cancellationToken)
{
turnState.Conversation.SaveActivity(turnContext.Activity);

await turnContext.SendActivityAsync($"You said: {turnContext.Activity.Text}", cancellationToken: cancellationToken);
}
}
51 changes: 51 additions & 0 deletions src/samples/Teams/HeaderPropagation/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using HeaderPropagation;
using Microsoft.Agents.Builder;
using Microsoft.Agents.Hosting.AspNetCore;
using Microsoft.Agents.Storage;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System.Threading;

WebApplicationBuilder builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();
builder.Services.AddHttpClient();
builder.Logging.AddConsole();

// Add AgentApplicationOptions from config.
builder.AddAgentApplicationOptions();

// Add the Agent
builder.AddAgent<MyAgent>();

// Register IStorage. For development, MemoryStorage is suitable.
// For production Agents, persisted storage should be used so
// that state survives Agent restarts, and operate correctly
// in a cluster of Agent instances.
builder.Services.AddSingleton<IStorage, MemoryStorage>();

WebApplication app = builder.Build();

// Configure the HTTP request pipeline.
app.UseRouting();

// Add the HeaderPropagation middleware to propagate incoming request headers to outgoing ones.
app.UseHeaderPropagation();

app.MapGet("/", () => "Microsoft Agents SDK Sample");
app.MapPost("/api/messages", async (HttpRequest request, HttpResponse response, IAgentHttpAdapter adapter, IAgent agent, CancellationToken cancellationToken) =>
{
await adapter.ProcessAsync(request, response, agent, cancellationToken);
})
.AllowAnonymous();

// Hardcoded for brevity and ease of testing.
// In production, this should be set in configuration.
app.Urls.Add($"http://localhost:3978");

app.Run();
90 changes: 90 additions & 0 deletions src/samples/Teams/HeaderPropagation/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# HeaderPropagation Sample

This sample shows how to enable the Header Propagation feature to capture all incoming request headers and propagate them to outgoing requests.
To achieve this behavior, the header propagation functionality requires the bot to use the `Extensions.Teams` package, as it contains the necessary configuration to decide which headers are going to be propagated to outgoing requests.

Additionally, to enable this functionality, the Header Propagation middleware is required as follows:
```cs
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

// Add the HeaderPropagation middleware to propagate incoming request headers to outgoing ones.
app.UseHeaderPropagation();
```

## Prerequisites

- Microsoft Teams is installed and you have an account (not a guest account)
- [.Net](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) version 8.0
- [dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows)
- [M365 developer account](https://docs.microsoft.com/en-us/microsoftteams/platform/concepts/build-and-test/prepare-your-o365-tenant) or access to a Teams account with the appropriate permissions to install an app.

## Running this sample

**To run the sample connected to Azure Bot Service, the following additional tools are required:**

1. [Create an Azure Bot](https://aka.ms/AgentsSDK-CreateBot)
- Be sure to add the Teams Channel
- Record the Application ID, the Tenant ID, and the Client Secret for use below

1. Configuring the token connection in the Agent settings
> The instructions for this sample are for a SingleTenant Azure Bot using ClientSecrets. The token connection configuration will vary if a different type of Azure Bot was configured. For more information see [DotNet MSAL Authentication provider](https://aka.ms/AgentsSDK-DotNetMSALAuth)

1. Open the `appsettings.json` file in the root of the sample project.

1. Find the section labeled `Connections`, it should appear similar to this:

```json
"TokenValidation": {
"Audiences": [
"{{ClientId}}" // this is the Client ID used for the Azure Bot
],
"TenantId": "{{TenantId}}"
},

"Connections": {
"ServiceConnection": {
"Settings": {
"AuthType": "ClientSecret", // this is the AuthType for the connection, valid values can be found in Microsoft.Agents.Authentication.Msal.Model.AuthTypes. The default is ClientSecret.
"AuthorityEndpoint": "https://login.microsoftonline.com/{{TenantId}}",
"ClientId": "{{ClientId}}", // this is the Client ID used for the connection.
"ClientSecret": "00000000-0000-0000-0000-000000000000", // this is the Client Secret used for the connection.
"Scopes": [
"https://api.botframework.com/.default"
]
}
}
},
```

1. Replace all **{{ClientId}}** with the AppId of the Azure Bot.
1. Replace all **{{TenantId}}** with the Tenant Id where your application is registered.
1. Set the **ClientSecret** to the Secret that was created for your identity.

> Storing sensitive values in appsettings is not recommended. Follow [AspNet Configuration](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-9.0) for best practices.

1. Manually update the manifest.json
- Edit the `manifest.json` contained in the `/appManifest` folder
- Replace with your AppId (that was created above) *everywhere* you see the place holder string `<<AAD_APP_CLIENT_ID>>`
- Replace `<<BOT_DOMAIN>>` with your Agent url. For example, the tunnel host name.
- Zip up the contents of the `/appManifest` folder to create a `manifest.zip`
1. Upload the `manifest.zip` to Teams
- Select **Developer Portal** in the Teams left sidebar
- Select **Apps** (top row)
- Select **Import app**, and select the manifest.zip

1. Run `dev tunnels`. Please follow [Create and host a dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) and host the tunnel with anonymous user access command as shown below:
> NOTE: Go to your project directory and open the `./Properties/launchSettings.json` file. Check the port number and use that port number in the devtunnel command (instead of 3978).

```bash
devtunnel host -p 3978 --allow-anonymous
```

1. On the Azure Bot, select **Settings**, then **Configuration**, and update the **Messaging endpoint** to `{tunnel-url}/api/messages`

1. Start the Agent, and select **Preview in Teams** in the upper right corner

1. Send a message and the bot will respond with an Echo.

## Further reading
To learn more about building Agents, see our [Microsoft 365 Agents SDK](https://github.com/microsoft/agents) repo.
Loading