public IConnectedService MapService(ConnectedService service)
        {
            var gitHubService = new GitHubConnectedService(service.Id, service.Name)
            {
                DefaultWorkRoot = service.DefaultWorkRoot,
                Owner           = service.GetPropertyValue("Owner")
            };

            var mode = service.GetPropertyValue("Mode");

            if (mode == "OAuth")
            {
                gitHubService.OAuth = new GitHubOAuthConfig(
                    service.GetPropertyValue("OAuth.ClientId"),
                    service.GetPropertyValue("OAuth.Secret"));

                gitHubService.AccessToken = service.TryGetPropertyValue <string>("AccessToken");
            }
            else
            {
                gitHubService.AccessToken = service.GetPropertyValue("PersonalAccessToken");
            }

            return(gitHubService);
        }
Пример #2
0
        /// <summary>
        /// Configures the services. This method gets called by the runtime. Use this method to add services to the container.
        /// </summary>
        /// <param name="services">The services.</param>
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddTransient <IProactiveMessageManager, ProactiveMessageManager>();
            services.AddTransient <IRecognizer, ReminderTextRecognizer>();

            string secretKey   = this.Configuration.GetSection("botFileSecret")?.Value;
            string botFilePath = this.Configuration.GetSection("botFilePath")?.Value;

            // Loads .bot configuration file and adds a singleton that your Bot can access through dependency injection.
            BotConfiguration botConfig = null;

            try
            {
                botConfig = BotConfiguration.Load(botFilePath ?? @".\BotConfiguration.bot", secretKey);
            }
            catch
            {
                string msg = "Error reading bot file. Please ensure you have valid botFilePath and botFileSecret set for your environment.\n" +
                             " - The botFileSecret is available under appsettings for your Azure Bot Service bot.\n" +
                             " - If you are running this bot locally, consider adding a appsettings.json file with botFilePath and botFileSecret.\n" +
                             " - See https://aka.ms/about-bot-file to learn more about .bot file its use and bot configuration.\n\n";
                throw new InvalidOperationException(msg);
            }

            services.AddSingleton(sp => botConfig);

            // Retrieve current endpoint.
            string           environment = this.isProduction ? "production" : "development";
            ConnectedService service     = botConfig.Services.Where(s => s.Type == "endpoint" && s.Name == environment).FirstOrDefault();

            if (!(service is EndpointService endpointService))
            {
                throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{environment}'.");
            }

            ICredentialProvider credentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword);

            services.AddSingleton <ICredentialProvider>(credentialProvider);

            services.AddBot <RemindMeBot>(options =>
            {
                options.CredentialProvider = credentialProvider;

                // Drop all activities not coming from Microsoft Teams.
                options.Middleware.Add(new DropNonTeamsActivitiesMiddleware());

                // This bot does not work in Channels.
                options.Middleware.Add(new DropChannelActivitiesMiddleware());

                // Catches any errors that occur during a conversation turn and logs them.
                options.OnTurnError = async(context, exception) =>
                {
                    await context.SendActivityAsync("Sorry, it looks like something went wrong.").ConfigureAwait(false);
                };
            });
        }
 private void UnProtectSecrets(ConnectedService connectedService)
 {
     foreach (ConnectedServiceProperty property in connectedService.Properties
              .Where(x => x.IsSecret.GetValueOrDefault()))
     {
         if (property.Value is string)
         {
             property.Value = _userDataProtector.UnProtect(property.Value);
         }
     }
 }
 public IConnectedService MapService(ConnectedService service)
 {
     return(new AzureDevOpsConnectedService(
                service.Id,
                service.Name,
                service.GetPropertyValue("Account"),
                service.GetPropertyValue("DefaultProject"),
                service.GetPropertyValue("PersonalAccessToken"))
     {
         DefaultWorkRoot = service.DefaultWorkRoot
     });
 }
Пример #5
0
        /// <summary>
        /// Registers a new LUIS intent recognizer instance.
        /// </summary>
        /// <param name="service">Service instance to register.</param>
        private void RegisterIntentRecognizer(ConnectedService service)
        {
            var luisService = (LuisService)service;

            var app = new LuisApplication(
                luisService.AppId,
                luisService.SubscriptionKey,
                luisService.GetEndpoint());

            var recognizer = new LuisRecognizer(app);

            IntentRecognizers.Add(luisService.Name, recognizer);
        }
