public BotFrameworkHttpAdapter GetBotAdapter(IStorage storage, BotSettings settings, UserState userState, ConversationState conversationState, IServiceProvider s)
        {
            var adapter = IsSkill(settings)
                ? new BotFrameworkHttpAdapter(new ConfigurationCredentialProvider(this.Configuration), s.GetService <AuthenticationConfiguration>())
                : new BotFrameworkHttpAdapter(new ConfigurationCredentialProvider(this.Configuration));

            adapter
            .UseStorage(storage)
            .UseBotState(userState, conversationState)
            .Use(new RegisterClassMiddleware <IConfiguration>(Configuration))
            .Use(s.GetService <TelemetryInitializerMiddleware>());

            // Configure Middlewares
            ConfigureTranscriptLoggerMiddleware(adapter, settings);
            ConfigureInspectionMiddleWare(adapter, settings, storage);
            ConfigureShowTypingMiddleWare(adapter, settings);

            adapter.OnTurnError = async(turnContext, exception) =>
            {
                await turnContext.SendActivityAsync(exception.Message).ConfigureAwait(false);

                await conversationState.ClearStateAsync(turnContext).ConfigureAwait(false);

                await conversationState.SaveChangesAsync(turnContext).ConfigureAwait(false);
            };
            return(adapter);
        }
        public BotFrameworkHttpAdapter GetBotAdapter(IStorage storage, BotSettings settings, UserState userState, ConversationState conversationState, IServiceProvider s)
        {
            HostContext.Current.Set <IConfiguration>(Configuration);

            var adapter = new BotFrameworkHttpAdapter(new ConfigurationCredentialProvider(this.Configuration));

            adapter
            .UseStorage(storage)
            .UseState(userState, conversationState);

            // Configure Middlewares
            ConfigureTranscriptLoggerMiddleware(adapter, settings);
            ConfigureInspectionMiddleWare(adapter, settings, s);
            ConfigureShowTypingMiddleWare(adapter, settings);

            adapter.OnTurnError = async(turnContext, exception) =>
            {
                await turnContext.SendActivityAsync(exception.Message).ConfigureAwait(false);

                await conversationState.ClearStateAsync(turnContext).ConfigureAwait(false);

                await conversationState.SaveChangesAsync(turnContext).ConfigureAwait(false);
            };
            return(adapter);
        }
Example #3
0
        public void SetCurrent(string botDir)
        {
            IStorage storage           = new MemoryStorage();
            var      userState         = new UserState(storage);
            var      conversationState = new ConversationState(storage);
            var      inspectionState   = new InspectionState(storage);

            // manage all bot resources
            var resourceExplorer = new ResourceExplorer().AddFolder(botDir);

            var adapter = new BotFrameworkHttpAdapter(new ConfigurationCredentialProvider(Config));

            var credentials = new MicrosoftAppCredentials(Config["MicrosoftAppId"], Config["MicrosoftAppPassword"]);

            adapter
            .UseStorage(storage)
            .UseState(userState, conversationState)
            .UseAdaptiveDialogs()
            .UseResourceExplorer(resourceExplorer)
            .UseLanguageGeneration(resourceExplorer, "common.lg")
            .Use(new RegisterClassMiddleware <IConfiguration>(Config))
            .Use(new InspectionMiddleware(inspectionState, userState, conversationState, credentials));

            adapter.OnTurnError = async(turnContext, exception) =>
            {
                await turnContext.SendActivityAsync(exception.Message).ConfigureAwait(false);

                await conversationState.ClearStateAsync(turnContext).ConfigureAwait(false);

                await conversationState.SaveChangesAsync(turnContext).ConfigureAwait(false);
            };
            CurrentAdapter = adapter;

            CurrentBot = new ComposerBot("Main.dialog", conversationState, userState, resourceExplorer, DebugSupport.SourceMap);
        }
Example #4
0
        public async Task OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken = default)
        {
            if (turnContext == null)
            {
                throw new ArgumentNullException(nameof(turnContext));
            }

            if (turnContext.Activity.Type == ActivityTypes.Message)
            {
                if (_resetPhrases.Contains(turnContext.Activity.Text?.ToLowerInvariant()))
                {
                    await _conversationState.ClearStateAsync(turnContext);

                    await _userState.ClearStateAsync(turnContext);

                    await _conversationState.SaveChangesAsync(turnContext, false, cancellationToken);

                    await _userState.SaveChangesAsync(turnContext, false, cancellationToken);

                    await turnContext.SendActivityAsync(MessageFactory.Text(MiddlewareStrings.Reset, MiddlewareStrings.ResetSpeak), cancellationToken);

                    return;
                }
            }
            await next(cancellationToken).ConfigureAwait(false);
        }
        private async Task <DialogTurnResult?> InterruptAsync(DialogContext innerDc, CancellationToken cancellationToken)
        {
            if (innerDc.Context.Activity.Type != ActivityTypes.Message)
            {
                return(null);
            }

            var result = await recognizer.RecognizeAsync(innerDc.Context, cancellationToken);

            if (result.IsGetMenuInformationIntent)
            {
                var message = MessageFactory.Text(Resource.MenuInformation, Resource.MenuInformation, InputHints.ExpectingInput);
                await innerDc.Context.SendActivityAsync(message, cancellationToken);

                return(new DialogTurnResult(DialogTurnStatus.Waiting));
            }

            if (result.IsCancelOrderIntent)
            {
                var cancelMessage = MessageFactory.Text(Resource.CancelOrderConfirmation, Resource.CancelOrderConfirmation, InputHints.IgnoringInput);
                await innerDc.Context.SendActivityAsync(cancelMessage, cancellationToken);

                await conversationState.ClearStateAsync(innerDc.Context, cancellationToken);

                return(await innerDc.CancelAllDialogsAsync(cancellationToken));
            }

            return(null);
        }
