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); }
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); }
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); }
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); }; }
// 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); }
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); }
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); }
// 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)); }); }
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)); }
/// <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 }); }
// 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)); }
// 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; }