diff --git a/RelayBotSample/AdapterWithErrorHandler.cs b/RelayBotSample/AdapterWithErrorHandler.cs deleted file mode 100644 index 57a27b15..00000000 --- a/RelayBotSample/AdapterWithErrorHandler.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using Microsoft.Bot.Builder.Integration.AspNet.Core; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; - -namespace Microsoft.PowerVirtualAgents.Samples.RelayBotSample -{ - public class AdapterWithErrorHandler : BotFrameworkHttpAdapter - { - public AdapterWithErrorHandler(IConfiguration configuration, ILogger logger) - : base(configuration, logger) - { - OnTurnError = async (turnContext, exception) => - { - // Log any leaked exception from the application. - logger.LogError($"Exception caught : {exception.ToString()}"); - - // Send a catch-all apology to the user. - await turnContext.SendActivityAsync("Sorry, it looks like something went wrong."); - }; - } - } -} diff --git a/RelayBotSample/BotConnector/BotService.cs b/RelayBotSample/BotConnector/BotService.cs deleted file mode 100644 index 4a239143..00000000 --- a/RelayBotSample/BotConnector/BotService.cs +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using Microsoft.Rest.Serialization; -using System; -using System.Net.Http; -using System.Threading.Tasks; - -namespace Microsoft.PowerVirtualAgents.Samples.RelayBotSample -{ - /// - /// Bot Service class to interact with bot - /// - public class BotService : IBotService - { - private static readonly HttpClient s_httpClient = new HttpClient(); - - public string BotName { get; set; } - - public string BotId { get; set; } - - public string TenantId { get; set; } - - public string TokenEndPoint { get; set; } - - public string GetBotName() - { - return BotName; - } - - /// - /// Get directline token for connecting bot - /// - /// directline token as string - public async Task GetTokenAsync() - { - string token; - using (var httpRequest = new HttpRequestMessage()) - { - httpRequest.Method = HttpMethod.Get; - UriBuilder uriBuilder = new UriBuilder(TokenEndPoint); - uriBuilder.Query = $"botId={BotId}&tenantId={TenantId}"; - httpRequest.RequestUri = uriBuilder.Uri; - using (var response = await s_httpClient.SendAsync(httpRequest)) - { - var responseString = await response.Content.ReadAsStringAsync(); - token = SafeJsonConvert.DeserializeObject(responseString).Token; - } - } - - return token; - } - } -} diff --git a/RelayBotSample/BotConnector/ConversationManager.cs b/RelayBotSample/BotConnector/ConversationManager.cs deleted file mode 100644 index adc2f6d3..00000000 --- a/RelayBotSample/BotConnector/ConversationManager.cs +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using Microsoft.Bot.Connector.DirectLine; -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using System.Timers; - -namespace Microsoft.PowerVirtualAgents.Samples.RelayBotSample -{ - /// - /// class for manage lifecycle of all conversations, - /// including mapping of external Azure Bot Service channel conversation to your Power Virtual Agents bot converstaion, - /// creating/ending conversations and refreshing tokens - /// - public class ConversationManager - { - private static readonly object s_padlock = new object(); - private static ConversationManager s_singleton = null; - - public static Dictionary ConversationRouter { get; private set; } = new Dictionary(); - - public static double TokenRefreshCheckIntervalInMinute { get; set; } - - public static double TokenRefreshIntervalInMinute { get; set; } - - public static double ConversationEndAfterIdleTimeInMinute { get; set; } - - public static double ConversationEndCheckIntervalInMinute { get; set; } - - /// - /// Singleton instance of ConversationManager - /// - public static ConversationManager Instance - { - get - { - lock (s_padlock) - { - if (s_singleton == null) - { - // Initialize token refresh check timer and set interval. - Timer s_TokenRefreshTimer = new Timer(); - s_TokenRefreshTimer.Interval = TokenRefreshCheckIntervalInMinute * 60 * 1000; - - // Hook up the Elapsed event for the timer. - s_TokenRefreshTimer.Elapsed += OnTokenRefreshCheckEvent; - - // Have the timer fire repeated events (true is the default) - s_TokenRefreshTimer.AutoReset = true; - - // Start the timer - s_TokenRefreshTimer.Enabled = true; - - // Initialize conversation idle check timer and set interval. - Timer s_ConversationIdleCheckTimer = new Timer(); - s_ConversationIdleCheckTimer.Interval = ConversationEndCheckIntervalInMinute * 60 * 1000; - - // Hook up the Elapsed event for the timer. - s_ConversationIdleCheckTimer.Elapsed += OnConversationIdleCheckEvent; - - // Have the timer fire repeated events (true is the default) - s_ConversationIdleCheckTimer.AutoReset = true; - - // Start the timer - s_ConversationIdleCheckTimer.Enabled = true; - - s_singleton = new ConversationManager(); - } - - return s_singleton; - } - } - } - - /// - /// Search if an external Azure Bot Service channel conversation is - /// connected to an existing Power Virtual Agent bot conversation - /// - /// true if conversation mapping exists, otherwiser false - /// external Azure Bot Service channel conversation ID - public bool ConversationExists(string externalCID) - { - return ConversationRouter.ContainsKey(externalCID); - } - - /// - /// Start a Power Virtual Agent bot conversation - /// for an external Azure Bot Service channel conversation - /// - /// Created Power Virtual Agent bot conversation - /// external Azure Bot Service channel conversation ID - public async Task StartBotConversationAsync(string externalCID, IBotService botService) - { - string token = await botService.GetTokenAsync(); - using (var directLineClient = new DirectLineClient(token)) - { - var conversation = await directLineClient.Conversations.StartConversationAsync(); - string conversationId = conversation?.ConversationId; - if (string.IsNullOrEmpty(conversationId)) - { - throw new TaskCanceledException("Exception caught: directline failed to create conversation using retrieved token"); - } - - var newBotConversation = new RelayConversation() - { - Token = token, - ConversationtId = conversationId, - WaterMark = null, - }; - ConversationRouter[externalCID] = newBotConversation; - } - - return ConversationRouter[externalCID]; - } - - /// - /// Retrive or start a Power Virtual Agent bot conversation - /// for a given external Azure Bot Service channel conversation - /// - /// Power Virtual Agent bot conversation - /// external Azure Bot Service channel conversation ID - public async Task GetOrCreateBotConversationAsync(string externalCID, IBotService botService) - { - return ConversationRouter.TryGetValue(externalCID, out var botConversation) ? - botConversation : await StartBotConversationAsync(externalCID, botService); - } - - private static void OnTokenRefreshCheckEvent(object source, ElapsedEventArgs e) - { - foreach (var conversation in ConversationRouter.Values) - { - if (DateTime.Now - conversation.LastTokenRefreshTime >= - TimeSpan.FromMinutes(TokenRefreshIntervalInMinute)) - { - // last token refresh TokenRefreshIntervalInMinute ago, refresh token - conversation.LastTokenRefreshTime = DateTime.Now; - using (var client = new DirectLineClient(conversation.Token)) - { - conversation.Token = client.Tokens.RefreshToken().Token; - } - } - } - } - - private static void OnConversationIdleCheckEvent(object source, ElapsedEventArgs e) - { - foreach (var externalConversationId in ConversationRouter.Keys) - { - var conversation = ConversationRouter[externalConversationId]; - if (DateTime.Now - conversation.LastConversationUpdateTime > - TimeSpan.FromMinutes(ConversationEndAfterIdleTimeInMinute)) - { - // conversation inactive for > ConversationEndAfterIdleTimeInMinute, removing from s_conversationRouter - // If same external conversation active again, a new bot conversation will be created - conversation = null; - ConversationRouter.Remove(externalConversationId); - } - } - } - } -} diff --git a/RelayBotSample/BotConnector/DirectLineToken.cs b/RelayBotSample/BotConnector/DirectLineToken.cs deleted file mode 100644 index 3a992b8a..00000000 --- a/RelayBotSample/BotConnector/DirectLineToken.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -namespace Microsoft.PowerVirtualAgents.Samples.RelayBotSample -{ - /// - /// class for serialization/deserialization DirectLineToken - /// - public class DirectLineToken - { - /// - /// constructor - /// - /// Directline token string - public DirectLineToken(string token) - { - Token = token; - } - - public string Token { get; set; } - } -} diff --git a/RelayBotSample/BotConnector/IBotService.cs b/RelayBotSample/BotConnector/IBotService.cs deleted file mode 100644 index d25438fe..00000000 --- a/RelayBotSample/BotConnector/IBotService.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System.Threading.Tasks; - -namespace Microsoft.PowerVirtualAgents.Samples.RelayBotSample -{ - public interface IBotService - { - string GetBotName(); - - Task GetTokenAsync(); - } -} \ No newline at end of file diff --git a/RelayBotSample/BotConnector/RelayConversation.cs b/RelayBotSample/BotConnector/RelayConversation.cs deleted file mode 100644 index 8b1b7255..00000000 --- a/RelayBotSample/BotConnector/RelayConversation.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using System; - -namespace Microsoft.PowerVirtualAgents.Samples.RelayBotSample -{ - /// - /// Data model class for Power Virtual Agent conversation - /// - public class RelayConversation - { - public string ConversationtId { get; set; } - - public string WaterMark { get; set; } - - public string Token { get; set; } - - public DateTime LastTokenRefreshTime { get; set; } = DateTime.Now; - - public DateTime LastConversationUpdateTime { get; set; } = DateTime.Now; - } -} \ No newline at end of file diff --git a/RelayBotSample/BotConnector/ResponseConverter.cs b/RelayBotSample/BotConnector/ResponseConverter.cs deleted file mode 100644 index 487cadee..00000000 --- a/RelayBotSample/BotConnector/ResponseConverter.cs +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using Microsoft.Bot.Builder; -using Microsoft.Bot.Schema; -using System.Collections.Generic; -using System.Linq; -using DirectLine = Microsoft.Bot.Connector.DirectLine; - -namespace Microsoft.PowerVirtualAgents.Samples.RelayBotSample -{ - /// - /// Class for converting Power Virtual Agents bot replied Direct Line Activity responses to standard Bot Schema activities - /// You can add customized response converting/parsing logic in this class - /// - public class ResponseConverter - { - /// - /// Convert single DirectLine activity into IMessageActivity instance - /// - /// IMessageActivity object as a message in a conversation - /// directline activity - public IMessageActivity ConvertToBotSchemaActivity(DirectLine.Activity directLineActivity) - { - if (directLineActivity == null) - { - return null; - } - - var dlAttachments = directLineActivity.Attachments; - if (dlAttachments != null && dlAttachments.Count() > 0) - { - return ConvertToAttachmentActivity(directLineActivity); - } - - if (directLineActivity.SuggestedActions != null) - { - return ConvertToSuggestedActionsAcitivity(directLineActivity); - } - - if (!string.IsNullOrEmpty(directLineActivity.Text)) - { - return MessageFactory.Text(directLineActivity.Text); - } - - return null; - } - - /// - /// Convert a list of DirectLine activities into list of IMessageActivity instances - /// - /// list of IMessageActivity objects as response messages in a conversation - /// list of directline activities - public IList ConvertToBotSchemaActivities(List directLineActivities) - { - return (directLineActivities == null || directLineActivities.Count() == 0) ? - new List() : - directLineActivities - .Select(directLineActivity => ConvertToBotSchemaActivity(directLineActivity)) - .ToList(); - } - - private IMessageActivity ConvertToAttachmentActivity(DirectLine.Activity directLineActivity) - { - var botSchemaAttachments = directLineActivity.Attachments.Select( - directLineAttachment => new Attachment() - { - ContentType = directLineAttachment.ContentType, - ContentUrl = directLineAttachment.ContentUrl, - Content = directLineAttachment.Content, - Name = directLineAttachment.Name, - ThumbnailUrl = directLineAttachment.ThumbnailUrl, - }).ToList(); - - return MessageFactory.Attachment( - botSchemaAttachments, - text: directLineActivity.Text, - ssml: directLineActivity.Speak, - inputHint: directLineActivity.InputHint); - } - - private IMessageActivity ConvertToSuggestedActionsAcitivity(DirectLine.Activity directLineActivity) - { - var directLineSuggestedActions = directLineActivity.SuggestedActions; - return MessageFactory.SuggestedActions( - actions: directLineSuggestedActions.Actions?.Select(action => action.Title).ToList(), - text: directLineActivity.Text, - ssml: directLineActivity.Speak, - inputHint: directLineActivity.InputHint); - } - } -} diff --git a/RelayBotSample/Bots/RelayBot.cs b/RelayBotSample/Bots/RelayBot.cs deleted file mode 100644 index b40d502e..00000000 --- a/RelayBotSample/Bots/RelayBot.cs +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using Microsoft.Bot.Builder; -using Microsoft.Bot.Connector.DirectLine; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using DirectLineActivity = Microsoft.Bot.Connector.DirectLine.Activity; -using DirectLineActivityTypes = Microsoft.Bot.Connector.DirectLine.ActivityTypes; -using IConversationUpdateActivity = Microsoft.Bot.Schema.IConversationUpdateActivity; -using IMessageActivity = Microsoft.Bot.Schema.IMessageActivity; - -namespace Microsoft.PowerVirtualAgents.Samples.RelayBotSample.Bots -{ - /// - /// This IBot implementation shows how to connect - /// an external Azure Bot Service channel bot (external bot) - /// to your Power Virtual Agent bot - /// - public class RelayBot : ActivityHandler - { - private const int WaitForBotResponseMaxMilSec = 5 * 1000; - private const int PollForBotResponseIntervalMilSec = 1000; - private static ConversationManager s_conversationManager = ConversationManager.Instance; - private ResponseConverter _responseConverter; - private IBotService _botService; - - public RelayBot(IBotService botService, ConversationManager conversationManager) - { - _botService = botService; - _responseConverter = new ResponseConverter(); - } - - // Invoked when a conversation update activity is received from the external Azure Bot Service channel - // Start a Power Virtual Agents bot conversation and store the mapping - protected override async Task OnConversationUpdateActivityAsync(ITurnContext turnContext, CancellationToken cancellationToken) - { - await s_conversationManager.GetOrCreateBotConversationAsync(turnContext.Activity.Conversation.Id, _botService); - } - - // Invoked when a message activity is received from the user - // Send the user message to Power Virtual Agent bot and get response - protected override async Task OnMessageActivityAsync(ITurnContext turnContext, CancellationToken cancellationToken) - { - var currentConversation = await s_conversationManager.GetOrCreateBotConversationAsync(turnContext.Activity.Conversation.Id, _botService); - - using (DirectLineClient client = new DirectLineClient(currentConversation.Token)) - { - // Send user message using directlineClient - await client.Conversations.PostActivityAsync(currentConversation.ConversationtId, new DirectLineActivity() - { - Type = DirectLineActivityTypes.Message, - From = new ChannelAccount { Id = turnContext.Activity.From.Id, Name = turnContext.Activity.From.Name }, - Text = turnContext.Activity.Text, - TextFormat = turnContext.Activity.TextFormat, - Locale = turnContext.Activity.Locale, - }); - - await RespondPowerVirtualAgentsBotReplyAsync(client, currentConversation, turnContext); - } - - // Update LastConversationUpdateTime for session management - currentConversation.LastConversationUpdateTime = DateTime.Now; - } - - private async Task RespondPowerVirtualAgentsBotReplyAsync(DirectLineClient client, RelayConversation currentConversation, ITurnContext turnContext) - { - var retryMax = WaitForBotResponseMaxMilSec / PollForBotResponseIntervalMilSec; - for (int retry = 0; retry < retryMax; retry++) - { - // Get bot response using directlineClient, - // response contains whole conversation history including user & bot's message - ActivitySet response = await client.Conversations.GetActivitiesAsync(currentConversation.ConversationtId, currentConversation.WaterMark); - - // Filter bot's reply message from response - List botResponses = response?.Activities?.Where(x => - x.Type == DirectLineActivityTypes.Message && - string.Equals(x.From.Name, _botService.GetBotName(), StringComparison.Ordinal)).ToList(); - - if (botResponses?.Count() > 0) - { - if (int.Parse(response?.Watermark ?? "0") <= int.Parse(currentConversation.WaterMark ?? "0")) - { - // means user sends new message, should break previous response poll - return; - } - - currentConversation.WaterMark = response.Watermark; - await turnContext.SendActivitiesAsync(_responseConverter.ConvertToBotSchemaActivities(botResponses).ToArray()); - } - - Thread.Sleep(PollForBotResponseIntervalMilSec); - } - } - } -} diff --git a/RelayBotSample/Controllers/BotController.cs b/RelayBotSample/Controllers/BotController.cs deleted file mode 100644 index 51b4525a..00000000 --- a/RelayBotSample/Controllers/BotController.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using Microsoft.AspNetCore.Mvc; -using Microsoft.Bot.Builder; -using Microsoft.Bot.Builder.Integration.AspNet.Core; -using System.Threading.Tasks; - -namespace Microsoft.PowerVirtualAgents.Samples.RelayBotSample.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] - 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/RelayBotSample/DeploymentTemplates/new-rg-parameters.json b/RelayBotSample/DeploymentTemplates/new-rg-parameters.json deleted file mode 100644 index ead33909..00000000 --- a/RelayBotSample/DeploymentTemplates/new-rg-parameters.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "groupLocation": { - "value": "" - }, - "groupName": { - "value": "" - }, - "appId": { - "value": "" - }, - "appSecret": { - "value": "" - }, - "botId": { - "value": "" - }, - "botSku": { - "value": "" - }, - "newAppServicePlanName": { - "value": "" - }, - "newAppServicePlanSku": { - "value": { - "name": "S1", - "tier": "Standard", - "size": "S1", - "family": "S", - "capacity": 1 - } - }, - "newAppServicePlanLocation": { - "value": "" - }, - "newWebAppName": { - "value": "" - } - } -} \ No newline at end of file diff --git a/RelayBotSample/DeploymentTemplates/preexisting-rg-parameters.json b/RelayBotSample/DeploymentTemplates/preexisting-rg-parameters.json deleted file mode 100644 index b6f5114f..00000000 --- a/RelayBotSample/DeploymentTemplates/preexisting-rg-parameters.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "appId": { - "value": "" - }, - "appSecret": { - "value": "" - }, - "botId": { - "value": "" - }, - "botSku": { - "value": "" - }, - "newAppServicePlanName": { - "value": "" - }, - "newAppServicePlanSku": { - "value": { - "name": "S1", - "tier": "Standard", - "size": "S1", - "family": "S", - "capacity": 1 - } - }, - "appServicePlanLocation": { - "value": "" - }, - "existingAppServicePlan": { - "value": "" - }, - "newWebAppName": { - "value": "" - } - } -} \ No newline at end of file diff --git a/RelayBotSample/DeploymentTemplates/template-with-new-rg.json b/RelayBotSample/DeploymentTemplates/template-with-new-rg.json deleted file mode 100644 index 06b82841..00000000 --- a/RelayBotSample/DeploymentTemplates/template-with-new-rg.json +++ /dev/null @@ -1,183 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "groupLocation": { - "type": "string", - "metadata": { - "description": "Specifies the location of the Resource Group." - } - }, - "groupName": { - "type": "string", - "metadata": { - "description": "Specifies the name of the Resource Group." - } - }, - "appId": { - "type": "string", - "metadata": { - "description": "Active Directory App 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." - } - }, - "botId": { - "type": "string", - "metadata": { - "description": "The globally unique and immutable bot ID. Also used to configure the displayName of the bot, which is mutable." - } - }, - "botSku": { - "type": "string", - "metadata": { - "description": "The pricing tier of the Bot Service Registration. Acceptable values are F0 and S1." - } - }, - "newAppServicePlanName": { - "type": "string", - "metadata": { - "description": "The name 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." - } - }, - "newAppServicePlanLocation": { - "type": "string", - "metadata": { - "description": "The location of the App Service Plan. Defaults to \"westus\"." - } - }, - "newWebAppName": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "The globally unique name of the Web App. Defaults to the value passed in for \"botId\"." - } - } - }, - "variables": { - "appServicePlanName": "[parameters('newAppServicePlanName')]", - "resourcesLocation": "[parameters('newAppServicePlanLocation')]", - "webAppName": "[if(empty(parameters('newWebAppName')), parameters('botId'), parameters('newWebAppName'))]", - "siteHost": "[concat(variables('webAppName'), '.azurewebsites.net')]", - "botEndpoint": "[concat('https://', variables('siteHost'), '/api/messages')]" - }, - "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/2015-01-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('newAppServicePlanSku')]", - "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": [ - "[resourceId('Microsoft.Web/serverfarms/', variables('appServicePlanName'))]" - ], - "name": "[variables('webAppName')]", - "properties": { - "name": "[variables('webAppName')]", - "serverFarmId": "[variables('appServicePlanName')]", - "siteConfig": { - "appSettings": [ - { - "name": "WEBSITE_NODE_DEFAULT_VERSION", - "value": "10.14.1" - }, - { - "name": "MicrosoftAppId", - "value": "[parameters('appId')]" - }, - { - "name": "MicrosoftAppPassword", - "value": "[parameters('appSecret')]" - } - ], - "cors": { - "allowedOrigins": [ - "https://botservice.hosting.portal.azure.net", - "https://hosting.onecloud.azure-test.net/" - ] - } - } - } - }, - { - "apiVersion": "2017-12-01", - "type": "Microsoft.BotService/botServices", - "name": "[parameters('botId')]", - "location": "global", - "kind": "bot", - "sku": { - "name": "[parameters('botSku')]" - }, - "properties": { - "name": "[parameters('botId')]", - "displayName": "[parameters('botId')]", - "endpoint": "[variables('botEndpoint')]", - "msaAppId": "[parameters('appId')]", - "developerAppInsightsApplicationId": null, - "developerAppInsightKey": null, - "publishingCredentials": null, - "storageResourceId": null - }, - "dependsOn": [ - "[resourceId('Microsoft.Web/sites/', variables('webAppName'))]" - ] - } - ], - "outputs": {} - } - } - } - ] -} \ No newline at end of file diff --git a/RelayBotSample/DeploymentTemplates/template-with-preexisting-rg.json b/RelayBotSample/DeploymentTemplates/template-with-preexisting-rg.json deleted file mode 100644 index 43943b65..00000000 --- a/RelayBotSample/DeploymentTemplates/template-with-preexisting-rg.json +++ /dev/null @@ -1,154 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "appId": { - "type": "string", - "metadata": { - "description": "Active Directory App 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. Defaults to \"\"." - } - }, - "botId": { - "type": "string", - "metadata": { - "description": "The globally unique and immutable bot ID. Also used to configure the displayName of the bot, which is mutable." - } - }, - "botSku": { - "defaultValue": "F0", - "type": "string", - "metadata": { - "description": "The pricing tier of the Bot Service Registration. Acceptable values are F0 and S1." - } - }, - "newAppServicePlanName": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "The name of the new 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." - } - }, - "appServicePlanLocation": { - "type": "string", - "metadata": { - "description": "The location of the App Service Plan." - } - }, - "existingAppServicePlan": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Name of the existing App Service Plan used to create the Web App for the bot." - } - }, - "newWebAppName": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "The globally unique name of the Web App. Defaults to the value passed in for \"botId\"." - } - } - }, - "variables": { - "defaultAppServicePlanName": "[if(empty(parameters('existingAppServicePlan')), 'createNewAppServicePlan', parameters('existingAppServicePlan'))]", - "useExistingAppServicePlan": "[not(equals(variables('defaultAppServicePlanName'), 'createNewAppServicePlan'))]", - "servicePlanName": "[if(variables('useExistingAppServicePlan'), parameters('existingAppServicePlan'), parameters('newAppServicePlanName'))]", - "resourcesLocation": "[parameters('appServicePlanLocation')]", - "webAppName": "[if(empty(parameters('newWebAppName')), parameters('botId'), parameters('newWebAppName'))]", - "siteHost": "[concat(variables('webAppName'), '.azurewebsites.net')]", - "botEndpoint": "[concat('https://', variables('siteHost'), '/api/messages')]" - }, - "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('useExistingAppServicePlan'))]", - "name": "[variables('servicePlanName')]", - "apiVersion": "2018-02-01", - "location": "[variables('resourcesLocation')]", - "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('resourcesLocation')]", - "kind": "app", - "dependsOn": [ - "[resourceId('Microsoft.Web/serverfarms/', variables('servicePlanName'))]" - ], - "name": "[variables('webAppName')]", - "properties": { - "name": "[variables('webAppName')]", - "serverFarmId": "[variables('servicePlanName')]", - "siteConfig": { - "appSettings": [ - { - "name": "WEBSITE_NODE_DEFAULT_VERSION", - "value": "10.14.1" - }, - { - "name": "MicrosoftAppId", - "value": "[parameters('appId')]" - }, - { - "name": "MicrosoftAppPassword", - "value": "[parameters('appSecret')]" - } - ], - "cors": { - "allowedOrigins": [ - "https://botservice.hosting.portal.azure.net", - "https://hosting.onecloud.azure-test.net/" - ] - } - } - } - }, - { - "apiVersion": "2017-12-01", - "type": "Microsoft.BotService/botServices", - "name": "[parameters('botId')]", - "location": "global", - "kind": "bot", - "sku": { - "name": "[parameters('botSku')]" - }, - "properties": { - "name": "[parameters('botId')]", - "displayName": "[parameters('botId')]", - "endpoint": "[variables('botEndpoint')]", - "msaAppId": "[parameters('appId')]", - "developerAppInsightsApplicationId": null, - "developerAppInsightKey": null, - "publishingCredentials": null, - "storageResourceId": null - }, - "dependsOn": [ - "[resourceId('Microsoft.Web/sites/', variables('webAppName'))]" - ] - } - ] -} \ No newline at end of file diff --git a/RelayBotSample/Program.cs b/RelayBotSample/Program.cs deleted file mode 100644 index 5ed15a40..00000000 --- a/RelayBotSample/Program.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using Microsoft.AspNetCore; -using Microsoft.AspNetCore.Hosting; - -namespace Microsoft.PowerVirtualAgents.Samples.RelayBotSample -{ - public class Program - { - public static void Main(string[] args) - { - CreateWebHostBuilder(args).Build().Run(); - } - - public static IWebHostBuilder CreateWebHostBuilder(string[] args) => - WebHost.CreateDefaultBuilder(args) - .UseStartup(); - } -} diff --git a/RelayBotSample/README.md b/RelayBotSample/README.md index 925a3335..fb60ba30 100644 --- a/RelayBotSample/README.md +++ b/RelayBotSample/README.md @@ -1,78 +1,8 @@ # Relay Bot +Relay bot is a legacy construct to integrate with a power virtual agent bot. +To integrate with your power virtual agent bot we now support power virtual agent bot as a skill, +please go through this [documentation](https://docs.microsoft.com/en-us/power-virtual-agents/advanced-use-pva-as-a-skill). -Sample of connecting Bot Framework v4 bot to a Power Virtual Agent bot. - -This bot has been created based on [Bot Framework](https://dev.botframework.com), it shows how to create an Azure Bot Service bot that connects to Power Virtual Agents bot - -## Prerequisites - -- [.NET Core SDK](https://dotnet.microsoft.com/download) version 2.1 - - ```bash - # determine dotnet version - dotnet --version - ``` - -## To try this sample - -- Clone the repository - - ```bash - git clone https://github.com/microsoft/PowerVirtualAgentsSample.git - ``` - -- In a terminal, navigate to `BYOBSample/` -- Update file appsettings.json with your Power Virtual Agent bot id, tenant id, bot name and other settings. - - To retrieve your bot's bot ID and tenant ID, click on left side pane's ***Manage***, click ***Channels*** and click on the Azure Bot Service channel that you need to connect to. - Copy and save the bot ID and tenant ID value by clicking Copy. - - Bot name can be found in you Power Virtual Agents bot Home page. - -- 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 `BYOBSample/` folder - - Select `SampleBot.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) -- [Restify](https://www.npmjs.com/package/restify) -- [dotenv](https://www.npmjs.com/package/dotenv) +If you are trying to enable speech with your power virtual agent bot, you have the following options today: +* Create a [bot](https://docs.microsoft.com/en-us/composer/quickstart-create-bot-with-azure) and enable [Direct Line speech](https://docs.microsoft.com/en-us/azure/bot-service/bot-service-channel-connect-directlinespeech?view=azure-bot-service-4.0) as a channel for that bot and connect to it to power virtual agent bot as a skill. +* Bring your own [custom canvas](https://github.com/microsoft/BotFramework-WebChat/tree/main/samples/03.speech/b.cognitive-speech-services-js) that enables speech services on the client side and [connect](https://docs.microsoft.com/en-us/power-virtual-agents/customize-default-canvas) it to the your power virtual agent bot. diff --git a/RelayBotSample/SampleBot.csproj b/RelayBotSample/SampleBot.csproj deleted file mode 100644 index cefada66..00000000 --- a/RelayBotSample/SampleBot.csproj +++ /dev/null @@ -1,20 +0,0 @@ - - - - netcoreapp2.1 - latest - - - - - - - - - - - Always - - - - diff --git a/RelayBotSample/Startup.cs b/RelayBotSample/Startup.cs deleted file mode 100644 index c23b24c0..00000000 --- a/RelayBotSample/Startup.cs +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Bot.Builder; -using Microsoft.Bot.Builder.Integration.AspNet.Core; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.PowerVirtualAgents.Samples.RelayBotSample.Bots; - -namespace Microsoft.PowerVirtualAgents.Samples.RelayBotSample -{ - 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.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); - - // Create the Bot Framework Adapter with error handling enabled. - services.AddSingleton(); - - // Create the bot as a transient. In this case the ASP Controller is expecting an IBot. - services.AddSingleton(); - - // Create the singleton instance of BotService from appsettings - var botService = new BotService(); - Configuration.Bind("BotService", (object)botService); - services.AddSingleton(botService); - - // Create the singleton instance of ConversationPool from appsettings - var conversationManager = new ConversationManager(); - Configuration.Bind("ConversationPool", conversationManager); - services.AddSingleton(conversationManager); - } - - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IHostingEnvironment env) - { - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } - else - { - app.UseHsts(); - } - - app.UseDefaultFiles(); - app.UseStaticFiles(); - - app.UseMvc(); - } - } -} diff --git a/RelayBotSample/appsettings.Development.json b/RelayBotSample/appsettings.Development.json deleted file mode 100644 index e203e940..00000000 --- a/RelayBotSample/appsettings.Development.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Debug", - "System": "Information", - "Microsoft": "Information" - } - } -} diff --git a/RelayBotSample/appsettings.json b/RelayBotSample/appsettings.json deleted file mode 100644 index 5d1da922..00000000 --- a/RelayBotSample/appsettings.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "MicrosoftAppId": "", - "MicrosoftAppPassword": "", - "BotService": { - "BotName": "", - "BotId": "", - "TenantId": "", - "TokenEndPoint": "https://powerva.microsoft.com/api/botmanagement/v1/directline/directlinetoken" - }, - "ConversationPool": { - "TokenRefreshCheckIntervalInMinute": 10, - "TokenRefreshIntervalInMinute": 30, - "ConversationEndAfterIdleTimeInMinute": 30, - "ConversationEndCheckIntervalInMinute": 10 - } -} \ No newline at end of file diff --git a/RelayBotSample/wwwroot/default.html b/RelayBotSample/wwwroot/default.html deleted file mode 100644 index 9585dff0..00000000 --- a/RelayBotSample/wwwroot/default.html +++ /dev/null @@ -1,418 +0,0 @@ - - - - - - - EchoBot - - - - - -
-
-
-
EchoBot
-
-
-
-
-
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
-
-
-
-
- -
- - -