Example #6
0
        public void SetBotAdapter(BotAdapter adapter, IStorage storage, BotSettings settings, UserState userState, ConversationState conversationState, IServiceProvider s, TelemetryInitializerMiddleware telemetryInitializerMiddleware)
        {
            adapter
            .UseStorage(storage)
            .UseBotState(userState)
            .Use(new RegisterClassMiddleware <ConversationState>(conversationState, typeof(ConversationState).FullName))
            .Use(new RegisterClassMiddleware <IConfiguration>(Configuration))
            .Use(new RegisterClassMiddleware <BotAdapter>(adapter))
            .Use(new RegisterClassMiddleware <TaskManager>(new TaskManager()))
            .Use(new HandleGroupMentionMiddleware())
            .Use(new ReferenceMiddleware())
            .Use(telemetryInitializerMiddleware);

            // Configure Middlewares
            ConfigureTranscriptLoggerMiddleware(adapter, settings);
            ConfigureInspectionMiddleWare(adapter, settings, storage);
            ConfigureShowTypingMiddleWare(adapter, settings);

            adapter.OnTurnError = async(turnContext, exception) =>
            {
                await turnContext.SendActivityAsync(exception.Message).ConfigureAwait(false);

                await conversationState.ClearStateAsync(turnContext).ConfigureAwait(false);

                await conversationState.SaveChangesAsync(turnContext).ConfigureAwait(false);
            };
        }
Example #7
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            //services.AddSingleton<IAdapterIntegration>(sp =>
            //{
            //    var options = sp.GetRequiredService<IOptions<BotFrameworkOptions>>().Value;
            //    var accessors = sp.GetRequiredService<TestBotAccessors>();

            //    options.Middleware.Add(new AutoSaveStateMiddleware(accessors.ConversationState));
            //    options.Middleware.Add(new ShowTypingMiddleware());

            //    var botFrameworkAdapter = new BotFrameworkAdapter(options.CredentialProvider, options.ChannelProvider, options.ConnectorClientRetryPolicy, options.HttpClient)
            //    {
            //        OnTurnError = options.OnTurnError,
            //    };

            //    foreach (var middleware in options.Middleware)
            //    {
            //        botFrameworkAdapter.Use(middleware);
            //    }

            //    //return botFrameworkAdapter;

            //    return new InteceptorAdapter(botFrameworkAdapter);
            //});

            IStorage dataStore         = new MemoryStorage();
            var      conversationState = new ConversationState(dataStore);

            var accessors = new TestBotAccessors
            {
                ConversationDialogState = conversationState.CreateProperty <DialogState>("DialogState"),
                ConversationState       = conversationState
            };

            services.AddBot <IBot>(
                (IServiceProvider sp) =>
            {
                return(new TestBot(accessors));
            },
                (BotFrameworkOptions options) =>
            {
                options.OnTurnError = async(turnContext, exception) =>
                {
                    await conversationState.ClearStateAsync(turnContext);
                    await conversationState.SaveChangesAsync(turnContext);
                };
                options.Middleware.Add(new AutoSaveStateMiddleware(conversationState));
            });

            //services.AddBot<TestBot>(options =>
            //{
            //    IStorage dataStore = new MemoryStorage();
            //    options.State.Add(new ConversationState(dataStore));
            //    options.Middleware.Add(new AutoSaveStateMiddleware(options.State.ToArray()));
            //    options.Middleware.Add(new ShowTypingMiddleware());
            //});
        }
        /// <summary>
        /// Runs dialog system in the context of an ITurnContext.
        /// </summary>
        /// <param name="context">turn context.</param>
        /// <param name="cancellationToken">cancelation token.</param>
        /// <returns>result of the running the logic against the activity.</returns>
        public async Task <DialogManagerResult> OnTurnAsync(ITurnContext context, CancellationToken cancellationToken = default(CancellationToken))
        {
            ConversationState conversationState = context.TurnState.Get <ConversationState>() ?? throw new ArgumentNullException($"{nameof(ConversationState)} is not found in the turn context. Have you called adapter.UseState() with a configured ConversationState object?");
            UserState         userState         = context.TurnState.Get <UserState>() ?? throw new ArgumentNullException($"{nameof(UserState)} is not found in the turn context. Have you called adapter.UseState() with a configured UserState object?");

            // create property accessors
            var lastAccessProperty = conversationState.CreateProperty <DateTime>(LASTACCESS);
            var lastAccess         = await lastAccessProperty.GetAsync(context, () => DateTime.UtcNow, cancellationToken : cancellationToken).ConfigureAwait(false);

            // Check for expired conversation
            var now = DateTime.UtcNow;

            if (this.ExpireAfter.HasValue && (DateTime.UtcNow - lastAccess) >= TimeSpan.FromMilliseconds((double)this.ExpireAfter))
            {
                // Clear conversation state
                await conversationState.ClearStateAsync(context, cancellationToken : cancellationToken).ConfigureAwait(false);
            }

            lastAccess = DateTime.UtcNow;
            await lastAccessProperty.SetAsync(context, lastAccess, cancellationToken : cancellationToken).ConfigureAwait(false);

            // get dialog stack
            var         dialogsProperty = conversationState.CreateProperty <DialogState>(DIALOGS);
            DialogState dialogState     = await dialogsProperty.GetAsync(context, () => new DialogState(), cancellationToken : cancellationToken).ConfigureAwait(false);

            // Create DialogContext
            var dc = new DialogContext(this.dialogSet, context, dialogState);

            DialogTurnResult turnResult = null;

            if (dc.ActiveDialog == null)
            {
                // start root dialog
                turnResult = await dc.BeginDialogAsync(this.rootDialogId, cancellationToken : cancellationToken).ConfigureAwait(false);
            }
            else
            {
                // Continue execution
                // - This will apply any queued up interruptions and execute the current/next step(s).
                turnResult = await dc.ContinueDialogAsync(cancellationToken : cancellationToken).ConfigureAwait(false);

                if (turnResult.Status == DialogTurnStatus.Empty)
                {
                    // restart root dialog
                    turnResult = await dc.BeginDialogAsync(this.rootDialogId, cancellationToken : cancellationToken).ConfigureAwait(false);
                }
            }

            // send trace of memory
            await dc.Context.SendActivityAsync((Activity)Activity.CreateTraceActivity("BotState", "https://www.botframework.com/schemas/botState", dc.GetState().GetMemorySnapshot(), "Bot State")).ConfigureAwait(false);

            return(new DialogManagerResult()
            {
                TurnResult = turnResult
            });
        }
        public async Task OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken = default)
        {
            var activity = turnContext.Activity;

            if (activity != null && activity.Type == ActivityTypes.EndOfConversation)
            {
                await _dialogState.DeleteAsync(turnContext).ConfigureAwait(false);

                await _conversationState.ClearStateAsync(turnContext).ConfigureAwait(false);

                await _conversationState.SaveChangesAsync(turnContext, force : true).ConfigureAwait(false);

                return;
            }

            await next(cancellationToken).ConfigureAwait(false);
        }
