diff --git a/samples/BotPowered-BasicAce/.gitignore b/samples/BotPowered-BasicAce-CollectFeedback/.gitignore similarity index 100% rename from samples/BotPowered-BasicAce/.gitignore rename to samples/BotPowered-BasicAce-CollectFeedback/.gitignore diff --git a/samples/BotPowered-BasicAce-CollectFeedback/AdapterWithErrorHandler.cs b/samples/BotPowered-BasicAce-CollectFeedback/AdapterWithErrorHandler.cs new file mode 100644 index 00000000..69b7ef45 --- /dev/null +++ b/samples/BotPowered-BasicAce-CollectFeedback/AdapterWithErrorHandler.cs @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Generated with Bot Builder V4 SDK Template for Visual Studio CoreBot v4.18.1 + +using Microsoft.Bot.Builder.Integration.AspNet.Core; +using Microsoft.Bot.Builder.TraceExtensions; +using Microsoft.Bot.Connector.Authentication; +using Microsoft.Extensions.Logging; + +namespace BotPowered_BasicAce_CollectFeedback +{ + public class AdapterWithErrorHandler : CloudAdapter + { + public AdapterWithErrorHandler(BotFrameworkAuthentication auth, ILogger logger) + : base(auth, logger) + { + OnTurnError = async (turnContext, exception) => + { + // Log any leaked exception from the application. + logger.LogError(exception, $"[OnTurnError] unhandled error : {exception.Message}"); + + // Send a message to the user + await turnContext.SendActivityAsync("The bot encountered an error or bug."); + await turnContext.SendActivityAsync("To continue to run this bot, please fix the bot source code."); + + // 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/BotPowered-BasicAce-CollectFeedback/BotPowered-BasicAce-CollectFeedback.csproj b/samples/BotPowered-BasicAce-CollectFeedback/BotPowered-BasicAce-CollectFeedback.csproj new file mode 100644 index 00000000..3a8592c4 --- /dev/null +++ b/samples/BotPowered-BasicAce-CollectFeedback/BotPowered-BasicAce-CollectFeedback.csproj @@ -0,0 +1,22 @@ + + + + net6.0 + latest + 262d8d01-f61b-48a2-9baa-31539b075b0a + $(MSBuildProjectName.Replace(" ", "_").Replace("-", "_")) + + + + + + + + + + + Always + + + + diff --git a/samples/BotPowered-BasicAce-CollectFeedback/BotPowered-BasicAce-CollectFeedback.sln b/samples/BotPowered-BasicAce-CollectFeedback/BotPowered-BasicAce-CollectFeedback.sln new file mode 100644 index 00000000..44e22f69 --- /dev/null +++ b/samples/BotPowered-BasicAce-CollectFeedback/BotPowered-BasicAce-CollectFeedback.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.6.33829.357 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotPowered-BasicAce-CollectFeedback", "BotPowered-BasicAce-CollectFeedback.csproj", "{C4EF0E19-232D-4F9B-ADB6-84B07D37C473}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C4EF0E19-232D-4F9B-ADB6-84B07D37C473}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C4EF0E19-232D-4F9B-ADB6-84B07D37C473}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C4EF0E19-232D-4F9B-ADB6-84B07D37C473}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C4EF0E19-232D-4F9B-ADB6-84B07D37C473}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {503AEAB0-93C3-462B-8F7E-7CF7F0EC9878} + EndGlobalSection +EndGlobal diff --git a/samples/BotPowered-BasicAce-CollectFeedback/Controllers/BotController.cs b/samples/BotPowered-BasicAce-CollectFeedback/Controllers/BotController.cs new file mode 100644 index 00000000..f3caeb0e --- /dev/null +++ b/samples/BotPowered-BasicAce-CollectFeedback/Controllers/BotController.cs @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Generated with Bot Builder V4 SDK Template for Visual Studio EmptyBot v4.18.1 + +using Microsoft.AspNetCore.Mvc; +using Microsoft.Bot.Builder; +using Microsoft.Bot.Builder.Integration.AspNet.Core; +using System.Threading.Tasks; + +namespace BotPowered_BasicAce_CollectFeedback.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 IBotFrameworkHttpAdapter _adapter; + private readonly IBot _bot; + + public BotController(IBotFrameworkHttpAdapter adapter, IBot bot) + { + _adapter = adapter; + _bot = bot; + } + + [HttpPost] + [HttpGet] + 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); + } + } +} diff --git a/samples/BotPowered-BasicAce/DeploymentTemplates/DeployUseExistResourceGroup/parameters-for-template-AzureBot-with-rg.json b/samples/BotPowered-BasicAce-CollectFeedback/DeploymentTemplates/DeployUseExistResourceGroup/parameters-for-template-AzureBot-with-rg.json similarity index 100% rename from samples/BotPowered-BasicAce/DeploymentTemplates/DeployUseExistResourceGroup/parameters-for-template-AzureBot-with-rg.json rename to samples/BotPowered-BasicAce-CollectFeedback/DeploymentTemplates/DeployUseExistResourceGroup/parameters-for-template-AzureBot-with-rg.json diff --git a/samples/BotPowered-BasicAce/DeploymentTemplates/DeployUseExistResourceGroup/parameters-for-template-BotApp-with-rg.json b/samples/BotPowered-BasicAce-CollectFeedback/DeploymentTemplates/DeployUseExistResourceGroup/parameters-for-template-BotApp-with-rg.json similarity index 100% rename from samples/BotPowered-BasicAce/DeploymentTemplates/DeployUseExistResourceGroup/parameters-for-template-BotApp-with-rg.json rename to samples/BotPowered-BasicAce-CollectFeedback/DeploymentTemplates/DeployUseExistResourceGroup/parameters-for-template-BotApp-with-rg.json diff --git a/samples/BotPowered-BasicAce/DeploymentTemplates/DeployUseExistResourceGroup/readme.md b/samples/BotPowered-BasicAce-CollectFeedback/DeploymentTemplates/DeployUseExistResourceGroup/readme.md similarity index 100% rename from samples/BotPowered-BasicAce/DeploymentTemplates/DeployUseExistResourceGroup/readme.md rename to samples/BotPowered-BasicAce-CollectFeedback/DeploymentTemplates/DeployUseExistResourceGroup/readme.md diff --git a/samples/BotPowered-BasicAce/DeploymentTemplates/DeployUseExistResourceGroup/template-AzureBot-with-rg.json b/samples/BotPowered-BasicAce-CollectFeedback/DeploymentTemplates/DeployUseExistResourceGroup/template-AzureBot-with-rg.json similarity index 100% rename from samples/BotPowered-BasicAce/DeploymentTemplates/DeployUseExistResourceGroup/template-AzureBot-with-rg.json rename to samples/BotPowered-BasicAce-CollectFeedback/DeploymentTemplates/DeployUseExistResourceGroup/template-AzureBot-with-rg.json diff --git a/samples/BotPowered-BasicAce/DeploymentTemplates/DeployUseExistResourceGroup/template-BotApp-with-rg.json b/samples/BotPowered-BasicAce-CollectFeedback/DeploymentTemplates/DeployUseExistResourceGroup/template-BotApp-with-rg.json similarity index 100% rename from samples/BotPowered-BasicAce/DeploymentTemplates/DeployUseExistResourceGroup/template-BotApp-with-rg.json rename to samples/BotPowered-BasicAce-CollectFeedback/DeploymentTemplates/DeployUseExistResourceGroup/template-BotApp-with-rg.json diff --git a/samples/BotPowered-BasicAce/DeploymentTemplates/DeployWithNewResourceGroup/parameters-for-template-AzureBot-new-rg.json b/samples/BotPowered-BasicAce-CollectFeedback/DeploymentTemplates/DeployWithNewResourceGroup/parameters-for-template-AzureBot-new-rg.json similarity index 100% rename from samples/BotPowered-BasicAce/DeploymentTemplates/DeployWithNewResourceGroup/parameters-for-template-AzureBot-new-rg.json rename to samples/BotPowered-BasicAce-CollectFeedback/DeploymentTemplates/DeployWithNewResourceGroup/parameters-for-template-AzureBot-new-rg.json diff --git a/samples/BotPowered-BasicAce/DeploymentTemplates/DeployWithNewResourceGroup/parameters-for-template-BotApp-new-rg.json b/samples/BotPowered-BasicAce-CollectFeedback/DeploymentTemplates/DeployWithNewResourceGroup/parameters-for-template-BotApp-new-rg.json similarity index 100% rename from samples/BotPowered-BasicAce/DeploymentTemplates/DeployWithNewResourceGroup/parameters-for-template-BotApp-new-rg.json rename to samples/BotPowered-BasicAce-CollectFeedback/DeploymentTemplates/DeployWithNewResourceGroup/parameters-for-template-BotApp-new-rg.json diff --git a/samples/BotPowered-BasicAce/DeploymentTemplates/DeployWithNewResourceGroup/readme.md b/samples/BotPowered-BasicAce-CollectFeedback/DeploymentTemplates/DeployWithNewResourceGroup/readme.md similarity index 100% rename from samples/BotPowered-BasicAce/DeploymentTemplates/DeployWithNewResourceGroup/readme.md rename to samples/BotPowered-BasicAce-CollectFeedback/DeploymentTemplates/DeployWithNewResourceGroup/readme.md diff --git a/samples/BotPowered-BasicAce/DeploymentTemplates/DeployWithNewResourceGroup/template-AzureBot-new-rg.json b/samples/BotPowered-BasicAce-CollectFeedback/DeploymentTemplates/DeployWithNewResourceGroup/template-AzureBot-new-rg.json similarity index 100% rename from samples/BotPowered-BasicAce/DeploymentTemplates/DeployWithNewResourceGroup/template-AzureBot-new-rg.json rename to samples/BotPowered-BasicAce-CollectFeedback/DeploymentTemplates/DeployWithNewResourceGroup/template-AzureBot-new-rg.json diff --git a/samples/BotPowered-BasicAce/DeploymentTemplates/DeployWithNewResourceGroup/template-BotApp-new-rg.json b/samples/BotPowered-BasicAce-CollectFeedback/DeploymentTemplates/DeployWithNewResourceGroup/template-BotApp-new-rg.json similarity index 100% rename from samples/BotPowered-BasicAce/DeploymentTemplates/DeployWithNewResourceGroup/template-BotApp-new-rg.json rename to samples/BotPowered-BasicAce-CollectFeedback/DeploymentTemplates/DeployWithNewResourceGroup/template-BotApp-new-rg.json diff --git a/samples/BotPowered-BasicAce-CollectFeedback/FeedbackBot.cs b/samples/BotPowered-BasicAce-CollectFeedback/FeedbackBot.cs new file mode 100644 index 00000000..932f01ef --- /dev/null +++ b/samples/BotPowered-BasicAce-CollectFeedback/FeedbackBot.cs @@ -0,0 +1,248 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using AdaptiveCards; +using Microsoft.Bot.Builder; +using Microsoft.Bot.Builder.SharePoint; +using Microsoft.Bot.Schema; +using Microsoft.Bot.Schema.SharePoint; +using Microsoft.Extensions.Configuration; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using System.Collections.Concurrent; +using System.Runtime.InteropServices; +using System.IO; +using AdaptiveCards.Templating; + +namespace BotPowered_BasicAce_CollectFeedback +{ + public class FeedbackBot : SharePointActivityHandler + { + private static string adaptiveCardExtensionId = Guid.NewGuid().ToString(); + private IConfiguration configuration = null; + public readonly string baseUrl; + + private static ConcurrentDictionary cardViews = new ConcurrentDictionary(); + + private static string CollectFeedbackCardView_ID = "GET_FEEDBACK_CARD_VIEW"; + private static string OkFeedbackCardView_ID = "OK_FEEDBACK_CARD_VIEW"; + private static string FeedbackQuickView_ID = "FEEDBACK_QUICK_VIEW"; + + public FeedbackBot(IConfiguration configuration) + : base() + { + this.configuration = configuration; + this.baseUrl = configuration["BaseUrl"]; + + // Add the CardViews + var aceData = new AceData() + { + Title = "Your voice matters!", + CardSize = AceData.AceCardSize.Large, + DataVersion = "1.0", + Id = adaptiveCardExtensionId + }; + + // Collect Feedback Card View (Input Text Card View) + CardViewResponse feedbackCardViewResponse = new CardViewResponse(); + feedbackCardViewResponse.AceData = aceData; + feedbackCardViewResponse.CardViewParameters = CardViewParameters.TextInputCardViewParameters( + new CardBarComponent() + { + Id = "FeedbackCardView", + }, + new CardTextComponent() + { + Text = "Please, provide feedback" + }, + new CardTextInputComponent() + { + Id = "feedbackValue", + Placeholder = "Your feedback ..." + }, + new List() + { + new CardButtonComponent() + { + Id = "SendFeedback", + Title = "Submit", + Action = new SubmitAction() + { + Parameters = new Dictionary() + { + {"viewToNavigateTo", OkFeedbackCardView_ID}, + {"dateTimeFeedback", DateTime.Now.ToString()} + } + } + } + }, + new Microsoft.Bot.Schema.SharePoint.CardImage() + { + Image = $"{baseUrl}/Media/Collect-Feedback.png", + AltText = "Collect feedback picture" + }); + feedbackCardViewResponse.ViewId = CollectFeedbackCardView_ID; + + feedbackCardViewResponse.OnCardSelection = new QuickViewAction() + { + Parameters = new QuickViewActionParameters() + { + View = FeedbackQuickView_ID + } + }; + + cardViews.TryAdd(feedbackCardViewResponse.ViewId, feedbackCardViewResponse); + + // OK Feedback Card View (Image Card View) + CardViewResponse okFeedbackCardViewResponse = new CardViewResponse(); + okFeedbackCardViewResponse.AceData = aceData; + okFeedbackCardViewResponse.CardViewParameters = CardViewParameters.ImageCardViewParameters( + new CardBarComponent() + { + Id = "OkFeedbackCardView", + }, + new CardTextComponent() + { + Text = "Here is your feedback '' collected on ''" + }, + new List() + { + new CardButtonComponent() + { + Id = "OkButton", + Title = "Ok", + Action = new SubmitAction() + { + Parameters = new Dictionary() + { + {"viewToNavigateTo", CollectFeedbackCardView_ID} + } + } + } + }, + new Microsoft.Bot.Schema.SharePoint.CardImage() + { + Image = $"{baseUrl}/Media/Ok-Feedback.png", + AltText = "Feedback collected" + }); + okFeedbackCardViewResponse.ViewId = OkFeedbackCardView_ID; + + okFeedbackCardViewResponse.OnCardSelection = new QuickViewAction() + { + Parameters = new QuickViewActionParameters() + { + View = FeedbackQuickView_ID + } + }; + + cardViews.TryAdd(okFeedbackCardViewResponse.ViewId, okFeedbackCardViewResponse); + } + + protected override Task OnSharePointTaskGetCardViewAsync(ITurnContext turnContext, AceRequest aceRequest, CancellationToken cancellationToken) + { + return Task.FromResult(cardViews[CollectFeedbackCardView_ID]); + } + + protected override Task OnSharePointTaskGetQuickViewAsync(ITurnContext turnContext, AceRequest aceRequest, CancellationToken cancellationToken) + { + // Add the Feedback QuickViews + QuickViewResponse feedbackQuickViewResponse = new QuickViewResponse(); + feedbackQuickViewResponse.Title = "Your feedback"; + feedbackQuickViewResponse.Template = new AdaptiveCard("1.5"); + + AdaptiveContainer container = new AdaptiveContainer(); + container.Separator = true; + AdaptiveTextBlock titleText = new AdaptiveTextBlock(); + titleText.Text = "Thanks for your feedback!"; + titleText.Color = AdaptiveTextColor.Dark; + titleText.Weight = AdaptiveTextWeight.Bolder; + titleText.Size = AdaptiveTextSize.Large; + titleText.Wrap = true; + titleText.MaxLines = 1; + titleText.Spacing = AdaptiveSpacing.None; + container.Items.Add(titleText); + + AdaptiveTextBlock dateTimeCollectedText = new AdaptiveTextBlock(); + dateTimeCollectedText.Text = $"We truly appreciate your effort in providing valuable feedback to us. Thanks!"; + dateTimeCollectedText.Color = AdaptiveTextColor.Dark; + dateTimeCollectedText.Size = AdaptiveTextSize.Medium; + dateTimeCollectedText.Wrap = true; + dateTimeCollectedText.MaxLines = 3; + dateTimeCollectedText.Spacing = AdaptiveSpacing.None; + container.Items.Add(dateTimeCollectedText); + + feedbackQuickViewResponse.Template.Body.Add(container); + + feedbackQuickViewResponse.ViewId = FeedbackQuickView_ID; + + return Task.FromResult(feedbackQuickViewResponse); + } + + protected override Task OnSharePointTaskGetPropertyPaneConfigurationAsync(ITurnContext turnContext, AceRequest aceRequest, CancellationToken cancellationToken) + { + return base.OnSharePointTaskGetPropertyPaneConfigurationAsync(turnContext, aceRequest, cancellationToken); + } + + protected override Task OnSharePointTaskSetPropertyPaneConfigurationAsync(ITurnContext turnContext, AceRequest aceRequest, CancellationToken cancellationToken) + { + return base.OnSharePointTaskSetPropertyPaneConfigurationAsync(turnContext, aceRequest, cancellationToken); + } + + protected override Task OnSharePointTaskHandleActionAsync(ITurnContext turnContext, AceRequest aceRequest, CancellationToken cancellationToken) + { + if (turnContext != null) + { + if (cancellationToken.IsCancellationRequested) + { + cancellationToken.ThrowIfCancellationRequested(); + } + } + Trace.Write("\n\n\nStarted to handle action.\n\n\n"); + JObject actionParameters = (JObject)((JObject)turnContext.Activity.Value).Property("data").Value; + + if (actionParameters["type"].ToString().Equals("Submit", StringComparison.InvariantCultureIgnoreCase) && + actionParameters["id"].ToString().Equals("SendFeedback", StringComparison.InvariantCultureIgnoreCase)) + { + CardViewHandleActionResponse response = new CardViewHandleActionResponse(); + + string viewToNavigateTo = actionParameters["data"]["viewToNavigateTo"].ToString(); + var feedbackValue = actionParameters["data"]["feedbackValue"].ToString(); + var dateTimeFeedback = DateTime.Parse(actionParameters["data"]["dateTimeFeedback"]?.ToString() ?? DateTime.MinValue.ToString()); + + var nextCard = cardViews[viewToNavigateTo]; + + // Configure title and description of task + var originalText = ((nextCard.CardViewParameters.Header.ToList())[0] as CardTextComponent).Text; + originalText = originalText.Replace("", feedbackValue).Replace("", dateTimeFeedback.ToString()); + ((nextCard.CardViewParameters.Header.ToList())[0] as CardTextComponent).Text = originalText; + + // Set the response for the action + response.RenderArguments = cardViews[viewToNavigateTo]; + + Trace.Write("\n\n\nFinished handling action.\n\n\n"); + return Task.FromResult(response); + } + else if (actionParameters["type"].ToString().Equals("Submit", StringComparison.InvariantCultureIgnoreCase) && + actionParameters["id"].ToString().Equals("OkButton", StringComparison.InvariantCultureIgnoreCase)) + { + CardViewHandleActionResponse response = new CardViewHandleActionResponse(); + + string viewToNavigateTo = actionParameters["data"]["viewToNavigateTo"].ToString(); + + // Set the response for the action + response.RenderArguments = cardViews[viewToNavigateTo]; + + Trace.Write("\n\n\nFinished handling action.\n\n\n"); + return Task.FromResult(response); + } + + Trace.Write("\n\n\nFinished handling action.\n\n\n"); + return Task.FromResult(new NoOpHandleActionResponse()); + } + } +} \ No newline at end of file diff --git a/samples/BotPowered-BasicAce-CollectFeedback/Program.cs b/samples/BotPowered-BasicAce-CollectFeedback/Program.cs new file mode 100644 index 00000000..f1a255ce --- /dev/null +++ b/samples/BotPowered-BasicAce-CollectFeedback/Program.cs @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Generated with Bot Builder V4 SDK Template for Visual Studio EmptyBot v4.18.1 + +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Hosting; + +namespace BotPowered_BasicAce_CollectFeedback +{ + public class Program + { + public static void Main(string[] args) + { + CreateHostBuilder(args).Build().Run(); + } + + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + }); + } +} diff --git a/samples/BotPowered-BasicAce/Properties/launchSettings.json b/samples/BotPowered-BasicAce-CollectFeedback/Properties/launchSettings.json similarity index 100% rename from samples/BotPowered-BasicAce/Properties/launchSettings.json rename to samples/BotPowered-BasicAce-CollectFeedback/Properties/launchSettings.json diff --git a/samples/BotPowered-BasicAce/QuickViewTemplates/ListTasksQuickView.json b/samples/BotPowered-BasicAce-CollectFeedback/QuickViewTemplates/ListTasksQuickView.json similarity index 100% rename from samples/BotPowered-BasicAce/QuickViewTemplates/ListTasksQuickView.json rename to samples/BotPowered-BasicAce-CollectFeedback/QuickViewTemplates/ListTasksQuickView.json diff --git a/samples/BotPowered-BasicAce-CollectFeedback/README.md b/samples/BotPowered-BasicAce-CollectFeedback/README.md new file mode 100644 index 00000000..9db8c9dc --- /dev/null +++ b/samples/BotPowered-BasicAce-CollectFeedback/README.md @@ -0,0 +1,98 @@ +# Bot-Powered-ACE Collect Feedback + +This sample shows how to create a Viva Connection Adaptive Card Extension (ACE) to collect feedback from users. The ACE has been implemented using a Bot-Powered-ACE based on .NET. + +Here you can see main CardView of the ACE to collect feedback in action: + +![Collect feedback CardView](./assets/feedback-ace-01.png) + +Here you can see the CardView that confirms feedback collection: + +![Feedback collected CardView](./assets/feedback-ace-02.png) + +And here you can see the QuickView to give instructions to the user: + +![Collect feedback instructions QuickView](./assets/feedback-ace-03.png) + +## Used Bot Framework Version + +This bot has been created using [Bot Framework](https://dev.botframework.com). + +## Applies to + +- [Microsoft SharePoint Online](https://www.microsoft.com/en-us/microsoft-365/sharepoint/collaboration) +- [Microsoft Viva Connections](https://learn.microsoft.com/en-us/viva/connections/viva-connections-overview) + +> Get your own free development tenant by subscribing to [Microsoft 365 developer program](http://aka.ms/o365devprogram) + +## Solution + +| Solution | Author(s) | +| ----------- | ------------------------------------------------------- | +| BotPowered-BasicAce-CollectFeedback | Paolo Pialorsi Paolo Pialorsi - [PiaSys.com](https://www.piasys.com/) - [@PaoloPia](https://twitter.com/PaoloPia) | + +## Version history + +| Version | Date | Comments | +| ------- | ---------------- | --------------- | +| 1.0 | December 14, 2023 | Initial release | + +## Disclaimer + +**THIS CODE IS PROVIDED _AS IS_ WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.** + +--- + +## Minimal Path to Awesome + +### Prerequisites + +- [.NET SDK](https://dotnet.microsoft.com/download) version 6.0 + + ```bash + # determine dotnet version + dotnet --version + ``` + +### To try this sample + +- In a terminal, navigate to `BotPowered_BasicAce_CollectFeedback` + + ```bash + # change into project folder + cd BotPowered_BasicAce_CollectFeedback + ``` + +- Run the bot from a terminal or from Visual Studio, choose option A or B. + + A) From a terminal + + ```bash + # run the bot + dotnet run + ``` + + B) Or from Visual Studio + + - Launch Visual Studio + - File -> Open -> Project/Solution + - Navigate to `BotPowered-BasicAce-CollectFeedback` folder + - Select `BotPowered-BasicAce-CollectFeedback.csproj` file + - Press `F5` to run the project + +### Deploy the bot to Azure + +To learn more about deploying a bot to Azure, see [Deploy your bot to Azure](https://aka.ms/azuredeployment) for a complete list of deployment instructions. + +### Further reading + +- [Bot Framework Documentation](https://docs.botframework.com) +- [Bot Basics](https://docs.microsoft.com/azure/bot-service/bot-builder-basics?view=azure-bot-service-4.0) +- [Activity processing](https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-concept-activity-processing?view=azure-bot-service-4.0) +- [Azure Bot Service Introduction](https://docs.microsoft.com/azure/bot-service/bot-service-overview-introduction?view=azure-bot-service-4.0) +- [Azure Bot Service Documentation](https://docs.microsoft.com/azure/bot-service/?view=azure-bot-service-4.0) +- [.NET Core CLI tools](https://docs.microsoft.com/en-us/dotnet/core/tools/?tabs=netcore2x) +- [Azure CLI](https://docs.microsoft.com/cli/azure/?view=azure-cli-latest) +- [Azure Portal](https://portal.azure.com) +- [Language Understanding using LUIS](https://docs.microsoft.com/en-us/azure/cognitive-services/luis/) +- [Channels and Bot Connector Service](https://docs.microsoft.com/en-us/azure/bot-service/bot-concepts?view=azure-bot-service-4.0) diff --git a/samples/BotPowered-BasicAce-CollectFeedback/Startup.cs b/samples/BotPowered-BasicAce-CollectFeedback/Startup.cs new file mode 100644 index 00000000..9b17c8a9 --- /dev/null +++ b/samples/BotPowered-BasicAce-CollectFeedback/Startup.cs @@ -0,0 +1,65 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Generated with Bot Builder V4 SDK Template for Visual Studio EmptyBot v4.18.1 + +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Bot.Builder; +using Microsoft.Bot.Builder.Integration.AspNet.Core; +using Microsoft.Bot.Connector.Authentication; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; + +namespace BotPowered_BasicAce_CollectFeedback +{ + public class Startup + { + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } + + public IConfiguration Configuration { get; } + + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + services.AddHttpClient().AddControllers().AddNewtonsoftJson(options => + { + options.SerializerSettings.MaxDepth = HttpHelper.BotMessageSerializerSettings.MaxDepth; + }); + + // Create the Bot Framework Authentication to be used with the Bot Adapter. + services.AddSingleton(); + + // Create the Bot Adapter with error handling enabled. + services.AddSingleton(); + + // Create the bot as a transient. In this case the ASP Controller is expecting an IBot. + services.AddTransient(); + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + + app.UseDefaultFiles() + .UseStaticFiles() + .UseWebSockets() + .UseRouting() + .UseAuthorization() + .UseEndpoints(endpoints => + { + endpoints.MapControllers(); + }); + + // app.UseHttpsRedirection(); + } + } +} diff --git a/samples/BotPowered-BasicAce/TeamsAppManifest/botpowered.basicace.zip b/samples/BotPowered-BasicAce-CollectFeedback/TeamsAppManifest/botpowered.basicace.zip similarity index 100% rename from samples/BotPowered-BasicAce/TeamsAppManifest/botpowered.basicace.zip rename to samples/BotPowered-BasicAce-CollectFeedback/TeamsAppManifest/botpowered.basicace.zip diff --git a/samples/BotPowered-BasicAce/TeamsAppManifest/icon-color.png b/samples/BotPowered-BasicAce-CollectFeedback/TeamsAppManifest/icon-color.png similarity index 100% rename from samples/BotPowered-BasicAce/TeamsAppManifest/icon-color.png rename to samples/BotPowered-BasicAce-CollectFeedback/TeamsAppManifest/icon-color.png diff --git a/samples/BotPowered-BasicAce/TeamsAppManifest/icon-outline.png b/samples/BotPowered-BasicAce-CollectFeedback/TeamsAppManifest/icon-outline.png similarity index 100% rename from samples/BotPowered-BasicAce/TeamsAppManifest/icon-outline.png rename to samples/BotPowered-BasicAce-CollectFeedback/TeamsAppManifest/icon-outline.png diff --git a/samples/BotPowered-BasicAce/TeamsAppManifest/manifest.json b/samples/BotPowered-BasicAce-CollectFeedback/TeamsAppManifest/manifest.json similarity index 100% rename from samples/BotPowered-BasicAce/TeamsAppManifest/manifest.json rename to samples/BotPowered-BasicAce-CollectFeedback/TeamsAppManifest/manifest.json diff --git a/samples/BotPowered-BasicAce/appsettings.Development.json b/samples/BotPowered-BasicAce-CollectFeedback/appsettings.Development.json similarity index 100% rename from samples/BotPowered-BasicAce/appsettings.Development.json rename to samples/BotPowered-BasicAce-CollectFeedback/appsettings.Development.json diff --git a/samples/BotPowered-BasicAce-CollectFeedback/appsettings.json b/samples/BotPowered-BasicAce-CollectFeedback/appsettings.json new file mode 100644 index 00000000..3eb7cb42 --- /dev/null +++ b/samples/BotPowered-BasicAce-CollectFeedback/appsettings.json @@ -0,0 +1,8 @@ +{ + "MicrosoftAppType": "MultiTenant", + "MicrosoftAppId": "", + "MicrosoftAppPassword": "", + "MicrosoftAppTenantId": "", + "BaseUrl": "", + "TemplatesPath": "" +} diff --git a/samples/BotPowered-BasicAce-CollectFeedback/assets/feedback-ace-01.png b/samples/BotPowered-BasicAce-CollectFeedback/assets/feedback-ace-01.png new file mode 100644 index 00000000..501f7d00 Binary files /dev/null and b/samples/BotPowered-BasicAce-CollectFeedback/assets/feedback-ace-01.png differ diff --git a/samples/BotPowered-BasicAce-CollectFeedback/assets/feedback-ace-02.png b/samples/BotPowered-BasicAce-CollectFeedback/assets/feedback-ace-02.png new file mode 100644 index 00000000..3e36cbd5 Binary files /dev/null and b/samples/BotPowered-BasicAce-CollectFeedback/assets/feedback-ace-02.png differ diff --git a/samples/BotPowered-BasicAce-CollectFeedback/assets/feedback-ace-03.png b/samples/BotPowered-BasicAce-CollectFeedback/assets/feedback-ace-03.png new file mode 100644 index 00000000..5a857c7e Binary files /dev/null and b/samples/BotPowered-BasicAce-CollectFeedback/assets/feedback-ace-03.png differ diff --git a/samples/BotPowered-BasicAce-CollectFeedback/assets/sample.json b/samples/BotPowered-BasicAce-CollectFeedback/assets/sample.json new file mode 100644 index 00000000..d5419ef6 --- /dev/null +++ b/samples/BotPowered-BasicAce-CollectFeedback/assets/sample.json @@ -0,0 +1,69 @@ +[{ + "name": "pnp-sp-fx-aces-botpowered-basicace-collect-feedback", + "source": "pnp", + "title": "Bot-Powered-ACE Collect Feedback", + "shortDescription": "Viva Connection Adaptive Card Extension (ACE) that shows how to collect feedback from users using a Bot-Powered-ACE implemented with .NET.", + "url": "https://github.com/pnp/sp-dev-fx-aces/tree/main/samples/BotPowered-BasicAce-CollectFeedback", + "longDescription": [ + "Viva Connection Adaptive Card Extension (ACE) that shows how to collect feedback from users using a Bot-Powered-ACE implemented with .NET." + ], + "creationDateTime": "2023-12-14", + "updateDateTime": "2023-12-14", + "products": [ + "SharePoint", + "Viva" + ], + "metadata": [ + { + "key": "BOT-FRAMEWORK-VERSION", + "value": "bot40" + } + ], + "thumbnails": [ + { + "type": "image", + "order": 100, + "url": "https://raw.githubusercontent.com/pnp/sp-dev-fx-aces/main/samples/BotPowered-BasicAce-CollectFeedback/assets/feedback-ace-01.png", + "alt": "Preview of the main CardView to collect feedback from user" + }, + { + "type": "image", + "order": 200, + "url": "https://raw.githubusercontent.com/pnp/sp-dev-fx-aces/main/samples/BotPowered-BasicAce-CollectFeedback/assets/feedback-ace-02.png", + "alt": "Preview of the CardView showing the feedback collected from user" + }, + { + "type": "image", + "order": 300, + "url": "https://raw.githubusercontent.com/pnp/sp-dev-fx-aces/main/samples/BotPowered-BasicAce-CollectFeedback/assets/feedback-ace-03.png", + "alt": "Preview of the main QuickView to show additional information to the user" + } + + ], + "authors": [ + { + "gitHubAccount": "PaoloPia", + "company": "PiaSys.com", + "pictureUrl": "https://github.com/paolopia.png", + "name": "Paolo Pialorsi", + "twitter": "PaoloPia" + } + ], + "references": [ + { + "name": "Viva Connections Extensibility guidance", + "description": "Adaptive Card Extensions are client-side components that run in the context of a SharePoint page.", + "url": "https://aka.ms/viva/connections/extensibility" + }, + { + "name": "Adaptive Card Documentation", + "description": "Detailed documentation on Adaptive Cards including the Adaptive Card designer.", + "url": "https://adaptivecards.io/" + }, + { + "name": "Adaptive Card Extension Design Guidance", + "description": "Design guidance for laying out Adaptive Card Extensions.", + "url": "https://docs.microsoft.com/en-us/sharepoint/dev/spfx/viva/design/design-intro" + } + ] +}] \ No newline at end of file diff --git a/samples/BotPowered-BasicAce-CollectFeedback/wwwroot/Media/Collect-Feedback.png b/samples/BotPowered-BasicAce-CollectFeedback/wwwroot/Media/Collect-Feedback.png new file mode 100644 index 00000000..16aecc8a Binary files /dev/null and b/samples/BotPowered-BasicAce-CollectFeedback/wwwroot/Media/Collect-Feedback.png differ diff --git a/samples/BotPowered-BasicAce-CollectFeedback/wwwroot/Media/Ok-Feedback.png b/samples/BotPowered-BasicAce-CollectFeedback/wwwroot/Media/Ok-Feedback.png new file mode 100644 index 00000000..ea5aa3a3 Binary files /dev/null and b/samples/BotPowered-BasicAce-CollectFeedback/wwwroot/Media/Ok-Feedback.png differ diff --git a/samples/BotPowered-BasicAce/wwwroot/default.htm b/samples/BotPowered-BasicAce-CollectFeedback/wwwroot/default.htm similarity index 100% rename from samples/BotPowered-BasicAce/wwwroot/default.htm rename to samples/BotPowered-BasicAce-CollectFeedback/wwwroot/default.htm diff --git a/samples/BotPowered-BasicAce-Tasks/.gitignore b/samples/BotPowered-BasicAce-Tasks/.gitignore new file mode 100644 index 00000000..ff5b00c5 --- /dev/null +++ b/samples/BotPowered-BasicAce-Tasks/.gitignore @@ -0,0 +1,264 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# Azure Functions localsettings file +local.settings.json + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# DNX +project.lock.json +project.fragment.lock.json +artifacts/ + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +#*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config +# NuGet v3's project.json files produces more ignoreable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +node_modules/ +orleans.codegen.cs + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc \ No newline at end of file diff --git a/samples/BotPowered-BasicAce/AdapterWithErrorHandler.cs b/samples/BotPowered-BasicAce-Tasks/AdapterWithErrorHandler.cs similarity index 97% rename from samples/BotPowered-BasicAce/AdapterWithErrorHandler.cs rename to samples/BotPowered-BasicAce-Tasks/AdapterWithErrorHandler.cs index 19d047ed..39e1748c 100644 --- a/samples/BotPowered-BasicAce/AdapterWithErrorHandler.cs +++ b/samples/BotPowered-BasicAce-Tasks/AdapterWithErrorHandler.cs @@ -8,7 +8,7 @@ using Microsoft.Bot.Connector.Authentication; using Microsoft.Extensions.Logging; -namespace BotPowered_BasicAce +namespace BotPowered_BasicAce_Tasks { public class AdapterWithErrorHandler : CloudAdapter { diff --git a/samples/BotPowered-BasicAce/BotPowered-BasicAce.csproj b/samples/BotPowered-BasicAce-Tasks/BotPowered-BasicAce-Tasks.csproj similarity index 80% rename from samples/BotPowered-BasicAce/BotPowered-BasicAce.csproj rename to samples/BotPowered-BasicAce-Tasks/BotPowered-BasicAce-Tasks.csproj index b565b1ac..4ab09981 100644 --- a/samples/BotPowered-BasicAce/BotPowered-BasicAce.csproj +++ b/samples/BotPowered-BasicAce-Tasks/BotPowered-BasicAce-Tasks.csproj @@ -3,6 +3,8 @@ net6.0 latest + c3120fef-4880-42e8-a94d-60b2d1aa6c5f + $(MSBuildProjectName.Replace(" ", "_").Replace("-", "_")) diff --git a/samples/BotPowered-BasicAce/BotPowered-BasicAce.sln b/samples/BotPowered-BasicAce-Tasks/BotPowered-BasicAce-Tasks.sln similarity index 91% rename from samples/BotPowered-BasicAce/BotPowered-BasicAce.sln rename to samples/BotPowered-BasicAce-Tasks/BotPowered-BasicAce-Tasks.sln index 76c29de6..8be0ecd3 100644 --- a/samples/BotPowered-BasicAce/BotPowered-BasicAce.sln +++ b/samples/BotPowered-BasicAce-Tasks/BotPowered-BasicAce-Tasks.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.6.33829.357 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotPowered-BasicAce", "BotPowered-BasicAce.csproj", "{C4EF0E19-232D-4F9B-ADB6-84B07D37C473}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotPowered-BasicAce-Tasks", "BotPowered-BasicAce-Tasks.csproj", "{C4EF0E19-232D-4F9B-ADB6-84B07D37C473}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/samples/BotPowered-BasicAce/Controllers/BotController.cs b/samples/BotPowered-BasicAce-Tasks/Controllers/BotController.cs similarity index 96% rename from samples/BotPowered-BasicAce/Controllers/BotController.cs rename to samples/BotPowered-BasicAce-Tasks/Controllers/BotController.cs index a260d68c..24fdff52 100644 --- a/samples/BotPowered-BasicAce/Controllers/BotController.cs +++ b/samples/BotPowered-BasicAce-Tasks/Controllers/BotController.cs @@ -8,7 +8,7 @@ using Microsoft.Bot.Builder.Integration.AspNet.Core; using System.Threading.Tasks; -namespace BotPowered_BasicAce.Controllers +namespace BotPowered_BasicAce_Tasks.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 diff --git a/samples/BotPowered-BasicAce-Tasks/DeploymentTemplates/DeployUseExistResourceGroup/parameters-for-template-AzureBot-with-rg.json b/samples/BotPowered-BasicAce-Tasks/DeploymentTemplates/DeployUseExistResourceGroup/parameters-for-template-AzureBot-with-rg.json new file mode 100644 index 00000000..c2c03ef3 --- /dev/null +++ b/samples/BotPowered-BasicAce-Tasks/DeploymentTemplates/DeployUseExistResourceGroup/parameters-for-template-AzureBot-with-rg.json @@ -0,0 +1,33 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "azureBotId": { + "value": "" + }, + "azureBotSku": { + "value": "S1" + }, + "azureBotRegion": { + "value": "global" + }, + "botEndpoint": { + "value": "" + }, + "appType": { + "value": "MultiTenant" + }, + "appId": { + "value": "" + }, + "UMSIName": { + "value": "" + }, + "UMSIResourceGroupName": { + "value": "" + }, + "tenantId": { + "value": "" + } + } +} \ No newline at end of file diff --git a/samples/BotPowered-BasicAce-Tasks/DeploymentTemplates/DeployUseExistResourceGroup/parameters-for-template-BotApp-with-rg.json b/samples/BotPowered-BasicAce-Tasks/DeploymentTemplates/DeployUseExistResourceGroup/parameters-for-template-BotApp-with-rg.json new file mode 100644 index 00000000..c4b29090 --- /dev/null +++ b/samples/BotPowered-BasicAce-Tasks/DeploymentTemplates/DeployUseExistResourceGroup/parameters-for-template-BotApp-with-rg.json @@ -0,0 +1,48 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "appServiceName": { + "value": "" + }, + "existingAppServicePlanName": { + "value": "" + }, + "existingAppServicePlanLocation": { + "value": "" + }, + "newAppServicePlanName": { + "value": "" + }, + "newAppServicePlanLocation": { + "value": "" + }, + "newAppServicePlanSku": { + "value": { + "name": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "capacity": 1 + } + }, + "appType": { + "value": "MultiTenant" + }, + "appId": { + "value": "" + }, + "appSecret": { + "value": "" + }, + "UMSIName": { + "value": "" + }, + "UMSIResourceGroupName": { + "value": "" + }, + "tenantId": { + "value": "" + } + } +} \ No newline at end of file diff --git a/samples/BotPowered-BasicAce-Tasks/DeploymentTemplates/DeployUseExistResourceGroup/readme.md b/samples/BotPowered-BasicAce-Tasks/DeploymentTemplates/DeployUseExistResourceGroup/readme.md new file mode 100644 index 00000000..628f0a95 --- /dev/null +++ b/samples/BotPowered-BasicAce-Tasks/DeploymentTemplates/DeployUseExistResourceGroup/readme.md @@ -0,0 +1,48 @@ +# Usage +The BotApp must be deployed prior to AzureBot. + +Command line: +- az login +- az deployment group create --resource-group --template-file --parameters @ + +# parameters-for-template-BotApp-with-rg: + +- **appServiceName**:(required) The Name of the Bot App Service. + +- (choose an existingAppServicePlan or create a new AppServicePlan) + - **existingAppServicePlanName**: The name of the App Service Plan. + - **existingAppServicePlanLocation**: The location of the App Service Plan. + - **newAppServicePlanName**: The name of the App Service Plan. + - **newAppServicePlanLocation**: The location of the App Service Plan. + - **newAppServicePlanSku**: The SKU of the App Service Plan. Defaults to Standard values. + +- **appType**: Type of Bot Authentication. set as MicrosoftAppType in the Web App's Application Settings. **Allowed values are: MultiTenant(default), SingleTenant, UserAssignedMSI.** + +- **appId**:(required) Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings. + +- **appSecret**:(required for MultiTenant and SingleTenant) Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings. + +- **UMSIName**:(required for UserAssignedMSI) The User-Assigned Managed Identity Resource used for the Bot's Authentication. + +- **UMSIResourceGroupName**:(required for UserAssignedMSI) The User-Assigned Managed Identity Resource Group used for the Bot's Authentication. + +- **tenantId**: The Azure AD Tenant ID to use as part of the Bot's Authentication. Only used for SingleTenant and UserAssignedMSI app types. Defaults to . + +MoreInfo: https://docs.microsoft.com/en-us/azure/bot-service/tutorial-provision-a-bot?view=azure-bot-service-4.0&tabs=userassigned%2Cnewgroup#create-an-identity-resource + + + +# parameters-for-template-AzureBot-with-rg: + +- **azureBotId**:(required) The globally unique and immutable bot ID. +- **azureBotSku**: The pricing tier of the Bot Service Registration. **Allowed values are: F0, S1(default)**. +- **azureBotRegion**: Specifies the location of the new AzureBot. **Allowed values are: global(default), westeurope**. +- **botEndpoint**: Use to handle client messages, Such as https://.azurewebsites.net/api/messages. + +- **appType**: Type of Bot Authentication. set as MicrosoftAppType in the Web App's Application Settings. **Allowed values are: MultiTenant(default), SingleTenant, UserAssignedMSI.** +- **appId**:(required) Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings. +- **UMSIName**:(required for UserAssignedMSI) The User-Assigned Managed Identity Resource used for the Bot's Authentication. +- **UMSIResourceGroupName**:(required for UserAssignedMSI) The User-Assigned Managed Identity Resource Group used for the Bot's Authentication. +- **tenantId**: The Azure AD Tenant ID to use as part of the Bot's Authentication. Only used for SingleTenant and UserAssignedMSI app types. Defaults to . + +MoreInfo: https://docs.microsoft.com/en-us/azure/bot-service/tutorial-provision-a-bot?view=azure-bot-service-4.0&tabs=userassigned%2Cnewgroup#create-an-identity-resource \ No newline at end of file diff --git a/samples/BotPowered-BasicAce-Tasks/DeploymentTemplates/DeployUseExistResourceGroup/template-AzureBot-with-rg.json b/samples/BotPowered-BasicAce-Tasks/DeploymentTemplates/DeployUseExistResourceGroup/template-AzureBot-with-rg.json new file mode 100644 index 00000000..103ca19e --- /dev/null +++ b/samples/BotPowered-BasicAce-Tasks/DeploymentTemplates/DeployUseExistResourceGroup/template-AzureBot-with-rg.json @@ -0,0 +1,119 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "azureBotId": { + "type": "string", + "metadata": { + "description": "The globally unique and immutable bot ID." + } + }, + "azureBotSku": { + "defaultValue": "S1", + "type": "string", + "metadata": { + "description": "The pricing tier of the Bot Service Registration. Allowed values are: F0, S1(default)." + } + }, + "azureBotRegion": { + "type": "string", + "defaultValue": "global", + "metadata": { + "description": "Specifies the location of the new AzureBot. Allowed values are: global(default), westeurope." + } + }, + "botEndpoint": { + "type": "string", + "metadata": { + "description": "Use to handle client messages, Such as https://.azurewebsites.net/api/messages." + } + }, + "appType": { + "type": "string", + "defaultValue": "MultiTenant", + "allowedValues": [ + "MultiTenant", + "SingleTenant", + "UserAssignedMSI" + ], + "metadata": { + "description": "Type of Bot Authentication. set as MicrosoftAppType in the Web App's Application Settings. Allowed values are: MultiTenant, SingleTenant, UserAssignedMSI. Defaults to \"MultiTenant\"." + } + }, + "appId": { + "type": "string", + "metadata": { + "description": "Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings." + } + }, + "UMSIName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The User-Assigned Managed Identity Resource used for the Bot's Authentication." + } + }, + "UMSIResourceGroupName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The User-Assigned Managed Identity Resource Group used for the Bot's Authentication." + } + }, + "tenantId": { + "type": "string", + "defaultValue": "[subscription().tenantId]", + "metadata": { + "description": "The Azure AD Tenant ID to use as part of the Bot's Authentication. Only used for SingleTenant and UserAssignedMSI app types. Defaults to \"Subscription Tenant ID\"." + } + } + }, + "variables": { + "tenantId": "[if(empty(parameters('tenantId')), subscription().tenantId, parameters('tenantId'))]", + "msiResourceId": "[concat(subscription().id, '/resourceGroups/', parameters('UMSIResourceGroupName'), '/providers/', 'Microsoft.ManagedIdentity/userAssignedIdentities/', parameters('UMSIName'))]", + "appTypeDef": { + "MultiTenant": { + "tenantId": "", + "msiResourceId": "" + }, + "SingleTenant": { + "tenantId": "[variables('tenantId')]", + "msiResourceId": "" + }, + "UserAssignedMSI": { + "tenantId": "[variables('tenantId')]", + "msiResourceId": "[variables('msiResourceId')]" + } + }, + "appType": { + "tenantId": "[variables('appTypeDef')[parameters('appType')].tenantId]", + "msiResourceId": "[variables('appTypeDef')[parameters('appType')].msiResourceId]" + } + }, + "resources": [ + { + "apiVersion": "2021-05-01-preview", + "type": "Microsoft.BotService/botServices", + "name": "[parameters('azureBotId')]", + "location": "[parameters('azureBotRegion')]", + "kind": "azurebot", + "sku": { + "name": "[parameters('azureBotSku')]" + }, + "properties": { + "displayName": "[parameters('azureBotId')]", + "iconUrl": "https://docs.botframework.com/static/devportal/client/images/bot-framework-default.png", + "endpoint": "[parameters('botEndpoint')]", + "msaAppId": "[parameters('appId')]", + "msaAppTenantId": "[variables('appType').tenantId]", + "msaAppMSIResourceId": "[variables('appType').msiResourceId]", + "msaAppType": "[parameters('appType')]", + "luisAppIds": [], + "schemaTransformationVersion": "1.3", + "isCmekEnabled": false, + "isIsolated": false + }, + "dependsOn": [] + } + ] +} \ No newline at end of file diff --git a/samples/BotPowered-BasicAce-Tasks/DeploymentTemplates/DeployUseExistResourceGroup/template-BotApp-with-rg.json b/samples/BotPowered-BasicAce-Tasks/DeploymentTemplates/DeployUseExistResourceGroup/template-BotApp-with-rg.json new file mode 100644 index 00000000..be94279e --- /dev/null +++ b/samples/BotPowered-BasicAce-Tasks/DeploymentTemplates/DeployUseExistResourceGroup/template-BotApp-with-rg.json @@ -0,0 +1,189 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "appServiceName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The globally unique name of the Web App." + } + }, + "existingAppServicePlanName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Name of the existing App Service Plan used to create the Web App for the bot." + } + }, + "existingAppServicePlanLocation": { + "type": "string", + "metadata": { + "description": "The location of the App Service Plan." + } + }, + "newAppServicePlanName": { + "type": "string", + "metadata": { + "description": "The name of the new App Service Plan." + } + }, + "newAppServicePlanLocation": { + "type": "string", + "metadata": { + "description": "The location of the App Service Plan." + } + }, + "newAppServicePlanSku": { + "type": "object", + "defaultValue": { + "name": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "capacity": 1 + }, + "metadata": { + "description": "The SKU of the App Service Plan. Defaults to Standard values." + } + }, + "appType": { + "type": "string", + "defaultValue": "MultiTenant", + "allowedValues": [ + "MultiTenant", + "SingleTenant", + "UserAssignedMSI" + ], + "metadata": { + "description": "Type of Bot Authentication. set as MicrosoftAppType in the Web App's Application Settings. Allowed values are: MultiTenant, SingleTenant, UserAssignedMSI. Defaults to \"MultiTenant\"." + } + }, + "appId": { + "type": "string", + "metadata": { + "description": "Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings." + } + }, + "appSecret": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings. Required for MultiTenant and SingleTenant app types. Defaults to \"\"." + } + }, + "UMSIName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The User-Assigned Managed Identity Resource used for the Bot's Authentication. Defaults to \"\"." + } + }, + "UMSIResourceGroupName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The User-Assigned Managed Identity Resource Group used for the Bot's Authentication. Defaults to \"\"." + } + }, + "tenantId": { + "type": "string", + "defaultValue": "[subscription().tenantId]", + "metadata": { + "description": "The Azure AD Tenant ID to use as part of the Bot's Authentication. Only used for SingleTenant and UserAssignedMSI app types. Defaults to \"Subscription Tenant ID\"." + } + } + }, + "variables": { + "tenantId": "[if(empty(parameters('tenantId')), subscription().tenantId, parameters('tenantId'))]", + "defaultAppServicePlanName": "[if(empty(parameters('existingAppServicePlanName')), 'createNewAppServicePlan', parameters('existingAppServicePlanName'))]", + "useExistingServicePlan": "[not(equals(variables('defaultAppServicePlanName'), 'createNewAppServicePlan'))]", + "servicePlanName": "[if(variables('useExistingServicePlan'), parameters('existingAppServicePlanName'), parameters('newAppServicePlanName'))]", + "servicePlanLocation": "[if(variables('useExistingServicePlan'), parameters('existingAppServicePlanLocation'), parameters('newAppServicePlanLocation'))]", + "msiResourceId": "[concat(subscription().id, '/resourceGroups/', parameters('UMSIResourceGroupName'), '/providers/', 'Microsoft.ManagedIdentity/userAssignedIdentities/', parameters('UMSIName'))]", + "appTypeDef": { + "MultiTenant": { + "tenantId": "", + "identity": { "type": "None" } + }, + "SingleTenant": { + "tenantId": "[variables('tenantId')]", + "identity": { "type": "None" } + }, + "UserAssignedMSI": { + "tenantId": "[variables('tenantId')]", + "identity": { + "type": "UserAssigned", + "userAssignedIdentities": { + "[variables('msiResourceId')]": {} + } + } + } + }, + "appType": { + "tenantId": "[variables('appTypeDef')[parameters('appType')].tenantId]", + "identity": "[variables('appTypeDef')[parameters('appType')].identity]" + } + }, + "resources": [ + { + "comments": "Create a new App Service Plan if no existing App Service Plan name was passed in.", + "type": "Microsoft.Web/serverfarms", + "condition": "[not(variables('useExistingServicePlan'))]", + "name": "[variables('servicePlanName')]", + "apiVersion": "2018-02-01", + "location": "[parameters('newAppServicePlanLocation')]", + "sku": "[parameters('newAppServicePlanSku')]", + "properties": { + "name": "[variables('servicePlanName')]" + } + }, + { + "comments": "Create a Web App using an App Service Plan", + "type": "Microsoft.Web/sites", + "apiVersion": "2015-08-01", + "location": "[variables('servicePlanLocation')]", + "kind": "app", + "dependsOn": [ + "[resourceId('Microsoft.Web/serverfarms', variables('servicePlanName'))]" + ], + "name": "[parameters('appServiceName')]", + "identity": "[variables('appType').identity]", + "properties": { + "name": "[parameters('appServiceName')]", + "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('servicePlanName'))]", + "siteConfig": { + "appSettings": [ + { + "name": "WEBSITE_NODE_DEFAULT_VERSION", + "value": "10.14.1" + }, + { + "name": "MicrosoftAppType", + "value": "[parameters('appType')]" + }, + { + "name": "MicrosoftAppId", + "value": "[parameters('appId')]" + }, + { + "name": "MicrosoftAppPassword", + "value": "[parameters('appSecret')]" + }, + { + "name": "MicrosoftAppTenantId", + "value": "[variables('appType').tenantId]" + } + ], + "cors": { + "allowedOrigins": [ + "https://botservice.hosting.portal.azure.net", + "https://hosting.onecloud.azure-test.net/" + ] + }, + "webSocketsEnabled": true + } + } + } + ] +} \ No newline at end of file diff --git a/samples/BotPowered-BasicAce-Tasks/DeploymentTemplates/DeployWithNewResourceGroup/parameters-for-template-AzureBot-new-rg.json b/samples/BotPowered-BasicAce-Tasks/DeploymentTemplates/DeployWithNewResourceGroup/parameters-for-template-AzureBot-new-rg.json new file mode 100644 index 00000000..44f169e4 --- /dev/null +++ b/samples/BotPowered-BasicAce-Tasks/DeploymentTemplates/DeployWithNewResourceGroup/parameters-for-template-AzureBot-new-rg.json @@ -0,0 +1,39 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "groupName": { + "value": "" + }, + "groupLocation": { + "value": "" + }, + "azureBotId": { + "value": "" + }, + "azureBotSku": { + "value": "S1" + }, + "azureBotRegion": { + "value": "global" + }, + "botEndpoint": { + "value": "" + }, + "appType": { + "value": "MultiTenant" + }, + "appId": { + "value": "" + }, + "UMSIName": { + "value": "" + }, + "UMSIResourceGroupName": { + "value": "" + }, + "tenantId": { + "value": "" + } + } +} \ No newline at end of file diff --git a/samples/BotPowered-BasicAce-Tasks/DeploymentTemplates/DeployWithNewResourceGroup/parameters-for-template-BotApp-new-rg.json b/samples/BotPowered-BasicAce-Tasks/DeploymentTemplates/DeployWithNewResourceGroup/parameters-for-template-BotApp-new-rg.json new file mode 100644 index 00000000..8abb03d5 --- /dev/null +++ b/samples/BotPowered-BasicAce-Tasks/DeploymentTemplates/DeployWithNewResourceGroup/parameters-for-template-BotApp-new-rg.json @@ -0,0 +1,48 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "groupName": { + "value": "" + }, + "groupLocation": { + "value": "" + }, + "appServiceName": { + "value": "" + }, + "appServicePlanName": { + "value": "" + }, + "appServicePlanLocation": { + "value": "" + }, + "appServicePlanSku": { + "value": { + "name": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "capacity": 1 + } + }, + "appType": { + "value": "MultiTenant" + }, + "appId": { + "value": "" + }, + "appSecret": { + "value": "" + }, + "UMSIName": { + "value": "" + }, + "UMSIResourceGroupName": { + "value": "" + }, + "tenantId": { + "value": "" + } + } +} \ No newline at end of file diff --git a/samples/BotPowered-BasicAce-Tasks/DeploymentTemplates/DeployWithNewResourceGroup/readme.md b/samples/BotPowered-BasicAce-Tasks/DeploymentTemplates/DeployWithNewResourceGroup/readme.md new file mode 100644 index 00000000..23bf7a5a --- /dev/null +++ b/samples/BotPowered-BasicAce-Tasks/DeploymentTemplates/DeployWithNewResourceGroup/readme.md @@ -0,0 +1,45 @@ +# Usage +The BotApp must be deployed prior to AzureBot. + +Command line: +- az login +- az deployment sub create --template-file --location --parameters @ + +# parameters-for-template-BotApp-new-rg: + +- **groupName**:(required) Specifies the name of the new Resource Group. +- **groupLocation**:(required) Specifies the location of the new Resource Group. + +- **appServiceName**:(required) The location of the App Service Plan. +- **appServicePlanName**:(required) The name of the App Service Plan. +- **appServicePlanLocation**: The location of the App Service Plan. Defaults to use groupLocation. +- **appServicePlanSku**: The SKU of the App Service Plan. Defaults to Standard values. + +- **appType**: Type of Bot Authentication. set as MicrosoftAppType in the Web App's Application Settings. **Allowed values are: MultiTenant(default), SingleTenant, UserAssignedMSI.** +- **appId**:(required) Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings. +- **appSecret**:(required for MultiTenant and SingleTenant) Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings. +- **UMSIName**:(required for UserAssignedMSI) The User-Assigned Managed Identity Resource used for the Bot's Authentication. +- **UMSIResourceGroupName**:(required for UserAssignedMSI) The User-Assigned Managed Identity Resource Group used for the Bot's Authentication. +- **tenantId**: The Azure AD Tenant ID to use as part of the Bot's Authentication. Only used for SingleTenant and UserAssignedMSI app types. Defaults to . + +MoreInfo: https://docs.microsoft.com/en-us/azure/bot-service/tutorial-provision-a-bot?view=azure-bot-service-4.0&tabs=userassigned%2Cnewgroup#create-an-identity-resource + + + +# parameters-for-template-AzureBot-new-rg: + +- **groupName**:(required) Specifies the name of the new Resource Group. +- **groupLocation**:(required) Specifies the location of the new Resource Group. + +- **azureBotId**:(required) The globally unique and immutable bot ID. Also used to configure the displayName of the bot, which is mutable. +- **azureBotSku**: The pricing tier of the Bot Service Registration. **Allowed values are: F0, S1(default)**. +- **azureBotRegion**: Specifies the location of the new AzureBot. **Allowed values are: global(default), westeurope**. +- **botEndpoint**: Use to handle client messages, Such as https://.azurewebsites.net/api/messages. + +- **appType**: Type of Bot Authentication. set as MicrosoftAppType in the Web App's Application Settings. **Allowed values are: MultiTenant(default), SingleTenant, UserAssignedMSI.** +- **appId**:(required) Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings. +- **UMSIName**:(required for UserAssignedMSI) The User-Assigned Managed Identity Resource used for the Bot's Authentication. +- **UMSIResourceGroupName**:(required for UserAssignedMSI) The User-Assigned Managed Identity Resource Group used for the Bot's Authentication. +- **tenantId**: The Azure AD Tenant ID to use as part of the Bot's Authentication. Only used for SingleTenant and UserAssignedMSI app types. Defaults to . + +MoreInfo: https://docs.microsoft.com/en-us/azure/bot-service/tutorial-provision-a-bot?view=azure-bot-service-4.0&tabs=userassigned%2Cnewgroup#create-an-identity-resource \ No newline at end of file diff --git a/samples/BotPowered-BasicAce-Tasks/DeploymentTemplates/DeployWithNewResourceGroup/template-AzureBot-new-rg.json b/samples/BotPowered-BasicAce-Tasks/DeploymentTemplates/DeployWithNewResourceGroup/template-AzureBot-new-rg.json new file mode 100644 index 00000000..da685912 --- /dev/null +++ b/samples/BotPowered-BasicAce-Tasks/DeploymentTemplates/DeployWithNewResourceGroup/template-AzureBot-new-rg.json @@ -0,0 +1,157 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "groupName": { + "type": "string", + "metadata": { + "description": "Specifies the name of the Resource Group." + } + }, + "groupLocation": { + "type": "string", + "metadata": { + "description": "Specifies the location of the Resource Group." + } + }, + "azureBotId": { + "type": "string", + "metadata": { + "description": "The globally unique and immutable bot ID." + } + }, + "azureBotSku": { + "type": "string", + "defaultValue": "S1", + "metadata": { + "description": "The pricing tier of the Bot Service Registration. Acceptable values are F0 and S1." + } + }, + "azureBotRegion": { + "type": "string", + "defaultValue": "global", + "metadata": { + "description": "" + } + }, + "botEndpoint": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Use to handle client messages, Such as https://.azurewebsites.net/api/messages." + } + }, + "appType": { + "type": "string", + "defaultValue": "MultiTenant", + "allowedValues": [ + "MultiTenant", + "SingleTenant", + "UserAssignedMSI" + ], + "metadata": { + "description": "Type of Bot Authentication. set as MicrosoftAppType in the Web App's Application Settings. Allowed values are: MultiTenant, SingleTenant, UserAssignedMSI. Defaults to \"MultiTenant\"." + } + }, + "appId": { + "type": "string", + "metadata": { + "description": "Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings." + } + }, + "tenantId": { + "type": "string", + "defaultValue": "[subscription().tenantId]", + "metadata": { + "description": "The Azure AD Tenant ID to use as part of the Bot's Authentication. Only used for SingleTenant and UserAssignedMSI app types. Defaults to \"Subscription Tenant ID\"." + } + }, + "UMSIName": { + "type": "string", + "metadata": { + "description": "The User-Assigned Managed Identity Resource used for the Bot's Authentication." + } + }, + "UMSIResourceGroupName": { + "type": "string", + "metadata": { + "description": "The User-Assigned Managed Identity Resource Group used for the Bot's Authentication." + } + } + }, + "variables": { + "tenantId": "[if(empty(parameters('tenantId')), subscription().tenantId, parameters('tenantId'))]", + "msiResourceId": "[concat(subscription().id, '/resourceGroups/', parameters('UMSIResourceGroupName'), '/providers/', 'Microsoft.ManagedIdentity/userAssignedIdentities/', parameters('UMSIName'))]", + "appTypeDef": { + "MultiTenant": { + "tenantId": "", + "msiResourceId": "" + }, + "SingleTenant": { + "tenantId": "[variables('tenantId')]", + "msiResourceId": "" + }, + "UserAssignedMSI": { + "tenantId": "[variables('tenantId')]", + "msiResourceId": "[variables('msiResourceId')]" + } + }, + "appType": { + "tenantId": "[variables('appTypeDef')[parameters('appType')].tenantId]", + "msiResourceId": "[variables('appTypeDef')[parameters('appType')].msiResourceId]" + } + }, + "resources": [ + { + "name": "[parameters('groupName')]", + "type": "Microsoft.Resources/resourceGroups", + "apiVersion": "2018-05-01", + "location": "[parameters('groupLocation')]", + "properties": {} + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2018-05-01", + "name": "storageDeployment", + "resourceGroup": "[parameters('groupName')]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/resourceGroups/', parameters('groupName'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": {}, + "variables": {}, + "resources": [ + { + "apiVersion": "2021-03-01", + "type": "Microsoft.BotService/botServices", + "name": "[parameters('azureBotId')]", + "location": "[parameters('azureBotRegion')]", + "kind": "azurebot", + "sku": { + "name": "[parameters('azureBotSku')]" + }, + "properties": { + "name": "[parameters('azureBotId')]", + "displayName": "[parameters('azureBotId')]", + "iconUrl": "https://docs.botframework.com/static/devportal/client/images/bot-framework-default.png", + "endpoint": "[parameters('botEndpoint')]", + "msaAppId": "[parameters('appId')]", + "msaAppTenantId": "[variables('appType').tenantId]", + "msaAppMSIResourceId": "[variables('appType').msiResourceId]", + "msaAppType": "[parameters('appType')]", + "luisAppIds": [], + "schemaTransformationVersion": "1.3", + "isCmekEnabled": false, + "isIsolated": false + } + } + ] + } + } + } + ] +} \ No newline at end of file diff --git a/samples/BotPowered-BasicAce-Tasks/DeploymentTemplates/DeployWithNewResourceGroup/template-BotApp-new-rg.json b/samples/BotPowered-BasicAce-Tasks/DeploymentTemplates/DeployWithNewResourceGroup/template-BotApp-new-rg.json new file mode 100644 index 00000000..ad065070 --- /dev/null +++ b/samples/BotPowered-BasicAce-Tasks/DeploymentTemplates/DeployWithNewResourceGroup/template-BotApp-new-rg.json @@ -0,0 +1,211 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "groupName": { + "type": "string", + "metadata": { + "description": "Specifies the name of the Resource Group." + } + }, + "groupLocation": { + "type": "string", + "metadata": { + "description": "Specifies the location of the Resource Group." + } + }, + "appServiceName": { + "type": "string", + "metadata": { + "description": "The globally unique name of the Web App." + } + }, + "appServicePlanName": { + "type": "string", + "metadata": { + "description": "The name of the App Service Plan." + } + }, + "appServicePlanLocation": { + "type": "string", + "metadata": { + "description": "The location of the App Service Plan." + } + }, + "appServicePlanSku": { + "type": "object", + "defaultValue": { + "name": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "capacity": 1 + }, + "metadata": { + "description": "The SKU of the App Service Plan. Defaults to Standard values." + } + }, + "tenantId": { + "type": "string", + "defaultValue": "[subscription().tenantId]", + "metadata": { + "description": "The Azure AD Tenant ID to use as part of the Bot's Authentication. Only used for SingleTenant and UserAssignedMSI app types. Defaults to \"Subscription Tenant ID\"." + } + }, + "appType": { + "type": "string", + "defaultValue": "MultiTenant", + "allowedValues": [ + "MultiTenant", + "SingleTenant", + "UserAssignedMSI" + ], + "metadata": { + "description": "Type of Bot Authentication. set as MicrosoftAppType in the Web App's Application Settings. Allowed values are: MultiTenant, SingleTenant, UserAssignedMSI. Defaults to \"MultiTenant\"." + } + }, + "appId": { + "type": "string", + "metadata": { + "description": "Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings." + } + }, + "appSecret": { + "type": "string", + "metadata": { + "description": "Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings. Required for MultiTenant and SingleTenant app types." + } + }, + "UMSIName": { + "type": "string", + "metadata": { + "description": "The User-Assigned Managed Identity Resource used for the Bot's Authentication." + } + }, + "UMSIResourceGroupName": { + "type": "string", + "metadata": { + "description": "The User-Assigned Managed Identity Resource Group used for the Bot's Authentication." + } + } + }, + "variables": { + "tenantId": "[if(empty(parameters('tenantId')), subscription().tenantId, parameters('tenantId'))]", + "appServicePlanName": "[parameters('appServicePlanName')]", + "resourcesLocation": "[if(empty(parameters('appServicePlanLocation')), parameters('groupLocation'), parameters('appServicePlanLocation'))]", + "appServiceName": "[parameters('appServiceName')]", + "resourceGroupId": "[concat(subscription().id, '/resourceGroups/', parameters('groupName'))]", + "msiResourceId": "[concat(subscription().id, '/resourceGroups/', parameters('UMSIResourceGroupName'), '/providers/', 'Microsoft.ManagedIdentity/userAssignedIdentities/', parameters('UMSIName'))]", + "appTypeDef": { + "MultiTenant": { + "tenantId": "", + "identity": { "type": "None" } + }, + "SingleTenant": { + "tenantId": "[variables('tenantId')]", + "identity": { "type": "None" } + }, + "UserAssignedMSI": { + "tenantId": "[variables('tenantId')]", + "identity": { + "type": "UserAssigned", + "userAssignedIdentities": { + "[variables('msiResourceId')]": {} + } + } + } + }, + "appType": { + "tenantId": "[variables('appTypeDef')[parameters('appType')].tenantId]", + "identity": "[variables('appTypeDef')[parameters('appType')].identity]" + } + }, + "resources": [ + { + "name": "[parameters('groupName')]", + "type": "Microsoft.Resources/resourceGroups", + "apiVersion": "2018-05-01", + "location": "[parameters('groupLocation')]", + "properties": {} + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2018-05-01", + "name": "storageDeployment", + "resourceGroup": "[parameters('groupName')]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/resourceGroups/', parameters('groupName'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": {}, + "variables": {}, + "resources": [ + { + "comments": "Create a new App Service Plan", + "type": "Microsoft.Web/serverfarms", + "name": "[variables('appServicePlanName')]", + "apiVersion": "2018-02-01", + "location": "[variables('resourcesLocation')]", + "sku": "[parameters('appServicePlanSku')]", + "properties": { + "name": "[variables('appServicePlanName')]" + } + }, + { + "comments": "Create a Web App using the new App Service Plan", + "type": "Microsoft.Web/sites", + "apiVersion": "2015-08-01", + "location": "[variables('resourcesLocation')]", + "kind": "app", + "dependsOn": [ + "[concat(variables('resourceGroupId'), '/providers/Microsoft.Web/serverfarms/', variables('appServicePlanName'))]" + ], + "name": "[variables('appServiceName')]", + "identity": "[variables('appType').identity]", + "properties": { + "name": "[variables('appServiceName')]", + "serverFarmId": "[variables('appServicePlanName')]", + "siteConfig": { + "appSettings": [ + { + "name": "WEBSITE_NODE_DEFAULT_VERSION", + "value": "10.14.1" + }, + { + "name": "MicrosoftAppType", + "value": "[parameters('appType')]" + }, + { + "name": "MicrosoftAppId", + "value": "[parameters('appId')]" + }, + { + "name": "MicrosoftAppPassword", + "value": "[parameters('appSecret')]" + }, + { + "name": "MicrosoftAppTenantId", + "value": "[variables('appType').tenantId]" + } + ], + "cors": { + "allowedOrigins": [ + "https://botservice.hosting.portal.azure.net", + "https://hosting.onecloud.azure-test.net/" + ] + }, + "webSocketsEnabled": true + } + } + } + ], + "outputs": {} + } + } + } + ] +} \ No newline at end of file diff --git a/samples/BotPowered-BasicAce/Program.cs b/samples/BotPowered-BasicAce-Tasks/Program.cs similarity index 94% rename from samples/BotPowered-BasicAce/Program.cs rename to samples/BotPowered-BasicAce-Tasks/Program.cs index 38cfd7ea..1b48b83e 100644 --- a/samples/BotPowered-BasicAce/Program.cs +++ b/samples/BotPowered-BasicAce-Tasks/Program.cs @@ -6,7 +6,7 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Hosting; -namespace BotPowered_BasicAce +namespace BotPowered_BasicAce_Tasks { public class Program { diff --git a/samples/BotPowered-BasicAce-Tasks/Properties/launchSettings.json b/samples/BotPowered-BasicAce-Tasks/Properties/launchSettings.json new file mode 100644 index 00000000..edde2eb9 --- /dev/null +++ b/samples/BotPowered-BasicAce-Tasks/Properties/launchSettings.json @@ -0,0 +1,28 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:3978", + "sslPort": 0 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "$safeprojectname$": { + "commandName": "Project", + "launchBrowser": true, + "applicationUrl": "https://localhost:3979;http://localhost:3978", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/samples/BotPowered-BasicAce-Tasks/QuickViewTemplates/ListTasksQuickView.json b/samples/BotPowered-BasicAce-Tasks/QuickViewTemplates/ListTasksQuickView.json new file mode 100644 index 00000000..ce6be737 --- /dev/null +++ b/samples/BotPowered-BasicAce-Tasks/QuickViewTemplates/ListTasksQuickView.json @@ -0,0 +1,105 @@ +{ + "schema": "http://adaptivecards.io/schemas/adaptive-card.json", + "type": "AdaptiveCard", + "version": "1.2", + "body": [ + { + "type": "TextBlock", + "weight": "Bolder", + "text": "${title}" + }, + { + "type": "Container", + "spacing": "Large", + "style": "emphasis", + "items": [ + { + "type": "ColumnSet", + "columns": [ + { + "type": "Column", + "items": [ + { + "type": "TextBlock", + "weight": "Bolder", + "text": "Title", + "wrap": true + } + ], + "width": "60px" + }, + { + "type": "Column", + "items": [ + { + "type": "TextBlock", + "weight": "Bolder", + "text": "Description", + "wrap": true + } + ], + "width": "150px" + }, + { + "type": "Column", + "items": [ + { + "type": "TextBlock", + "weight": "Bolder", + "text": "Due Date", + "wrap": true + } + ], + "width": "80px" + } + ] + } + ], + "bleed": true + }, + { + "$data": "${tasks}", + "type": "Container", + "items": [ + { + "type": "ColumnSet", + "columns": [ + { + "type": "Column", + "items": [ + { + "type": "TextBlock", + "text": "${Title}", + "wrap": true + } + ], + "width": "60px" + }, + { + "type": "Column", + "items": [ + { + "type": "TextBlock", + "text": "${Description}", + "wrap": true + } + ], + "width": "150px" + }, + { + "type": "Column", + "items": [ + { + "type": "TextBlock", + "text": "${formatDateTime(DueDate, 'yyyy-MM-dd')}", + "wrap": true + } + ], + "width": "80px" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/samples/BotPowered-BasicAce-Tasks/README.md b/samples/BotPowered-BasicAce-Tasks/README.md new file mode 100644 index 00000000..d8e92c4b --- /dev/null +++ b/samples/BotPowered-BasicAce-Tasks/README.md @@ -0,0 +1,98 @@ +# Bot-Powered-ACE Tasks + +This sample shows how to create a Viva Connection Adaptive Card Extension (ACE) to show hypothetical tasks for the current user. The ACE has been implemented using a Bot-Powered-ACE based on .NET. + +Here you can see main CardView of the ACE to see a recap of the active tasks in action: + +![Active tasks CardView](./assets/tasks-ace-01.png) + +Here you can see the CardView that shows a single task: + +![Single task CardView](./assets/tasks-ace-02.png) + +And here you can see the QuickView to list all the tasks: + +![List tasks QuickView](./assets/tasks-ace-03.png) + +## Used Bot Framework Version + +This bot has been created using [Bot Framework](https://dev.botframework.com). + +## Applies to + +- [Microsoft SharePoint Online](https://www.microsoft.com/en-us/microsoft-365/sharepoint/collaboration) +- [Microsoft Viva Connections](https://learn.microsoft.com/en-us/viva/connections/viva-connections-overview) + +> Get your own free development tenant by subscribing to [Microsoft 365 developer program](http://aka.ms/o365devprogram) + +## Solution + +| Solution | Author(s) | +| ----------- | ------------------------------------------------------- | +| BotPowered-BasicAce-Tasks | Paolo Pialorsi Paolo Pialorsi - [PiaSys.com](https://www.piasys.com/) - [@PaoloPia](https://twitter.com/PaoloPia) | + +## Version history + +| Version | Date | Comments | +| ------- | ---------------- | --------------- | +| 1.0 | December 14, 2023 | Initial release | + +## Disclaimer + +**THIS CODE IS PROVIDED _AS IS_ WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.** + +--- + +## Minimal Path to Awesome + +### Prerequisites + +- [.NET SDK](https://dotnet.microsoft.com/download) version 6.0 + + ```bash + # determine dotnet version + dotnet --version + ``` + +### To try this sample + +- In a terminal, navigate to `BotPowered_BasicAce_Tasks` + + ```bash + # change into project folder + cd BotPowered_BasicAce_Tasks + ``` + +- Run the bot from a terminal or from Visual Studio, choose option A or B. + + A) From a terminal + + ```bash + # run the bot + dotnet run + ``` + + B) Or from Visual Studio + + - Launch Visual Studio + - File -> Open -> Project/Solution + - Navigate to `BotPowered-BasicAce-Tasks` folder + - Select `BotPowered-BasicAce-Tasks.csproj` file + - Press `F5` to run the project + +### Deploy the bot to Azure + +To learn more about deploying a bot to Azure, see [Deploy your bot to Azure](https://aka.ms/azuredeployment) for a complete list of deployment instructions. + +### Further reading + +- [Bot Framework Documentation](https://docs.botframework.com) +- [Bot Basics](https://docs.microsoft.com/azure/bot-service/bot-builder-basics?view=azure-bot-service-4.0) +- [Activity processing](https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-concept-activity-processing?view=azure-bot-service-4.0) +- [Azure Bot Service Introduction](https://docs.microsoft.com/azure/bot-service/bot-service-overview-introduction?view=azure-bot-service-4.0) +- [Azure Bot Service Documentation](https://docs.microsoft.com/azure/bot-service/?view=azure-bot-service-4.0) +- [.NET Core CLI tools](https://docs.microsoft.com/en-us/dotnet/core/tools/?tabs=netcore2x) +- [Azure CLI](https://docs.microsoft.com/cli/azure/?view=azure-cli-latest) +- [Azure Portal](https://portal.azure.com) +- [Language Understanding using LUIS](https://docs.microsoft.com/en-us/azure/cognitive-services/luis/) +- [Channels and Bot Connector Service](https://docs.microsoft.com/en-us/azure/bot-service/bot-concepts?view=azure-bot-service-4.0) diff --git a/samples/BotPowered-BasicAce/Startup.cs b/samples/BotPowered-BasicAce-Tasks/Startup.cs similarity index 98% rename from samples/BotPowered-BasicAce/Startup.cs rename to samples/BotPowered-BasicAce-Tasks/Startup.cs index 432ad256..a107c382 100644 --- a/samples/BotPowered-BasicAce/Startup.cs +++ b/samples/BotPowered-BasicAce-Tasks/Startup.cs @@ -12,7 +12,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -namespace BotPowered_BasicAce +namespace BotPowered_BasicAce_Tasks { public class Startup { diff --git a/samples/BotPowered-BasicAce/TaskItem.cs b/samples/BotPowered-BasicAce-Tasks/TaskItem.cs similarity index 88% rename from samples/BotPowered-BasicAce/TaskItem.cs rename to samples/BotPowered-BasicAce-Tasks/TaskItem.cs index e8eafe3b..c67f80b1 100644 --- a/samples/BotPowered-BasicAce/TaskItem.cs +++ b/samples/BotPowered-BasicAce-Tasks/TaskItem.cs @@ -1,7 +1,7 @@ using Microsoft.Bot.Schema.SharePoint; using System; -namespace BotPowered_BasicAce +namespace BotPowered_BasicAce_Tasks { public class TaskItem { diff --git a/samples/BotPowered-BasicAce/TasksBot.cs b/samples/BotPowered-BasicAce-Tasks/TasksBot.cs similarity index 98% rename from samples/BotPowered-BasicAce/TasksBot.cs rename to samples/BotPowered-BasicAce-Tasks/TasksBot.cs index 9950b942..f0001c62 100644 --- a/samples/BotPowered-BasicAce/TasksBot.cs +++ b/samples/BotPowered-BasicAce-Tasks/TasksBot.cs @@ -19,7 +19,7 @@ using System.IO; using AdaptiveCards.Templating; -namespace BotPowered_BasicAce +namespace BotPowered_BasicAce_Tasks { public class TasksBot : SharePointActivityHandler { @@ -29,7 +29,6 @@ public class TasksBot : SharePointActivityHandler private static ConcurrentDictionary cardViews = new ConcurrentDictionary(); private static ConcurrentDictionary quickViews = new ConcurrentDictionary(); - private static bool cardsInitialized = false; private static string MainCardView_ID = "MAIN_TASKS_CARD_VIEW"; private static string SingleTaskCardView_ID = "SINGLE_TASK_CARD_VIEW"; @@ -48,9 +47,6 @@ public TasksBot(IConfiguration configuration) this.configuration = configuration; this.baseUrl = configuration["BaseUrl"]; - // Skip cards init if it has already been done - // if (cardsInitialized) return; - // Add the CardViews var aceData = new AceData() { @@ -175,9 +171,6 @@ public TasksBot(IConfiguration configuration) listTasksQuickViewResponse.ViewId = ListTasksQuickView_ID; quickViews.TryAdd(listTasksQuickViewResponse.ViewId, listTasksQuickViewResponse); - - // Set cards as already initialized - cardsInitialized = true; } protected override Task OnSharePointTaskGetCardViewAsync(ITurnContext turnContext, AceRequest aceRequest, CancellationToken cancellationToken) diff --git a/samples/BotPowered-BasicAce-Tasks/TeamsAppManifest/botpowered.basicace.zip b/samples/BotPowered-BasicAce-Tasks/TeamsAppManifest/botpowered.basicace.zip new file mode 100644 index 00000000..21d28bc7 Binary files /dev/null and b/samples/BotPowered-BasicAce-Tasks/TeamsAppManifest/botpowered.basicace.zip differ diff --git a/samples/BotPowered-BasicAce-Tasks/TeamsAppManifest/icon-color.png b/samples/BotPowered-BasicAce-Tasks/TeamsAppManifest/icon-color.png new file mode 100644 index 00000000..b8cf81af Binary files /dev/null and b/samples/BotPowered-BasicAce-Tasks/TeamsAppManifest/icon-color.png differ diff --git a/samples/BotPowered-BasicAce-Tasks/TeamsAppManifest/icon-outline.png b/samples/BotPowered-BasicAce-Tasks/TeamsAppManifest/icon-outline.png new file mode 100644 index 00000000..2c3bf6fa Binary files /dev/null and b/samples/BotPowered-BasicAce-Tasks/TeamsAppManifest/icon-outline.png differ diff --git a/samples/BotPowered-BasicAce-Tasks/TeamsAppManifest/manifest.json b/samples/BotPowered-BasicAce-Tasks/TeamsAppManifest/manifest.json new file mode 100644 index 00000000..dbaecaae --- /dev/null +++ b/samples/BotPowered-BasicAce-Tasks/TeamsAppManifest/manifest.json @@ -0,0 +1,65 @@ +{ + "$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.14/MicrosoftTeams.schema.json", + "manifestVersion": "1.16", + "version": "1.0.0", + "id": "0910daf8-c72d-411f-845a-0436941165ed", + "packageName": "botpowered.basicace", + "developer": { + "name": "PiaSys.com", + "websiteUrl": "https://www.piasys.com/", + "privacyUrl": "http://piasys.com/privacy/", + "termsOfUseUrl": "https://www.piasys.com/terms-of-use/", + "mpnId": "1075379" + }, + "name": { + "short": "BOT-Powered ACE Basic Demo", + "full": "This is a basic demo of a BOT-Powered ACE for Microsoft Viva Connections Dashboard to show hypothetical user's tasks" + }, + "description": { + "short": "Basic demo of a BOT-Powered ACE for Microsoft Viva Connections Dashboard to show hypothetical user's tasks", + "full": "Basic demo of how to use the latest release of the BOT Framework SDK to build a BOT-Powered ACE for Microsoft Viva Connections Dashboard to show hypothetical user's tasks" + }, + "icons": { + "outline": "icon-outline.png", + "color": "icon-color.png" + }, + "accentColor": "#FFFFFF", + "bots": [ + { + "botId": "0910daf8-c72d-411f-845a-0436941165ed", + "needsChannelSelector": false, + "isNotificationOnly": false, + "supportsCalling": false, + "supportsVideo": false, + "supportsFiles": false, + "scopes": [ + "team", + "personal", + "groupchat" + ] + } + ], + "dashboardCards": [ + { + "id": "0910daf8-c72d-411f-845a-0436941165ed", + "displayName": "BOT-Powered ACE Tasks", + "description": "BOT-Powered ACE Tasks demo", + "icon": { + "officeUIFabricIconName": "TaskSolid" + }, + "contentSource": { + "sourceType": "bot", + "botConfiguration": { + "botId": "0910daf8-c72d-411f-845a-0436941165ed" + } + }, + "defaultSize": "medium" + } + ], + "permissions": [ + "identity" + ], + "validDomains": [ + "piasys-ace-basic.ngrok.io" + ] +} \ No newline at end of file diff --git a/samples/BotPowered-BasicAce-Tasks/appsettings.Development.json b/samples/BotPowered-BasicAce-Tasks/appsettings.Development.json new file mode 100644 index 00000000..e203e940 --- /dev/null +++ b/samples/BotPowered-BasicAce-Tasks/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } + } +} diff --git a/samples/BotPowered-BasicAce-Tasks/appsettings.json b/samples/BotPowered-BasicAce-Tasks/appsettings.json new file mode 100644 index 00000000..3eb7cb42 --- /dev/null +++ b/samples/BotPowered-BasicAce-Tasks/appsettings.json @@ -0,0 +1,8 @@ +{ + "MicrosoftAppType": "MultiTenant", + "MicrosoftAppId": "", + "MicrosoftAppPassword": "", + "MicrosoftAppTenantId": "", + "BaseUrl": "", + "TemplatesPath": "" +} diff --git a/samples/BotPowered-BasicAce-Tasks/assets/sample.json b/samples/BotPowered-BasicAce-Tasks/assets/sample.json new file mode 100644 index 00000000..a78cd64c --- /dev/null +++ b/samples/BotPowered-BasicAce-Tasks/assets/sample.json @@ -0,0 +1,69 @@ +[{ + "name": "pnp-sp-fx-aces-botpowered-basicace-tasks", + "source": "pnp", + "title": "Bot-Powered-ACE Tasks", + "shortDescription": "Viva Connection Adaptive Card Extension (ACE) that shows how to show hypothetical tasks for the current user using a Bot-Powered-ACE implemented with .NET.", + "url": "https://github.com/pnp/sp-dev-fx-aces/tree/main/samples/BotPowered-BasicAce-Tasks", + "longDescription": [ + "Viva Connection Adaptive Card Extension (ACE) that shows how to show hypothetical tasks for the current user using a Bot-Powered-ACE implemented with .NET." + ], + "creationDateTime": "2023-12-14", + "updateDateTime": "2023-12-14", + "products": [ + "SharePoint", + "Viva" + ], + "metadata": [ + { + "key": "BOT-FRAMEWORK-VERSION", + "value": "bot40" + } + ], + "thumbnails": [ + { + "type": "image", + "order": 100, + "url": "https://raw.githubusercontent.com/pnp/sp-dev-fx-aces/main/samples/BotPowered-BasicAce-CollectFeedback/assets/tasks-ace-01.png", + "alt": "Preview of the main CardView to show a recap of the active tasks" + }, + { + "type": "image", + "order": 200, + "url": "https://raw.githubusercontent.com/pnp/sp-dev-fx-aces/main/samples/BotPowered-BasicAce-CollectFeedback/assets/tasks-ace-02.png", + "alt": "Preview of the CardView showing a single task" + }, + { + "type": "image", + "order": 300, + "url": "https://raw.githubusercontent.com/pnp/sp-dev-fx-aces/main/samples/BotPowered-BasicAce-CollectFeedback/assets/tasks-ace-03.png", + "alt": "Preview of the main QuickView to show a detailed list of tasks" + } + + ], + "authors": [ + { + "gitHubAccount": "PaoloPia", + "company": "PiaSys.com", + "pictureUrl": "https://github.com/paolopia.png", + "name": "Paolo Pialorsi", + "twitter": "PaoloPia" + } + ], + "references": [ + { + "name": "Viva Connections Extensibility guidance", + "description": "Adaptive Card Extensions are client-side components that run in the context of a SharePoint page.", + "url": "https://aka.ms/viva/connections/extensibility" + }, + { + "name": "Adaptive Card Documentation", + "description": "Detailed documentation on Adaptive Cards including the Adaptive Card designer.", + "url": "https://adaptivecards.io/" + }, + { + "name": "Adaptive Card Extension Design Guidance", + "description": "Design guidance for laying out Adaptive Card Extensions.", + "url": "https://docs.microsoft.com/en-us/sharepoint/dev/spfx/viva/design/design-intro" + } + ] +}] \ No newline at end of file diff --git a/samples/BotPowered-BasicAce-Tasks/assets/tasks-ace-01.png b/samples/BotPowered-BasicAce-Tasks/assets/tasks-ace-01.png new file mode 100644 index 00000000..cd39a742 Binary files /dev/null and b/samples/BotPowered-BasicAce-Tasks/assets/tasks-ace-01.png differ diff --git a/samples/BotPowered-BasicAce-Tasks/assets/tasks-ace-02.png b/samples/BotPowered-BasicAce-Tasks/assets/tasks-ace-02.png new file mode 100644 index 00000000..ddd8f627 Binary files /dev/null and b/samples/BotPowered-BasicAce-Tasks/assets/tasks-ace-02.png differ diff --git a/samples/BotPowered-BasicAce-Tasks/assets/tasks-ace-03.png b/samples/BotPowered-BasicAce-Tasks/assets/tasks-ace-03.png new file mode 100644 index 00000000..08c2bc9b Binary files /dev/null and b/samples/BotPowered-BasicAce-Tasks/assets/tasks-ace-03.png differ diff --git a/samples/BotPowered-BasicAce/wwwroot/Media/List-of-Tasks.png b/samples/BotPowered-BasicAce-Tasks/wwwroot/Media/List-of-Tasks.png similarity index 100% rename from samples/BotPowered-BasicAce/wwwroot/Media/List-of-Tasks.png rename to samples/BotPowered-BasicAce-Tasks/wwwroot/Media/List-of-Tasks.png diff --git a/samples/BotPowered-BasicAce-Tasks/wwwroot/default.htm b/samples/BotPowered-BasicAce-Tasks/wwwroot/default.htm new file mode 100644 index 00000000..f58d62ca --- /dev/null +++ b/samples/BotPowered-BasicAce-Tasks/wwwroot/default.htm @@ -0,0 +1,420 @@ + + + + + + + BotPowered_BasicAce + + + + + +
+
+
+
BotPowered_BasicAce Bot
+
+
+
+
+
Your bot is ready!
+
You can test your bot in the Bot Framework Emulator
+ by connecting to http://localhost:3978/api/messages.
+ +
Visit Azure + Bot Service to register your bot and add it to
+ various channels. The bot's endpoint URL typically looks + like this:
+
https://your_bots_hostname/api/messages
+
+
+
+
+ +
+ + + \ No newline at end of file diff --git a/samples/BotPowered-BasicAce/README.md b/samples/BotPowered-BasicAce/README.md deleted file mode 100644 index f9f190ce..00000000 --- a/samples/BotPowered-BasicAce/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# BotPowered_BasicAce - -Bot Framework v4 empty bot sample. - -This bot has been created using [Bot Framework](https://dev.botframework.com), it shows the minimum code required to build a bot. - -## Prerequisites - -- [.NET SDK](https://dotnet.microsoft.com/download) version 6.0 - - ```bash - # determine dotnet version - dotnet --version - ``` - -## To try this sample - -- In a terminal, navigate to `BotPowered_BasicAce` - - ```bash - # change into project folder - cd BotPowered_BasicAce - ``` - -- Run the bot from a terminal or from Visual Studio, choose option A or B. - - A) From a terminal - - ```bash - # run the bot - dotnet run - ``` - - B) Or from Visual Studio - - - Launch Visual Studio - - File -> Open -> Project/Solution - - Navigate to `BotPowered_BasicAce` folder - - Select `BotPowered_BasicAce.csproj` file - - Press `F5` to run the project - -## Testing the bot using Bot Framework Emulator - -[Bot Framework Emulator](https://github.com/microsoft/botframework-emulator) is a desktop application that allows bot developers to test and debug their bots on localhost or running remotely through a tunnel. - -- Install the Bot Framework Emulator version 4.3.0 or greater from [here](https://github.com/Microsoft/BotFramework-Emulator/releases) - -### Connect to the bot using Bot Framework Emulator - -- Launch Bot Framework Emulator -- File -> Open Bot -- Enter a Bot URL of `http://localhost:3978/api/messages` - -## Deploy the bot to Azure - -To learn more about deploying a bot to Azure, see [Deploy your bot to Azure](https://aka.ms/azuredeployment) for a complete list of deployment instructions. - -## Further reading - -- [Bot Framework Documentation](https://docs.botframework.com) -- [Bot Basics](https://docs.microsoft.com/azure/bot-service/bot-builder-basics?view=azure-bot-service-4.0) -- [Activity processing](https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-concept-activity-processing?view=azure-bot-service-4.0) -- [Azure Bot Service Introduction](https://docs.microsoft.com/azure/bot-service/bot-service-overview-introduction?view=azure-bot-service-4.0) -- [Azure Bot Service Documentation](https://docs.microsoft.com/azure/bot-service/?view=azure-bot-service-4.0) -- [.NET Core CLI tools](https://docs.microsoft.com/en-us/dotnet/core/tools/?tabs=netcore2x) -- [Azure CLI](https://docs.microsoft.com/cli/azure/?view=azure-cli-latest) -- [Azure Portal](https://portal.azure.com) -- [Language Understanding using LUIS](https://docs.microsoft.com/en-us/azure/cognitive-services/luis/) -- [Channels and Bot Connector Service](https://docs.microsoft.com/en-us/azure/bot-service/bot-concepts?view=azure-bot-service-4.0)