Пример #6
0
        internal async Task <StorageFile> GetFile(int id)
        {
            File file = await ConnectedService.GetInvoiceAsync(id);

            if (file == null)
            {
                return(null);
            }

            var streamFile = await DownloadFileAsync(file);

            return(streamFile);
        }
        public async Task <ConnectedService> SaveAsync(
            ConnectedService connectedService,
            CancellationToken cancellationToken)
        {
            ProtectSecrets(connectedService);

            await _settingsStore.SaveAsync(
                connectedService,
                connectedService.Id.ToString("N"),
                SettingPath,
                cancellationToken);

            return(connectedService);
        }
Пример #8
0
        /// <summary>
        /// This method gets called by the runtime. Use this method to add services to the container.
        /// </summary>
        /// <param name="services">The <see cref="IServiceCollection"/> specifies the contract for a collection of service descriptors.</param>
        /// <seealso cref="IStatePropertyAccessor{T}"/>
        /// <seealso cref="https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/dependency-injection"/>
        /// <seealso cref="https://docs.microsoft.com/en-us/azure/bot-service/bot-service-manage-channels?view=azure-bot-service-4.0"/>
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddBot <CustomPromptBot>(options =>
            {
                string secretKey   = Configuration.GetSection("botFileSecret")?.Value;
                string botFilePath = Configuration.GetSection("botFilePath")?.Value;

                // Loads .bot configuration file and adds a singleton that your Bot can access through dependency injection.
                BotConfiguration botConfig = BotConfiguration.Load(botFilePath ?? @".\custom-prompt.bot", secretKey);
                services.AddSingleton(sp => botConfig
                                      ?? throw new InvalidOperationException($"The .bot config file could not be loaded. ({botConfig})"));

                // Retrieve current endpoint.
                string environment       = _isProduction ? "production" : "development";
                ConnectedService service = botConfig.Services.Where(s => s.Type == "endpoint" && s.Name == environment).FirstOrDefault();
                if (!(service is EndpointService endpointService))
                {
                    throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{environment}'.");
                }

                options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword);

                // Creates a logger for the application to use.
                ILogger logger = _loggerFactory.CreateLogger <CustomPromptBot>();

                // Catches any errors that occur during a conversation turn and logs them.
                options.OnTurnError = async(context, exception) =>
                {
                    logger.LogError($"Exception caught : {exception}");
                    await context.SendActivityAsync("Sorry, it looks like something went wrong.");
                };
            });

            // Create conversation and user state with in-memory storage provider.
            IStorage          storage           = new MemoryStorage();
            ConversationState conversationState = new ConversationState(storage);
            UserState         userState         = new UserState(storage);

            // Create and register state accessors.
            // Accessors created here are passed into the IBot-derived class on every turn.
            services.AddSingleton <CustomPromptBotAccessors>(sp =>
            {
                // Create the custom state accessor.
                return(new CustomPromptBotAccessors(conversationState, userState)
                {
                    ConversationFlowAccessor = conversationState.CreateProperty <ConversationFlow>(CustomPromptBotAccessors.ConversationFlowName),
                    UserProfileAccessor = userState.CreateProperty <UserProfile>(CustomPromptBotAccessors.UserProfileName),
                });
            });
        }
        /// <summary>
        /// Configures the services. This method gets called by the runtime. Use this method to add services to the container.
        /// </summary>
        /// <param name="services">The services.</param>
        public void ConfigureServices(IServiceCollection services)
        {
            string secretKey   = this.Configuration.GetSection("botFileSecret")?.Value;
            string botFilePath = this.Configuration.GetSection("botFilePath")?.Value;

            // Loads .bot configuration file and adds a singleton that your Bot can access through dependency injection.
            BotConfiguration botConfig = null;

            try
            {
                botConfig = BotConfiguration.Load(botFilePath ?? @".\BotConfiguration.bot", secretKey);
            }
            catch
            {
                string msg = "Error reading bot file. Please ensure you have valid botFilePath and botFileSecret set for your environment.\n" +
                             " - The botFileSecret is available under appsettings for your Azure Bot Service bot.\n" +
                             " - If you are running this bot locally, consider adding a appsettings.json file with botFilePath and botFileSecret.\n" +
                             " - See https://aka.ms/about-bot-file to learn more about .bot file its use and bot configuration.\n\n";
                throw new InvalidOperationException(msg);
            }

            services.AddSingleton(sp => botConfig);

            // Retrieve current endpoint.
            string           environment = this.isProduction ? "production" : "development";
            ConnectedService botService  = botConfig.Services.Where(s => s.Type == "endpoint" && s.Name == environment).FirstOrDefault();

            if (!(botService is EndpointService endpointService))
            {
                throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{environment}'.");
            }

            services.AddTransient <IActivityProcessor, TeamsActivityProcessor>();
            services.AddTransient <IMessageActivityHandler, MessageActivityHandler>();
            services.AddTransient <ITeamsInvokeActivityHandler, TeamsInvokeActivityHandler>();

            services.AddBot <FileBot>(options =>
            {
                options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword);

                options.Middleware.Add(new DropNonTeamsActivitiesMiddleware());

                options.Middleware.Add(new DropChannelActivitiesMiddleware()); // File bot only works for chats

                // --> Add Teams Middleware.
                options.Middleware.Add(
                    new TeamsMiddleware(
                        options.CredentialProvider));
            });
        }