Example #10
0
        public async Task ClearAndSave()
        {
            var turnContext = TestUtilities.CreateEmptyContext();

            turnContext.Activity.Conversation = new ConversationAccount {
                Id = "1234"
            };

            var storage = new MemoryStorage(new Dictionary <string, JObject>());

            // Turn 0
            var botState1 = new ConversationState(storage);

            (await botState1
             .CreateProperty <TestPocoState>("test-name")
             .GetAsync(turnContext, () => new TestPocoState())).Value = "test-value";
            await botState1.SaveChangesAsync(turnContext);

            // Turn 1
            var botState2 = new ConversationState(storage);
            var value1    = (await botState2
                             .CreateProperty <TestPocoState>("test-name")
                             .GetAsync(turnContext, () => new TestPocoState {
                Value = "default-value"
            })).Value;

            Assert.AreEqual("test-value", value1);

            // Turn 2
            var botState3 = new ConversationState(storage);
            await botState3.ClearStateAsync(turnContext);

            await botState3.SaveChangesAsync(turnContext);

            // Turn 3
            var botState4 = new ConversationState(storage);
            var value2    = (await botState4
                             .CreateProperty <TestPocoState>("test-name")
                             .GetAsync(turnContext, () => new TestPocoState {
                Value = "default-value"
            })).Value;

            Assert.AreEqual("default-value", value2);
        }
        public async Task OnTurnAsync(ITurnContext turnContext, NextDelegate next,
                                      CancellationToken cancellationToken = new CancellationToken())
        {
            var lastChatTime = await LastAccssedTimeProperty
                               .GetAsync(turnContext, () => DateTime.UtcNow, cancellationToken).ConfigureAwait(false);

            if (ExpireAfterSeconds > 0)
            {
                var timeInterval = DateTime.UtcNow - lastChatTime;

                if (timeInterval >= TimeSpan.FromSeconds(ExpireAfterSeconds))
                {
                    // Clear state.
                    await _conversationState.ClearStateAsync(turnContext, cancellationToken).ConfigureAwait(false);

                    var conversationExpire = new
                    {
                        TimeDelay           = timeInterval,
                        ExceptedWaitingTime = ExpireAfterSeconds,
                        ReceivedType        = turnContext.Activity.Type
                    };


                    turnContext.Activity.Type = ConversationActivity.ActivityName;


                    var expireDetails = JsonConvert.SerializeObject(conversationExpire);
                    ObjectPath.SetPathValue(turnContext.TurnState, "turn.expire", JObject.Parse(expireDetails));
                }
            }


            // Set LastAccessedTime to the current time.
            await LastAccssedTimeProperty.SetAsync(turnContext, DateTime.UtcNow, cancellationToken)
            .ConfigureAwait(false);

            // Save any state changes that might have occurred during the turn.
            await _conversationState.SaveChangesAsync(turnContext, false, cancellationToken)
            .ConfigureAwait(false);

            await next(cancellationToken);
        }
Example #12
0
        public AcsSmsAdapter GetAcsBotAdapter(AcsSmsAdapterOptions options, IStorage storage, BotSettings settings, UserState userState, CrossChannelUserState crossChannelUserState, ConversationState conversationState, IServiceProvider s)
        {
            var adapter = new AcsSmsAdapter(options);

            adapter
            .UseStorage(storage)
            .UseBotState(userState, conversationState, crossChannelUserState)
            .Use(new RegisterClassMiddleware <IConfiguration>(Configuration))
            .Use(s.GetService <TelemetryInitializerMiddleware>());

            adapter.OnTurnError = async(turnContext, exception) =>
            {
                await turnContext.SendActivityAsync(exception.Message).ConfigureAwait(false);

                await conversationState.ClearStateAsync(turnContext).ConfigureAwait(false);

                await conversationState.SaveChangesAsync(turnContext).ConfigureAwait(false);
            };
            return(adapter);
        }
