diff --git a/.github/workflows/build-complete-samples.yml b/.github/workflows/build-complete-samples.yml
index 9e357bec34..906143cdec 100644
--- a/.github/workflows/build-complete-samples.yml
+++ b/.github/workflows/build-complete-samples.yml
@@ -460,9 +460,9 @@ jobs:
name: 'bot-configuration-app'
version: '6.0.x'
- - project_path: 'samples/bot-configuration-app-auth/csharp/Bot configuration/Bot Configuration.csproj'
+ - project_path: 'samples/bot-configuration-app-auth/csharp/Bot configuration/Bot configuration.csproj'
name: 'bot-configuration-app-auth'
- version: '6.0.x'
+ version: '10.0.x'
- project_path: 'samples/app-HR-talent/csharp/src/TeamsTalentMgmtAppV6.csproj'
name: 'app-HR-talent'
diff --git a/samples/bot-configuration-app-auth/csharp/Bot Configuration.sln b/samples/bot-configuration-app-auth/csharp/Bot Configuration.sln
deleted file mode 100644
index 0033c74f20..0000000000
--- a/samples/bot-configuration-app-auth/csharp/Bot Configuration.sln
+++ /dev/null
@@ -1,37 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 17
-VisualStudioVersion = 17.7.34302.85
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bot Configuration", "Bot configuration\Bot Configuration.csproj", "{783D6E6F-7339-4D74-89D4-B240496CC7A3}"
-EndProject
-Project("{A9E3F50B-275E-4AF7-ADCE-8BE12D41E305}") = "M365Agent", "M365Agent\M365Agent.ttkproj", "{8A5D16E9-1CAF-42D6-8400-75AE6088E9A5}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{5C136CED-CFA6-4839-A70F-F8FAB5EF59CC}"
- ProjectSection(SolutionItems) = preProject
- Bot Configuration.slnLaunch.user = Bot Configuration.slnLaunch.user
- EndProjectSection
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {783D6E6F-7339-4D74-89D4-B240496CC7A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {783D6E6F-7339-4D74-89D4-B240496CC7A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {783D6E6F-7339-4D74-89D4-B240496CC7A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {783D6E6F-7339-4D74-89D4-B240496CC7A3}.Release|Any CPU.Build.0 = Release|Any CPU
- {8A5D16E9-1CAF-42D6-8400-75AE6088E9A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {8A5D16E9-1CAF-42D6-8400-75AE6088E9A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {8A5D16E9-1CAF-42D6-8400-75AE6088E9A5}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
- {8A5D16E9-1CAF-42D6-8400-75AE6088E9A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {8A5D16E9-1CAF-42D6-8400-75AE6088E9A5}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {C0264D40-8A26-4CAF-9DE9-0CFF497234D8}
- EndGlobalSection
-EndGlobal
diff --git a/samples/bot-configuration-app-auth/csharp/Bot Configuration.slnLaunch.user b/samples/bot-configuration-app-auth/csharp/Bot Configuration.slnLaunch.user
index 541f4d3174..0e0a746c40 100644
--- a/samples/bot-configuration-app-auth/csharp/Bot Configuration.slnLaunch.user
+++ b/samples/bot-configuration-app-auth/csharp/Bot Configuration.slnLaunch.user
@@ -1,31 +1,52 @@
[
{
- "Name": "Microsoft Teams (browser)",
+ "Name": "Microsoft 365 Agents Playground (browser)",
"Projects": [
{
- "Path": "Bot configuration\\Bot Configuration.csproj",
- "Action": "Start",
- "DebugTarget": "Start Project"
+ "Path": "M365Agent\\M365Agent.atkproj",
+ "Name": "M365Agent\\M365Agent.atkproj",
+ "Action": "StartWithoutDebugging",
+ "DebugTarget": "Microsoft 365 Agents Playground (browser)"
},
{
- "Path": "M365Agent\\M365Agent.ttkproj",
- "Action": "StartWithoutDebugging",
- "DebugTarget": "Microsoft Teams (browser)"
+ "Path": "Bot configuration\\Bot configuration.csproj",
+ "Name": "Bot configuration\\Bot configuration.csproj",
+ "Action": "Start",
+ "DebugTarget": "Microsoft 365 Agents Playground"
}
]
},
{
- "Name": "Microsoft Teams (browser) (skip update app)",
+ "Name": "Microsoft Teams (browser)",
"Projects": [
{
- "Path": "Bot configuration\\Bot Configuration.csproj",
+ "Path": "M365Agent\\M365Agent.atkproj",
+ "Name": "M365Agent\\M365Agent.atkproj",
+ "Action": "StartWithoutDebugging",
+ "DebugTarget": "Microsoft Teams (browser)"
+ },
+ {
+ "Path": "Bot configuration\\Bot configuration.csproj",
+ "Name": "Bot configuration\\Bot configuration.csproj",
"Action": "Start",
"DebugTarget": "Start Project"
- },
+ }
+ ]
+ },
+ {
+ "Name": "Microsoft Teams (browser) (skip update app)",
+ "Projects": [
{
- "Path": "M365Agent\\M365Agent.ttkproj",
+ "Path": "M365Agent\\M365Agent.atkproj",
+ "Name": "M365Agent\\M365Agent.atkproj",
"Action": "StartWithoutDebugging",
"DebugTarget": "Microsoft Teams (browser) (skip update app)"
+ },
+ {
+ "Path": "Bot configuration\\Bot configuration.csproj",
+ "Name": "Bot configuration\\Bot configuration.csproj",
+ "Action": "Start",
+ "DebugTarget": "Start Project"
}
]
}
diff --git a/samples/bot-configuration-app-auth/csharp/Bot configuration.slnx b/samples/bot-configuration-app-auth/csharp/Bot configuration.slnx
new file mode 100644
index 0000000000..504ac2d8d4
--- /dev/null
+++ b/samples/bot-configuration-app-auth/csharp/Bot configuration.slnx
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/samples/bot-configuration-app-auth/csharp/Bot configuration/.gitignore b/samples/bot-configuration-app-auth/csharp/Bot configuration/.gitignore
index 7466c01f9c..77c7154916 100644
--- a/samples/bot-configuration-app-auth/csharp/Bot configuration/.gitignore
+++ b/samples/bot-configuration-app-auth/csharp/Bot configuration/.gitignore
@@ -5,6 +5,7 @@ env/.env.*.user
env/.env.local
appsettings.Development.json
.deployment
+appsettings.Playground.json
# User-specific files
*.user
@@ -22,4 +23,8 @@ bld/
[Ll]og/
# Notification local store
-.notification.localstore.json
\ No newline at end of file
+.notification.localstore.json
+.notification.playgroundstore.json
+
+# devTools
+devTools/
\ No newline at end of file
diff --git a/samples/bot-configuration-app-auth/csharp/Bot configuration/AdapterWithErrorHandler.cs b/samples/bot-configuration-app-auth/csharp/Bot configuration/AdapterWithErrorHandler.cs
deleted file mode 100644
index c924c6cc78..0000000000
--- a/samples/bot-configuration-app-auth/csharp/Bot configuration/AdapterWithErrorHandler.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-//
-// Generated with Bot Builder V4 SDK Template for Visual Studio CoreBot v4.6.2
-
-using Microsoft.Bot.Builder;
-using Microsoft.Bot.Builder.Integration.AspNet.Core;
-using Microsoft.Bot.Builder.TraceExtensions;
-using Microsoft.Bot.Connector.Authentication;
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.Logging;
-
-namespace Microsoft.Teams.Samples.HelloWorld.Web
-{
- ///
- /// AdapterWithErrorHandler handles errors during bot execution.
- ///
- public class AdapterWithErrorHandler : CloudAdapter
- {
- ///
- /// Initializes a new instance of the class.
- ///
- /// The bot framework authentication.
- /// The logger.
- public AdapterWithErrorHandler(BotFrameworkAuthentication botFrameworkAuthentication, ILogger logger)
- : base(botFrameworkAuthentication, logger)
- {
- OnTurnError = async (turnContext, exception) =>
- {
- // Log any leaked exception from the application.
- logger.LogError(exception, $"[OnTurnError] unhandled error : {exception.Message}");
-
- // Uncomment the line below for local debugging.
- // await turnContext.SendActivityAsync($"Sorry, it looks like something went wrong. Exception Caught: {exception.Message}");
-
- // Send a trace activity, which will be displayed in the Bot Framework Emulator
- await turnContext.TraceActivityAsync("OnTurnError Trace", exception.Message, "https://www.botframework.com/schemas/error", "TurnError");
- };
- }
- }
-}
diff --git a/samples/bot-configuration-app-auth/csharp/Bot configuration/Bot Configuration.csproj b/samples/bot-configuration-app-auth/csharp/Bot configuration/Bot Configuration.csproj
index e65308dbe5..81958d0257 100644
--- a/samples/bot-configuration-app-auth/csharp/Bot configuration/Bot Configuration.csproj
+++ b/samples/bot-configuration-app-auth/csharp/Bot configuration/Bot Configuration.csproj
@@ -1,26 +1,30 @@
-
+
- net6.0
- latest
+ net10.0
+ enable
+ enable
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
- Always
+
+
+ PreserveNewest
+ None
+
+
+
+ PreserveNewest
+ None
-
\ No newline at end of file
diff --git a/samples/bot-configuration-app-auth/csharp/Bot configuration/Bots/TeamsBot.cs b/samples/bot-configuration-app-auth/csharp/Bot configuration/Bots/TeamsBot.cs
deleted file mode 100644
index b6288c05fe..0000000000
--- a/samples/bot-configuration-app-auth/csharp/Bot configuration/Bots/TeamsBot.cs
+++ /dev/null
@@ -1,144 +0,0 @@
-using AdaptiveCards;
-using Bogus.DataSets;
-using Microsoft.Bot.Builder;
-using Microsoft.Bot.Builder.Teams;
-using Microsoft.Bot.Schema;
-using Microsoft.Bot.Schema.Teams;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Net.Http;
-using System.Net;
-using System.Threading;
-using System.Threading.Tasks;
-using System.IO;
-
-namespace Botconfiguration.Bots
-{
- ///
- /// TeamsBot class handles bot activities for Microsoft Teams.
- ///
- public class TeamsBot : TeamsActivityHandler
- {
- private string _chosenFlow = string.Empty;
-
- ///
- /// Handles the event when members are added to the channel.
- ///
- /// List of members added.
- /// Turn context.
- /// Cancellation token.
- protected override async Task OnMembersAddedAsync(IList membersAdded, ITurnContext turnContext, CancellationToken cancellationToken)
- {
- const string imagePath = "Images/configbutton.png";
- var imageData = Convert.ToBase64String(await File.ReadAllBytesAsync(imagePath));
-
- var adaptiveCardJson = $@"
- {{
- ""$schema"": ""http://adaptivecards.io/schemas/adaptive-card.json"",
- ""type"": ""AdaptiveCard"",
- ""version"": ""1.0"",
- ""body"": [
- {{
- ""type"": ""TextBlock"",
- ""text"": ""Hello and welcome! With this sample, you can experience the functionality of bot configuration. To access Bot configuration, click on the settings button in the bot description card."",
- ""wrap"": true,
- ""size"": ""large"",
- ""weight"": ""bolder""
- }},
- {{
- ""type"": ""Image"",
- ""url"": ""data:image/png;base64,{imageData}"",
- ""size"": ""auto""
- }}
- ],
- ""fallbackText"": ""This card requires Adaptive Card support.""
- }}";
-
- var attachment = new Attachment
- {
- ContentType = AdaptiveCard.ContentType,
- Content = JsonConvert.DeserializeObject(adaptiveCardJson)
- };
-
- var reply = MessageFactory.Attachment(attachment);
- await turnContext.SendActivityAsync(reply, cancellationToken);
- }
-
- ///
- /// Handles the event when a message activity is received.
- ///
- /// Turn context.
- /// Cancellation token.
- protected override async Task OnMessageActivityAsync(ITurnContext turnContext, CancellationToken cancellationToken)
- {
- var activity = turnContext.Activity;
- if (!string.IsNullOrEmpty(activity.Text))
- {
- var text = activity.Text.ToLower().Trim();
- if (text == "chosen flow" || text == "typeahead search adaptive card chosen flow")
- {
- await turnContext.SendActivityAsync($"Bot configured for {_chosenFlow} flow", cancellationToken: cancellationToken);
- }
- }
- else if (activity.Value != null)
- {
- await turnContext.SendActivityAsync($"Selected option is: {activity.Value}", cancellationToken: cancellationToken);
- }
- }
-
- ///
- /// Handles the event when a configuration fetch is requested.
- ///
- /// Turn context.
- /// Configuration data.
- /// Cancellation token.
- /// Configuration response.
- protected override Task OnTeamsConfigFetchAsync(ITurnContext turnContext, JObject configData, CancellationToken cancellationToken)
- {
- var response = new ConfigResponse
- {
- Config = new BotConfigAuth
- {
- SuggestedActions = new SuggestedActions
- {
- Actions = new List
- {
- new CardAction
- {
- Type = ActionTypes.OpenUrl,
- Title = "Sign in to this app",
- Value = "https://example.com/auth"
- }
- }
- },
- Type = "auth"
- }
- };
- return Task.FromResult(response);
- }
-
- ///
- /// Handles the event when a configuration submit is requested.
- ///
- /// Turn context.
- /// Configuration data.
- /// Cancellation token.
- /// Configuration response.
- protected override Task OnTeamsConfigSubmitAsync(ITurnContext turnContext, JObject configData, CancellationToken cancellationToken)
- {
- var response = new ConfigResponse
- {
- Config = new TaskModuleMessageResponse
- {
- Type = "message",
- Value = "You have chosen to finish setting up bot"
- }
- };
-
- return Task.FromResult(response);
- }
- }
-}
\ No newline at end of file
diff --git a/samples/bot-configuration-app-auth/csharp/Bot configuration/Config.cs b/samples/bot-configuration-app-auth/csharp/Bot configuration/Config.cs
new file mode 100644
index 0000000000..9f79e2b2b3
--- /dev/null
+++ b/samples/bot-configuration-app-auth/csharp/Bot configuration/Config.cs
@@ -0,0 +1,17 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+namespace Bot_configuration
+{
+ public class ConfigOptions
+ {
+ public TeamsConfigOptions Teams { get; set; }
+ }
+
+ public class TeamsConfigOptions
+ {
+ public string ClientId { get; set; }
+ public string ClientSecret { get; set; }
+ public string TenantId { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/samples/bot-configuration-app-auth/csharp/Bot configuration/Controllers/BotController.cs b/samples/bot-configuration-app-auth/csharp/Bot configuration/Controllers/BotController.cs
deleted file mode 100644
index 80da0b44fd..0000000000
--- a/samples/bot-configuration-app-auth/csharp/Bot configuration/Controllers/BotController.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-//
-// Generated with Bot Builder V4 SDK Template for Visual Studio EchoBot v4.6.2
-
-using Microsoft.AspNetCore.Mvc;
-using Microsoft.Bot.Builder;
-using Microsoft.Bot.Builder.Integration.AspNet.Core;
-using System.Threading.Tasks;
-
-namespace Botconfiguration.Controllers
-{
- // This ASP Controller is created to handle a request. Dependency Injection will provide the Adapter and IBot
- // implementation at runtime. Multiple different IBot implementations running at different endpoints can be
- // achieved by specifying a more specific type for the bot constructor argument.
- [Route("api/messages")]
- [ApiController]
- public class BotController : ControllerBase
- {
- private readonly CloudAdapter Adapter;
- private readonly IBot Bot;
-
- public BotController(CloudAdapter adapter, IBot bot)
- {
- Adapter = adapter;
- Bot = bot;
- }
-
- [HttpPost]
- public async Task PostAsync()
- {
- // Delegate the processing of the HTTP POST to the adapter.
- // The adapter will invoke the bot.
- await Adapter.ProcessAsync(Request, Response, Bot);
- }
- }
-}
\ No newline at end of file
diff --git a/samples/bot-configuration-app-auth/csharp/Bot configuration/Controllers/Controller.cs b/samples/bot-configuration-app-auth/csharp/Bot configuration/Controllers/Controller.cs
new file mode 100644
index 0000000000..9f4eebbc26
--- /dev/null
+++ b/samples/bot-configuration-app-auth/csharp/Bot configuration/Controllers/Controller.cs
@@ -0,0 +1,153 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using Microsoft.Teams.Api.Activities;
+using Microsoft.Teams.Apps;
+using Microsoft.Teams.Apps.Activities;
+using Microsoft.Teams.Apps.Activities.Invokes;
+using Microsoft.Teams.Apps.Annotations;
+using Microsoft.Teams.Cards;
+using System.Text.Json;
+
+namespace Bot_configuration.Controllers
+{
+ ///
+ /// Teams SDK v2 Controller for Bot Configuration Sample
+ /// Demonstrates bot configuration through settings button (config invoke activities)
+ ///
+ [TeamsController]
+ public class Controller
+ {
+ private static string _chosenFlow = string.Empty;
+
+ ///
+ /// Handles conversation members added event
+ /// Sends welcome message with configuration instructions
+ ///
+ [Conversation.MembersAdded]
+ public async Task OnMembersAdded([Context] ConversationUpdateActivity activity, [Context] IContext.Client client, [Context] Microsoft.Teams.Common.Logging.ILogger log)
+ {
+ const string imagePath = "Images/configbutton.png";
+ string imageData = string.Empty;
+ if (File.Exists(imagePath))
+ {
+ imageData = Convert.ToBase64String(File.ReadAllBytes(imagePath));
+ }
+ var card = new Microsoft.Teams.Cards.AdaptiveCard
+ {
+ Body = new List
+ {
+ new TextBlock("Hello and welcome! With this sample, you can experience the functionality of bot configuration. To access Bot configuration, click on the settings button in the bot description card.")
+ {
+ Wrap = true,
+ Size = TextSize.Large,
+ Weight = TextWeight.Bolder
+ }
+ }
+ };
+ if (!string.IsNullOrEmpty(imageData))
+ {
+ card.Body.Add(new Image($"data:image/png;base64,{imageData}"));
+ }
+ await client.Send(card);
+ }
+
+ ///
+ /// Handles incoming messages
+ ///
+ [Message]
+ public async Task OnMessage([Context] MessageActivity activity, [Context] IContext.Client client, [Context] Microsoft.Teams.Common.Logging.ILogger log)
+ {
+ if (!string.IsNullOrEmpty(activity.Text))
+ {
+ var text = activity.Text.ToLower().Trim();
+ if (text == "chosen flow" || text.Contains("chosen flow"))
+ {
+ var response = string.IsNullOrEmpty(_chosenFlow)
+ ? "No flow has been configured yet. Please use the settings button to configure the bot."
+ : $"Bot configured for {_chosenFlow} flow";
+
+ await client.Send(response);
+ }
+ else
+ {
+ await client.Send($"You said: '{activity.Text}'\n\nTry sending 'chosen flow' to check configuration.");
+ }
+ }
+ else if (activity.Value != null)
+ {
+ await client.Send($"Selected option is: {activity.Value}");
+ }
+ }
+
+ ///
+ /// Handles config/fetch invoke - Shows auth dialog when settings button is clicked
+ /// Replaces OnTeamsConfigFetchAsync from Bot Builder SDK
+ ///
+ [Invoke("config/fetch")]
+ public object OnConfigFetch([Context] InvokeActivity activity, [Context] Microsoft.Teams.Common.Logging.ILogger log)
+ {
+ return new
+ {
+ config = new
+ {
+ type = "auth",
+ suggestedActions = new
+ {
+ actions = new[]
+ {
+ new
+ {
+ type = "openUrl",
+ title = "Sign in to this app",
+ value = "https://example.com/auth"
+ }
+ }
+ }
+ }
+ };
+ }
+
+ ///
+ /// Handles config/submit invoke - Processes configuration submission
+ /// Replaces OnTeamsConfigSubmitAsync from Bot Builder SDK
+ ///
+ [Invoke("config/submit")]
+ public async Task