Пример #10
0
        private void ProtectSecrets(ConnectedService connectedService)
        {
            IConnectedServiceProvider provider = _providers
                                                 .First(x => x.Type.Name == connectedService.Type);

            foreach (ConnectedServiceProperty property in connectedService.Properties
                     .Where(x => provider.Type.SecretProperties.Contains(x.Name)))
            {
                if (property.Value is string)
                {
                    property.Value    = _userDataProtector.Protect(property.Value);
                    property.IsSecret = true;
                }
            }
        }
Пример #11
0
        /// <summary>
        /// Registers a new knowledge base instance.
        /// </summary>
        /// <param name="service">Service instance to register.</param>
        private void RegisterKnowledgebase(ConnectedService service)
        {
            var qnaMakerService = (QnAMakerService)service;

            var endpoint = new QnAMakerEndpoint
            {
                EndpointKey     = qnaMakerService.EndpointKey,
                Host            = qnaMakerService.Hostname,
                KnowledgeBaseId = qnaMakerService.KbId,
            };

            var qna = new QnAMaker(endpoint);

            Knowledgebases.Add(qnaMakerService.Name, qna);
        }
        /// <summary>
        /// This method gets called by the runtime. Use this method to add services to the container.
        /// </summary>
        /// <param name="services">The <see cref="IServiceCollection"/> specifies the contract for a collection of service descriptors.</param>
        /// <seealso cref="IStatePropertyAccessor{T}"/>
        /// <seealso cref="https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/dependency-injection"/>
        /// <seealso cref="https://docs.microsoft.com/en-us/azure/bot-service/bot-service-manage-channels?view=azure-bot-service-4.0"/>
        public void ConfigureServices(IServiceCollection services)
        {
            IStorage          storage           = new MemoryStorage();
            ConversationState conversationState = new ConversationState(storage);
            UserState         userState         = new UserState(storage);

            services.AddSingleton <ConversationStateDataAccessors>(sp =>
            {
                // Create the custom state accessor.
                return(new ConversationStateDataAccessors(
                           conversationState,
                           userState,
                           conversationState.CreateProperty <ConversationData>(ConversationStateDataAccessors.ConversationDataName),
                           userState.CreateProperty <UserData>(ConversationStateDataAccessors.UserDataName)));
            });

            services.AddMvc()
            .AddControllersAsServices();

            services.AddBot <MaintenanceBookingServiceBot>(options =>
            {
                var secretKey = Configuration.GetSection("botFileSecret")?.Value;

                // Loads .bot configuration file and adds a singleton that your Bot can access through dependency injection.
                var botConfig = BotConfiguration.Load(@".\MaintenanceBookingService.bot", secretKey);
                services.AddSingleton(sp => botConfig);

                // Retrieve current endpoint.
                ConnectedService service = botConfig.Services
                                           .Where(s => s.Type == "endpoint" &&
                                                  s.Name == DevelopmentEnvName)
                                           .FirstOrDefault();
                if (!(service is EndpointService endpointService))
                {
                    throw new InvalidOperationException($"The .bot file does not contain a development endpoint.");
                }

                options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword);

                // Catches any errors that occur during a conversation turn and logs them.
                options.OnTurnError = async(context, exception) =>
                {
                    await context.SendActivityAsync("Sorry, it looks like something went wrong.");
                };
            });
        }