Example #13
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            IStorage dataStore         = new MemoryStorage();
            var      conversationState = new ConversationState(dataStore);
            var      userState         = new UserState(dataStore);
            var      userStateMap      = userState.CreateProperty <StateMap>("user");

            // Get Bot file
            string rootDialog = string.Empty;
            var    botFile    = Configuration.GetSection("bot").Get <BotFile>();
            var    botProject = BotProject.Load(botFile);

            rootDialog = botProject.entry;

            var accessors = new TestBotAccessors
            {
                ConversationDialogState = conversationState.CreateProperty <DialogState>("DialogState"),
                ConversationState       = conversationState,
                RootDialogFile          = botProject.path + rootDialog
            };

            services.AddBot <IBot>(
                (IServiceProvider sp) =>
            {
                return(new TestBot(accessors));
            },
                (BotFrameworkOptions options) =>
            {
                options.OnTurnError = async(turnContext, exception) =>
                {
                    await conversationState.ClearStateAsync(turnContext);
                    await conversationState.SaveChangesAsync(turnContext);
                };
                options.Middleware.Add(new AutoSaveStateMiddleware(conversationState));
            });
        }
Example #14
0
        public override void Configure(IFunctionsHostBuilder builder)
        {
            // Get assets directory.
            var assetsDirectory = GetAssetsDirectory();

            // Build configuration with assets.
            var config = BuildConfiguration(assetsDirectory);

            var settings = new BotSettings();

            config.Bind(settings);

            var services = builder.Services;

            services.AddSingleton <IConfiguration>(config);

            services.AddLogging();

            // Create the credential provider to be used with the Bot Framework Adapter.
            services.AddSingleton <ICredentialProvider, ConfigurationCredentialProvider>();
            services.AddSingleton <BotAdapter>(sp => (BotFrameworkHttpAdapter)sp.GetService <IBotFrameworkHttpAdapter>());

            // Register AuthConfiguration to enable custom claim validation.
            services.AddSingleton <AuthenticationConfiguration>();

            // Adaptive component registration
            ComponentRegistration.Add(new DialogsComponentRegistration());
            ComponentRegistration.Add(new DeclarativeComponentRegistration());
            ComponentRegistration.Add(new AdaptiveComponentRegistration());
            ComponentRegistration.Add(new LanguageGenerationComponentRegistration());
            ComponentRegistration.Add(new QnAMakerComponentRegistration());
            ComponentRegistration.Add(new LuisComponentRegistration());

            // This is for custom action component registration.
            //ComponentRegistration.Add(new CustomActionComponentRegistration());

            // Register the skills client and skills request handler.
            services.AddSingleton <SkillConversationIdFactoryBase, SkillConversationIdFactory>();
            services.AddHttpClient <BotFrameworkClient, SkillHttpClient>();
            services.AddSingleton <ChannelServiceHandler, SkillHandler>();

            // Register telemetry client, initializers and middleware
            services.AddApplicationInsightsTelemetry(settings?.ApplicationInsights?.InstrumentationKey ?? string.Empty);

            services.AddSingleton <ITelemetryInitializer, OperationCorrelationTelemetryInitializer>();
            services.AddSingleton <ITelemetryInitializer, TelemetryBotIdInitializer>();
            services.AddSingleton <IBotTelemetryClient, BotTelemetryClient>();
            services.AddSingleton <TelemetryLoggerMiddleware>(sp =>
            {
                var telemetryClient = sp.GetService <IBotTelemetryClient>();
                return(new TelemetryLoggerMiddleware(telemetryClient, logPersonalInformation: settings?.Telemetry?.LogPersonalInformation ?? false));
            });
            services.AddSingleton <TelemetryInitializerMiddleware>(sp =>
            {
                var httpContextAccessor       = sp.GetService <IHttpContextAccessor>();
                var telemetryLoggerMiddleware = sp.GetService <TelemetryLoggerMiddleware>();
                return(new TelemetryInitializerMiddleware(httpContextAccessor, telemetryLoggerMiddleware, settings?.Telemetry?.LogActivities ?? false));
            });

            // Storage
            IStorage storage;

            if (ConfigSectionValid(settings?.CosmosDb?.AuthKey))
            {
                storage = new CosmosDbPartitionedStorage(settings?.CosmosDb);
            }
            else
            {
                storage = new MemoryStorage();
            }

            services.AddSingleton(storage);
            var userState         = new UserState(storage);
            var conversationState = new ConversationState(storage);

            services.AddSingleton(userState);
            services.AddSingleton(conversationState);

            // Resource explorer to track declarative assets
            var resourceExplorer = new ResourceExplorer().AddFolder(assetsDirectory.FullName);

            services.AddSingleton(resourceExplorer);

            // Adapter
            services.AddSingleton <IBotFrameworkHttpAdapter, BotFrameworkHttpAdapter>(s =>
            {
                // Retrieve required dependencies
                IStorage storage    = s.GetService <IStorage>();
                UserState userState = s.GetService <UserState>();
                ConversationState conversationState = s.GetService <ConversationState>();
                TelemetryInitializerMiddleware telemetryInitializerMiddleware = s.GetService <TelemetryInitializerMiddleware>();

                var adapter = new BotFrameworkHttpAdapter(new ConfigurationCredentialProvider(config));

                adapter
                .UseStorage(storage)
                .UseBotState(userState, conversationState)
                .Use(new RegisterClassMiddleware <IConfiguration>(config))
                .Use(telemetryInitializerMiddleware);

                // Configure Middlewares
                ConfigureTranscriptLoggerMiddleware(adapter, settings);
                ConfigureInspectionMiddleWare(adapter, settings, s);
                ConfigureShowTypingMiddleWare(adapter, settings);

                adapter.OnTurnError = async(turnContext, exception) =>
                {
                    await turnContext.SendActivityAsync(exception.Message).ConfigureAwait(false);
                    await conversationState.ClearStateAsync(turnContext).ConfigureAwait(false);
                    await conversationState.SaveChangesAsync(turnContext).ConfigureAwait(false);
                };

                return(adapter);
            });

            var defaultLocale = config.GetValue <string>(DefaultLanguageSetting) ?? EnglishLocale;

            var removeRecipientMention = settings?.Feature?.RemoveRecipientMention ?? false;

            // Bot
            services.AddSingleton <IBot>(s =>
                                         new ComposerBot(
                                             s.GetService <ConversationState>(),
                                             s.GetService <UserState>(),
                                             s.GetService <ResourceExplorer>(),
                                             s.GetService <BotFrameworkClient>(),
                                             s.GetService <SkillConversationIdFactoryBase>(),
                                             s.GetService <IBotTelemetryClient>(),
                                             GetRootDialog(assetsDirectory.FullName),
                                             defaultLocale,
                                             removeRecipientMention));
        }
Example #15
0
        /// <summary>
        /// Runs dialog system in the context of an ITurnContext.
        /// </summary>
        /// <param name="context">turn context.</param>
        /// <param name="cancellationToken">Cancellation token.</param>
        /// <returns>result of the running the logic against the activity.</returns>
        public async Task <DialogManagerResult> OnTurnAsync(ITurnContext context, CancellationToken cancellationToken = default)
        {
            var botStateSet = new BotStateSet();

            // Preload TurnState with DM TurnState.
            foreach (var pair in InitialTurnState)
            {
                context.TurnState.Set(pair.Key, pair.Value);
            }

            // register DialogManager with TurnState.
            context.TurnState.Set(this);

            if (ConversationState == null)
            {
                ConversationState = context.TurnState.Get <ConversationState>() ?? throw new InvalidOperationException($"Unable to get an instance of {nameof(ConversationState)} from turnContext.");
            }
            else
            {
                context.TurnState.Set(ConversationState);
            }

            botStateSet.Add(ConversationState);

            if (UserState == null)
            {
                UserState = context.TurnState.Get <UserState>();
            }
            else
            {
                context.TurnState.Set(UserState);
            }

            if (UserState != null)
            {
                botStateSet.Add(UserState);
            }

            // create property accessors
            var lastAccessProperty = ConversationState.CreateProperty <DateTime>(LastAccess);
            var lastAccess         = await lastAccessProperty.GetAsync(context, () => DateTime.UtcNow, cancellationToken).ConfigureAwait(false);

            // Check for expired conversation
            if (ExpireAfter.HasValue && (DateTime.UtcNow - lastAccess) >= TimeSpan.FromMilliseconds((double)ExpireAfter))
            {
                // Clear conversation state
                await ConversationState.ClearStateAsync(context, cancellationToken).ConfigureAwait(false);
            }

            lastAccess = DateTime.UtcNow;
            await lastAccessProperty.SetAsync(context, lastAccess, cancellationToken).ConfigureAwait(false);

            // get dialog stack
            var dialogsProperty = ConversationState.CreateProperty <DialogState>(_dialogStateProperty);
            var dialogState     = await dialogsProperty.GetAsync(context, () => new DialogState(), cancellationToken).ConfigureAwait(false);

            // Create DialogContext
            var dc = new DialogContext(Dialogs, context, dialogState);

            // Call the common dialog "continue/begin" execution pattern shared with the classic RunAsync extension method
            var turnResult = await DialogExtensions.InternalRunAsync(context, _rootDialogId, dc, StateConfiguration, cancellationToken).ConfigureAwait(false);

            // save BotState changes
            await botStateSet.SaveAllChangesAsync(dc.Context, false, cancellationToken).ConfigureAwait(false);

            return(new DialogManagerResult {
                TurnResult = turnResult
            });
        }