Пример #13
0
        public async Task <SaveConnectedServicePayload> SaveConnectedServiceAsync(
            [Service] IConnectedServiceManager serviceManager,
            SaveConnectedServiceInput input,
            CancellationToken cancellationToken)
        {
            var service = new ConnectedService
            {
                Id              = input.id ?? Guid.NewGuid(),
                Name            = input.Name,
                Type            = input.Type,
                DefaultWorkRoot = input.DefaultWorkRoot,
                Properties      = input.Properties.ToList()
            };

            service = await serviceManager.SaveAsync(service, cancellationToken);

            return(new SaveConnectedServicePayload(service));
        }
Пример #14
0
        public void ConfigureServices(IServiceCollection services)
        {
            // Load the connected services from .bot file.
            string           botFilePath   = Configuration.GetSection("botFilePath")?.Value;
            string           botFileSecret = Configuration.GetSection("botFileSecret")?.Value;
            BotConfiguration botConfig     = BotConfiguration.Load(botFilePath, botFileSecret);

            services.AddSingleton(sp => botConfig ?? throw new InvalidOperationException($"The .bot config file could not be loaded."));

            // Get default locale from appsettings.json
            string defaultLocale = Configuration.GetSection("defaultLocale").Get <string>();

            // Use Application Insights
            services.AddBotApplicationInsights(botConfig);

            // Initializes your bot service clients and adds a singleton that your Bot can access through dependency injection.
            BotServices connectedServices = new BotServices(botConfig);

            services.AddSingleton(sp => connectedServices);

            // Initialize Bot State
            ConnectedService       cosmosDbService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.CosmosDB) ?? throw new Exception("Please configure your CosmosDb service in your .bot file.");
            CosmosDbService        cosmosDb        = cosmosDbService as CosmosDbService;
            CosmosDbStorageOptions cosmosOptions   = new CosmosDbStorageOptions()
            {
                CosmosDBEndpoint = new Uri(cosmosDb.Endpoint),
                AuthKey          = cosmosDb.Key,
                CollectionId     = cosmosDb.Collection,
                DatabaseId       = cosmosDb.Database,
            };
            CosmosDbStorage   dataStore         = new CosmosDbStorage(cosmosOptions);
            UserState         userState         = new UserState(dataStore);
            ConversationState conversationState = new ConversationState(dataStore);

            services.AddSingleton(dataStore);
            services.AddSingleton(userState);
            services.AddSingleton(conversationState);
            services.AddSingleton(new BotStateSet(userState, conversationState));

            // Add the bot with options
            services.AddBot <Bot>(options =>
            {
                // Load the connected services from .bot file.
                string environment       = _isProduction ? "production" : "development";
                ConnectedService service = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.Endpoint && s.Name == environment);
                if (!(service is EndpointService endpointService))
                {
                    throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{environment}'.");
                }

                options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword);

                // Telemetry Middleware (logs activity messages in Application Insights)
                ServiceProvider sp = services.BuildServiceProvider();
                IBotTelemetryClient telemetryClient = sp.GetService <IBotTelemetryClient>();

                TelemetryLoggerMiddleware appInsightsLogger = new TelemetryLoggerMiddleware(telemetryClient, logPersonalInformation: true);
                options.Middleware.Add(appInsightsLogger);

                // Catches any errors that occur during a conversation turn and logs them to AppInsights.
                options.OnTurnError = async(context, exception) =>
                {
                    telemetryClient.TrackException(exception);
                    //await context.SendActivityAsync(MainStrings.ERROR);
                    await context.SendActivityAsync(exception.ToString());
                };

                // Transcript Middleware (saves conversation history in a standard format)
                ConnectedService storageService                 = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.BlobStorage) ?? throw new Exception("Please configure your Azure Storage service in your .bot file.");
                BlobStorageService blobStorage                  = storageService as BlobStorageService;
                AzureBlobTranscriptStore transcriptStore        = new AzureBlobTranscriptStore(blobStorage.ConnectionString, blobStorage.Container);
                TranscriptLoggerMiddleware transcriptMiddleware = new TranscriptLoggerMiddleware(transcriptStore);
                options.Middleware.Add(transcriptMiddleware);

                // Typing Middleware (automatically shows typing when the bot is responding/working)
                options.Middleware.Add(new ShowTypingMiddleware());

                // Locale Middleware (sets UI culture based on Activity.Locale)
                options.Middleware.Add(new SetLocaleMiddleware(defaultLocale ?? "en-us"));

                // Autosave State Middleware (saves bot state after each turn)
                options.Middleware.Add(new AutoSaveStateMiddleware(userState, conversationState));
            });
        }