Example #16
0
        // 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);

            services.AddSingleton <IConfiguration>(this.Configuration);

            // Create the credential provider to be used with the Bot Framework Adapter.
            services.AddSingleton <ICredentialProvider, ConfigurationCredentialProvider>();

            services.AddSingleton <InspectionMiddleware>();

            // Load settings
            var settings = new BotSettings();

            Configuration.Bind(settings);

            IStorage storage = null;

            // Configure storage for deployment
            if (!string.IsNullOrEmpty(settings.CosmosDb.AuthKey))
            {
                storage = new CosmosDbStorage(settings.CosmosDb);
            }
            else
            {
                Console.WriteLine("The settings of CosmosDbStorage is incomplete, please check following settings: settings.CosmosDb");
                storage = new MemoryStorage();
            }

            services.AddSingleton(storage);
            var userState         = new UserState(storage);
            var conversationState = new ConversationState(storage);
            var inspectionState   = new InspectionState(storage);

            // Configure telemetry
            services.AddApplicationInsightsTelemetry();
            var telemetryClient = new BotTelemetryClient(new TelemetryClient());

            services.AddSingleton <IBotTelemetryClient>(telemetryClient);
            services.AddBotApplicationInsights(telemetryClient);

            var botFile = Configuration.GetSection("bot").Get <string>();

            TypeFactory.Configuration = this.Configuration;

            // manage all bot resources
            var resourceExplorer = new ResourceExplorer().AddFolder(botFile);

            var credentials = new MicrosoftAppCredentials(this.Configuration["MicrosoftAppId"], this.Configuration["MicrosoftAppPassword"]);

            services.AddSingleton <IBotFrameworkHttpAdapter, BotFrameworkHttpAdapter>((s) =>
            {
                var adapter = new BotFrameworkHttpAdapter(new ConfigurationCredentialProvider(this.Configuration));
                adapter
                .UseStorage(storage)
                .UseState(userState, conversationState)
                .UseAdaptiveDialogs()
                .UseResourceExplorer(resourceExplorer)
                .UseLanguageGeneration(resourceExplorer, "common.lg")
                .Use(new RegisterClassMiddleware <IConfiguration>(Configuration))
                .Use(new InspectionMiddleware(inspectionState, userState, conversationState, credentials));

                if (!string.IsNullOrEmpty(settings.BlobStorage.ConnectionString) && !string.IsNullOrEmpty(settings.BlobStorage.Container))
                {
                    adapter.Use(new TranscriptLoggerMiddleware(new AzureBlobTranscriptStore(settings.BlobStorage.ConnectionString, settings.BlobStorage.Container)));
                }
                else
                {
                    Console.WriteLine("The settings of TranscriptLoggerMiddleware is incomplete, please check following settings: settings.BlobStorage.ConnectionString, settings.BlobStorage.Container");
                }

                adapter.OnTurnError = async(turnContext, exception) =>
                {
                    await turnContext.SendActivityAsync(exception.Message).ConfigureAwait(false);
                    telemetryClient.TrackException(new Exception("Exceptions: " + exception.Message));
                    await conversationState.ClearStateAsync(turnContext).ConfigureAwait(false);
                    await conversationState.SaveChangesAsync(turnContext).ConfigureAwait(false);
                };
                return(adapter);
            });

            services.AddSingleton <IBot, ComposerBot>((sp) => new ComposerBot("Main.dialog", conversationState, userState, resourceExplorer, DebugSupport.SourceMap, telemetryClient));
        }