Пример #15
0
 public SaveConnectedServicePayload(ConnectedService connectedService)
 {
     ConnectedService = connectedService;
 }
Пример #16
0
        /// <summary>
        /// Configures the services. This method gets called by the runtime. Use this method to add services to the container.
        /// </summary>
        /// <param name="services">The services.</param>
        public void ConfigureServices(IServiceCollection services)
        {
            string secretKey   = this.Configuration.GetSection("botFileSecret")?.Value;
            string botFilePath = this.Configuration.GetSection("botFilePath")?.Value;

            // Loads .bot configuration file and adds a singleton that your Bot can access through dependency injection.
            BotConfiguration botConfig = null;

            try
            {
                botConfig = BotConfiguration.Load(botFilePath ?? @".\BotConfiguration.bot", secretKey);
            }
            catch
            {
                string msg = "Error reading bot file. Please ensure you have valid botFilePath and botFileSecret set for your environment.\n" +
                             " - The botFileSecret is available under appsettings for your Azure Bot Service bot.\n" +
                             " - If you are running this bot locally, consider adding a appsettings.json file with botFilePath and botFileSecret.\n" +
                             " - See https://aka.ms/about-bot-file to learn more about .bot file its use and bot configuration.\n\n";
                throw new InvalidOperationException(msg);
            }

            services.AddSingleton(sp => botConfig);

            // Retrieve current endpoint.
            string           environment = this.isProduction ? "production" : "development";
            ConnectedService botService  = botConfig.Services.Where(s => s.Type == "endpoint" && s.Name == environment).FirstOrDefault();

            if (!(botService is EndpointService endpointService))
            {
                throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{environment}'.");
            }

            services.AddTransient <IActivityProcessor, TeamsActivityProcessor>();
            services.AddTransient <ITeamsConversationUpdateActivityHandler, TeamsConversationUpdateActivityHandler>();
            services.AddTransient <IMessageActivityHandler, MessageActivityHandler>();

            services.AddBot <AuditBot>(options =>
            {
                IStorage dataStore = new MemoryStorage();

                // --> Adding conversation state handler which understands a team as single conversation.
                options.State.Add(new TeamSpecificConversationState(dataStore));

                options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword);

                // Drop all activities not coming from Microsoft Teams.
                options.Middleware.Add(new DropNonTeamsActivitiesMiddleware());

                // --> Add Teams Middleware.
                options.Middleware.Add(
                    new TeamsMiddleware(
                        options.CredentialProvider));

                // Drop all non team messages.
                options.Middleware.Add(new DropChatActivitiesMiddleware());
            });

            services.AddSingleton(sp =>
            {
                BotFrameworkOptions options = sp.GetRequiredService <IOptions <BotFrameworkOptions> >().Value;
                if (options == null)
                {
                    throw new InvalidOperationException("BotFrameworkOptions must be configured prior to setting up the State Accessors");
                }

                TeamSpecificConversationState conversationState = options.State.OfType <TeamSpecificConversationState>().FirstOrDefault();
                if (conversationState == null)
                {
                    throw new InvalidOperationException("ConversationState must be defined and added before adding conversation-scoped state accessors.");
                }

                // Create the custom state accessor.
                // State accessors enable other components to read and write individual properties of state.
                var accessors = new AuditLogAccessor(conversationState)
                {
                    AuditLog = conversationState.CreateProperty <TeamOperationHistory>(AuditLogAccessor.AuditLogName),
                };

                return(accessors);
            });
        }
Пример #17
0
        /// <summary>
        /// This method gets called by the runtime. Use this method to add services to the container.
        /// </summary>
        /// <param name="services">Specifies the contract for a <see cref="IServiceCollection"/> of service descriptors.</param>
        public void ConfigureServices(IServiceCollection services)
        {
            string secretKey   = Configuration.GetSection("botFileSecret")?.Value;
            string botFilePath = Configuration.GetSection("botFilePath")?.Value;

            // Loads .bot configuration file and adds a singleton that your Bot can access through dependency injection.
            BotConfiguration botConfig = null;

            try
            {
                botConfig = BotConfiguration.Load(botFilePath ?? @".\BotConfiguration.bot", secretKey);
            }
            catch
            {
                string msg = @"Error reading bot file. Please ensure you have valid botFilePath and botFileSecret set for your environment.
    - You can find the botFilePath and botFileSecret in the Azure App Service application settings.
    - If you are running this bot locally, consider adding a appsettings.json file with botFilePath and botFileSecret.
    - See https://aka.ms/about-bot-file to learn more about .bot file its use and bot configuration.
    ";
                throw new InvalidOperationException(msg);
            }

            services.AddSingleton(sp => botConfig ?? throw new InvalidOperationException($"The .bot config file could not be loaded. ({botConfig})"));

            // Add BotServices singleton.
            // Create the connected services from .bot file.
            services.AddSingleton(sp => new BotServices(botConfig));

            // Retrieve current endpoint.
            string           environment = _isProduction ? "production" : "development";
            ConnectedService service     = botConfig.Services.Where(s => s.Type == "endpoint" && s.Name == environment).FirstOrDefault();

            if (!(service is EndpointService endpointService))
            {
                throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{environment}'.");
            }

            // Memory Storage is for local bot debugging only. When the bot
            // is restarted, everything stored in memory will be gone.
            IStorage dataStore = new MemoryStorage();

            // For production bots use the Azure Blob or
            // Azure CosmosDB storage providers. For the Azure
            // based storage providers, add the Microsoft.Bot.Builder.Azure
            // Nuget package to your solution. That package is found at:
            // https://www.nuget.org/packages/Microsoft.Bot.Builder.Azure/
            // Un-comment the following lines to use Azure Blob Storage
            // // Storage configuration name or ID from the .bot file.
            // const string StorageConfigurationId = "<STORAGE-NAME-OR-ID-FROM-BOT-FILE>";
            // var blobConfig = botConfig.FindServiceByNameOrId(StorageConfigurationId);
            // if (!(blobConfig is BlobStorageService blobStorageConfig))
            // {
            //    throw new InvalidOperationException($"The .bot file does not contain an blob storage with name '{StorageConfigurationId}'.");
            // }
            // // Default container name.
            // const string DefaultBotContainer = "botstate";
            // var storageContainer = string.IsNullOrWhiteSpace(blobStorageConfig.Container) ? DefaultBotContainer : blobStorageConfig.Container;
            // IStorage dataStore = new Microsoft.Bot.Builder.Azure.AzureBlobStorage(blobStorageConfig.ConnectionString, storageContainer);

            // Create and add conversation state.
            ConversationState conversationState = new ConversationState(dataStore);

            services.AddSingleton(conversationState);

            UserState userState = new UserState(dataStore);

            services.AddSingleton(userState);

            services.AddBot <BasicBot>(options =>
            {
                options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword);

                // Catches any errors that occur during a conversation turn and logs them to currently
                // configured ILogger.
                ILogger logger      = _loggerFactory.CreateLogger <BasicBot>();
                options.OnTurnError = async(context, exception) =>
                {
                    logger.LogError($"Exception caught : {exception}");
                    await context.SendActivityAsync($"Sorry, it looks like something went wrong: {exception}");
                };
            });
        }
 private async void onLogoutCommand(IUICommand command)
 {
     await ConnectedService.SignOut();
 }