Example #17
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc(options => options.EnableEndpointRouting = false).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

            services.AddSingleton <IConfiguration>(this.Configuration);

            // Create the credential provider to be used with the Bot Framework Adapter.
            services.AddSingleton <ICredentialProvider, ConfigurationCredentialProvider>();

            // Load settings
            var settings = new BotSettings();

            Configuration.Bind(settings);

            IStorage storage = null;

            // Configure storage for deployment
            if (!string.IsNullOrEmpty(settings.CosmosDb.AuthKey))
            {
                storage = new CosmosDbStorage(settings.CosmosDb);
            }
            else
            {
                Console.WriteLine("The settings of CosmosDbStorage is incomplete, please check following settings: settings.CosmosDb");
                storage = new MemoryStorage();
            }

            services.AddSingleton(storage);
            var userState         = new UserState(storage);
            var conversationState = new ConversationState(storage);

            var botFile = Configuration.GetSection("bot").Get <string>();

            // manage all bot resources
            var resourceExplorer = new ResourceExplorer().AddFolder(botFile);

            var credentials = new MicrosoftAppCredentials(this.Configuration["MicrosoftAppId"], this.Configuration["MicrosoftAppPassword"]);

            services.AddSingleton <IBotFrameworkHttpAdapter, BotFrameworkHttpAdapter>((s) =>
            {
                HostContext.Current.Set <IConfiguration>(Configuration);

                var adapter = new BotFrameworkHttpAdapter(new ConfigurationCredentialProvider(this.Configuration));
                adapter
                .UseStorage(storage)
                .UseState(userState, conversationState);

                if (!string.IsNullOrEmpty(settings.BlobStorage.ConnectionString) && !string.IsNullOrEmpty(settings.BlobStorage.Container))
                {
                    adapter.Use(new TranscriptLoggerMiddleware(new AzureBlobTranscriptStore(settings.BlobStorage.ConnectionString, settings.BlobStorage.Container)));
                }
                else
                {
                    Console.WriteLine("The settings of TranscriptLoggerMiddleware is incomplete, please check following settings: settings.BlobStorage.ConnectionString, settings.BlobStorage.Container");
                }

                adapter.OnTurnError = async(turnContext, exception) =>
                {
                    await turnContext.SendActivityAsync(exception.Message).ConfigureAwait(false);
                    await conversationState.ClearStateAsync(turnContext).ConfigureAwait(false);
                    await conversationState.SaveChangesAsync(turnContext).ConfigureAwait(false);
                };
                return(adapter);
            });

            services.AddSingleton <IBot, ComposerBot>((sp) => new ComposerBot("Main.dialog", conversationState, userState, resourceExplorer, DebugSupport.SourceMap));
        }
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers().AddNewtonsoftJson();

            services.AddSingleton <IConfiguration>(this.Configuration);

            // Create the credential provider to be used with the Bot Framework Adapter.
            services.AddSingleton <ICredentialProvider, ConfigurationCredentialProvider>();
            services.AddSingleton <BotAdapter>(sp => (BotFrameworkHttpAdapter)sp.GetService <IBotFrameworkHttpAdapter>());

            // Register AuthConfiguration to enable custom claim validation.
            services.AddSingleton <AuthenticationConfiguration>();

            // Register the skills client and skills request handler.
            services.AddSingleton <SkillConversationIdFactoryBase, SkillConversationIdFactory>();
            services.AddHttpClient <BotFrameworkClient, SkillHttpClient>();
            services.AddSingleton <ChannelServiceHandler, SkillHandler>();

            // Load settings
            var settings = new BotSettings();

            Configuration.Bind(settings);

            IStorage storage = null;

            // Configure storage for deployment
            if (!string.IsNullOrEmpty(settings.CosmosDb.AuthKey))
            {
                storage = new CosmosDbStorage(settings.CosmosDb);
            }
            else
            {
                Console.WriteLine("The settings of CosmosDbStorage is incomplete, please check following settings: settings.CosmosDb");
                storage = new MemoryStorage();
            }

            services.AddSingleton(storage);
            var userState         = new UserState(storage);
            var conversationState = new ConversationState(storage);

            var botFile = Configuration.GetSection("bot").Get <string>();

            // manage all bot resources
            var resourceExplorer = new ResourceExplorer().AddFolder(botFile);

            services.AddSingleton(userState);
            services.AddSingleton(conversationState);
            services.AddSingleton(resourceExplorer);

            services.AddSingleton <IBotFrameworkHttpAdapter, BotFrameworkHttpAdapter>((s) =>
            {
                HostContext.Current.Set <IConfiguration>(Configuration);

                var adapter = new BotFrameworkHttpAdapter(new ConfigurationCredentialProvider(this.Configuration));
                adapter
                .UseStorage(storage)
                .UseState(userState, conversationState);

                if (!string.IsNullOrEmpty(settings.BlobStorage.ConnectionString) && !string.IsNullOrEmpty(settings.BlobStorage.Container))
                {
                    adapter.Use(new TranscriptLoggerMiddleware(new AzureBlobTranscriptStore(settings.BlobStorage.ConnectionString, settings.BlobStorage.Container)));
                }
                else
                {
                    Console.WriteLine("The settings of TranscriptLoggerMiddleware is incomplete, please check following settings: settings.BlobStorage.ConnectionString, settings.BlobStorage.Container");
                }

                adapter.OnTurnError = async(turnContext, exception) =>
                {
                    await turnContext.SendActivityAsync(exception.Message).ConfigureAwait(false);
                    await conversationState.ClearStateAsync(turnContext).ConfigureAwait(false);
                    await conversationState.SaveChangesAsync(turnContext).ConfigureAwait(false);
                };
                return(adapter);
            });

            services.AddSingleton <IBot, ComposerBot>();
        }
        /// <summary>
        /// Runs dialog system in the context of an ITurnContext.
        /// </summary>
        /// <param name="context">turn context.</param>
        /// <param name="cancellationToken">cancelation token.</param>
        /// <returns>result of the running the logic against the activity.</returns>
        public async Task <DialogManagerResult> OnTurnAsync(ITurnContext context, CancellationToken cancellationToken = default(CancellationToken))
        {
            var botStateSet = new BotStateSet();

            // preload turnstate with DM turnstate
            foreach (var pair in this.TurnState)
            {
                context.TurnState.Set(pair.Key, pair.Value);
            }

            if (this.ConversationState == null)
            {
                this.ConversationState = context.TurnState.Get <ConversationState>() ?? throw new ArgumentNullException(nameof(this.ConversationState));
            }
            else
            {
                context.TurnState.Set(this.ConversationState);
            }

            botStateSet.Add(this.ConversationState);

            if (this.UserState == null)
            {
                this.UserState = context.TurnState.Get <UserState>();
            }

            if (this.UserState != null)
            {
                botStateSet.Add(this.UserState);
            }

            // create property accessors
            var lastAccessProperty = ConversationState.CreateProperty <DateTime>(LASTACCESS);
            var lastAccess         = await lastAccessProperty.GetAsync(context, () => DateTime.UtcNow, cancellationToken : cancellationToken).ConfigureAwait(false);

            // Check for expired conversation
            var now = DateTime.UtcNow;

            if (this.ExpireAfter.HasValue && (DateTime.UtcNow - lastAccess) >= TimeSpan.FromMilliseconds((double)this.ExpireAfter))
            {
                // Clear conversation state
                await ConversationState.ClearStateAsync(context, cancellationToken : cancellationToken).ConfigureAwait(false);
            }

            lastAccess = DateTime.UtcNow;
            await lastAccessProperty.SetAsync(context, lastAccess, cancellationToken : cancellationToken).ConfigureAwait(false);

            // get dialog stack
            var         dialogsProperty = ConversationState.CreateProperty <DialogState>(this.dialogStateProperty);
            DialogState dialogState     = await dialogsProperty.GetAsync(context, () => new DialogState(), cancellationToken : cancellationToken).ConfigureAwait(false);

            // Create DialogContext
            var dc = new DialogContext(this.Dialogs, context, dialogState);

            // get the dialogstatemanager configuration
            var dialogStateManager = new DialogStateManager(dc, this.StateConfiguration);
            await dialogStateManager.LoadAllScopesAsync(cancellationToken).ConfigureAwait(false);

            dc.Context.TurnState.Add(dialogStateManager);

            DialogTurnResult turnResult = null;

            // Loop as long as we are getting valid OnError handled we should continue executing the actions for the turn.
            //
            // NOTE: We loop around this block because each pass through we either complete the turn and break out of the loop
            // or we have had an exception AND there was an OnError action which captured the error.  We need to continue the
            // turn based on the actions the OnError handler introduced.
            while (true)
            {
                try
                {
                    if (dc.ActiveDialog == null)
                    {
                        // start root dialog
                        turnResult = await dc.BeginDialogAsync(this.rootDialogId, cancellationToken : cancellationToken).ConfigureAwait(false);
                    }
                    else
                    {
                        // Continue execution
                        // - This will apply any queued up interruptions and execute the current/next step(s).
                        turnResult = await dc.ContinueDialogAsync(cancellationToken : cancellationToken).ConfigureAwait(false);

                        if (turnResult.Status == DialogTurnStatus.Empty)
                        {
                            // restart root dialog
                            turnResult = await dc.BeginDialogAsync(this.rootDialogId, cancellationToken : cancellationToken).ConfigureAwait(false);
                        }
                    }

                    // turn successfully completed, break the loop
                    break;
                }
                catch (Exception err)
                {
                    // fire error event, bubbling from the leaf.
                    var handled = await dc.EmitEventAsync(DialogEvents.Error, err, bubble : true, fromLeaf : true, cancellationToken : cancellationToken).ConfigureAwait(false);

                    if (!handled)
                    {
                        // error was NOT handled, throw the exception and end the turn. (This will trigger the Adapter.OnError handler and end the entire dialog stack)
                        throw;
                    }
                }
            }

            // save all state scopes to their respective botState locations.
            await dialogStateManager.SaveAllChangesAsync(cancellationToken).ConfigureAwait(false);

            // save botstate changes
            await botStateSet.SaveAllChangesAsync(dc.Context, false, cancellationToken).ConfigureAwait(false);

            // send trace of memory
            var snapshot      = dc.GetState().GetMemorySnapshot();
            var traceActivity = (Activity)Activity.CreateTraceActivity("BotState", "https://www.botframework.com/schemas/botState", snapshot, "Bot State");
            await dc.Context.SendActivityAsync(traceActivity).ConfigureAwait(false);

            return(new DialogManagerResult()
            {
                TurnResult = turnResult
            });
        }
        /// <summary>
        /// Runs dialog system in the context of an ITurnContext.
        /// </summary>
        /// <param name="context">turn context.</param>
        /// <param name="cancellationToken">Cancellation token.</param>
        /// <returns>result of the running the logic against the activity.</returns>
        public async Task <DialogManagerResult> OnTurnAsync(ITurnContext context, CancellationToken cancellationToken = default)
        {
            var botStateSet = new BotStateSet();

            // Preload TurnState with DM TurnState.
            foreach (var pair in TurnState)
            {
                context.TurnState.Set(pair.Key, pair.Value);
            }

            if (ConversationState == null)
            {
                ConversationState = context.TurnState.Get <ConversationState>() ?? throw new ArgumentNullException(nameof(ConversationState));
            }
            else
            {
                context.TurnState.Set(ConversationState);
            }

            botStateSet.Add(ConversationState);

            if (UserState == null)
            {
                UserState = context.TurnState.Get <UserState>();
            }

            if (UserState != null)
            {
                botStateSet.Add(UserState);
            }

            // create property accessors
            var lastAccessProperty = ConversationState.CreateProperty <DateTime>(LastAccess);
            var lastAccess         = await lastAccessProperty.GetAsync(context, () => DateTime.UtcNow, cancellationToken).ConfigureAwait(false);

            // Check for expired conversation
            if (ExpireAfter.HasValue && (DateTime.UtcNow - lastAccess) >= TimeSpan.FromMilliseconds((double)ExpireAfter))
            {
                // Clear conversation state
                await ConversationState.ClearStateAsync(context, cancellationToken).ConfigureAwait(false);
            }

            lastAccess = DateTime.UtcNow;
            await lastAccessProperty.SetAsync(context, lastAccess, cancellationToken).ConfigureAwait(false);

            // get dialog stack
            var dialogsProperty = ConversationState.CreateProperty <DialogState>(_dialogStateProperty);
            var dialogState     = await dialogsProperty.GetAsync(context, () => new DialogState(), cancellationToken).ConfigureAwait(false);

            // Create DialogContext
            var dc = new DialogContext(Dialogs, context, dialogState);

            // get the DialogStateManager configuration
            var dialogStateManager = new DialogStateManager(dc, StateConfiguration);
            await dialogStateManager.LoadAllScopesAsync(cancellationToken).ConfigureAwait(false);

            dc.Context.TurnState.Add(dialogStateManager);

            DialogTurnResult turnResult = null;

            // Loop as long as we are getting valid OnError handled we should continue executing the actions for the turn.
            //
            // NOTE: We loop around this block because each pass through we either complete the turn and break out of the loop
            // or we have had an exception AND there was an OnError action which captured the error.  We need to continue the
            // turn based on the actions the OnError handler introduced.
            var endOfTurn = false;

            while (!endOfTurn)
            {
                try
                {
                    if (context.TurnState.Get <IIdentity>(BotAdapter.BotIdentityKey) is ClaimsIdentity claimIdentity && SkillValidation.IsSkillClaim(claimIdentity.Claims))
                    {
                        // The bot is running as a skill.
                        turnResult = await HandleSkillOnTurnAsync(dc, cancellationToken).ConfigureAwait(false);
                    }
                    else
                    {
                        // The bot is running as root bot.
                        turnResult = await HandleBotOnTurnAsync(dc, cancellationToken).ConfigureAwait(false);
                    }

                    // turn successfully completed, break the loop
                    endOfTurn = true;
                }