public DialogBase(StateAccessors state, DialogSet dialogs, IApiInterface api, IConfiguration configuration) { this.state = state; this.dialogs = dialogs; this.api = api; this.configuration = configuration; }
public SearchCompanyDataDialog(StateAccessors accessors, ILoggerFactory loggerFactory, BotServices botServices, IServiceProvider serviceProvider) : base(nameof(SearchCompanyDataDialog)) { _accessors = accessors; _loggerFactory = loggerFactory; _botServices = botServices; _serviceProvider = serviceProvider; _companyService = (CompanyService)_serviceProvider.GetService(typeof(CompanyService)); var waterfallSteps = new WaterfallStep[] { InitializeStateStepAsync, AskForCompanyFullNameStepAsync, SearchCompanyStepAsync, ResultHandlerStepAsync, EndSearchDialogStepAsync }; var culture = CulturedBot.Culture?.Name; AddDialog(new WaterfallDialog(_searchCompanyDataWaterfall, waterfallSteps)); AddDialog(new TextPrompt(_companyNamePrompt)); AddDialog(new TextPrompt(_retryFetchingMinimumDataFromUserPrompt /*, defaultLocale: culture*/)); AddDialog(new TextPrompt(_confirmForwardingPrompt /*, defaultLocale: culture*/)); }
// This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940. // AddSingleton - Same for every object and every request. // AddScoped - Same within a request but different across different requests. // AddTransient - Always different. New instance for every controller and service. public void ConfigureServices(IServiceCollection services) { // Add the configuration. services.AddSingleton(this.configuration); // Add the API interface. // Cosmos recommends a singleton for the lifetime of the application. // Other types may need to be scoped to the request (like Entity Framework). var api = new CosmosInterface(this.configuration); services.AddSingleton(api); // Add the state accessors. var state = StateAccessors.Create(this.configuration); services.AddSingleton(state); // Add the translator. var translator = new Translator(this.configuration); services.AddSingleton(translator); // Configure the bot. services.AddBot <TheBot>(options => { // Load the configuration settings. options.CredentialProvider = new SimpleCredentialProvider( this.configuration.MicrosoftAppId(), this.configuration.MicrosoftAppPassword()); // Catches any errors that occur during a conversation turn and logs them. options.OnTurnError = async(context, exception) => { Debug.WriteLine(exception.Message); await context.TraceActivityAsync("Exception", exception); if (!configuration.IsProduction()) { await context.SendActivityAsync(exception.Message); await context.SendActivityAsync(exception.StackTrace); } await context.SendActivityAsync(Phrases.Exceptions.Error); }; // Auto-save the state after each turn. // This should be the first middleware called in order to catch state changes by any other middleware or the bot. options.Middleware.Add(new AutoSaveStateMiddleware(state.ConversationState)); // Trim the incoming message. options.Middleware.Add(new TrimIncomingMessageMiddleware()); // Make sure the user object is available. options.Middleware.Add(new CreateUserMiddleware(api)); // Translate the messages if necessary. options.Middleware.Add(new TranslationMiddleware(api, state, translator)); }); }
public TheBot(IConfiguration configuration, StateAccessors state, CosmosInterface api) { this.configuration = configuration; this.state = state ?? throw new ArgumentNullException(nameof(state)); this.dialogs = new DialogSet(state.DialogContextAccessor); this.api = api ?? throw new ArgumentNullException(nameof(api)); // Register prompts. Prompt.Register(this.dialogs, this.configuration, this.api); }
public CreateOpportunityDialog(StateAccessors accessors, ILoggerFactory loggerFactory, BotServices botServices, IServiceProvider serviceProvider) : base(nameof(CreateOpportunityDialog)) { _accessors = accessors; _loggerFactory = loggerFactory; _botServices = botServices; _serviceProvider = serviceProvider; _leadService = (LeadService)_serviceProvider.GetService(typeof(LeadService)); _opportunityService = (OpportunityService)_serviceProvider.GetService(typeof(OpportunityService)); _productService = (ProductService)_serviceProvider.GetService(typeof(ProductService)); var waterfallSteps = new WaterfallStep[] { //Start of dialog InitializeStateStepAsync, //Searching for lead AskForLeadFullNameStepAsync, SearchLeadStepAsync, LeadResultHandlerStepAsync, //Searching for product AskForProductNameStepAsync, SearchProductStepAsync, ProductResultHandlerStepAsync, //Checking the closing date AskForClosingDateStepAsync, SearchClosingDateStepAsync, ClosingDateResultHandlerStepAsync, //Checking for comment AskIfUserWantsToCommentStepAsync, AskToCommentStepAsync, FetchingCommentFromUserStepAsync, //End of Dialog EndSearchDialogStepAsync }; var culture = CulturedBot.Culture?.Name; AddDialog(new WaterfallDialog(_createOpportunityDataWaterfall, waterfallSteps)); //Searching for lead AddDialog(new TextPrompt(_leadFullNamePrompt)); AddDialog(new TextPrompt(_retryFetchingLeadFromUserPrompt /*, defaultLocale: culture*/)); //Searching for product AddDialog(new TextPrompt(_productNamePrompt)); AddDialog(new TextPrompt(_retryFetchingProductFromUserPrompt /*, defaultLocale: culture*/)); //Checking the closing date AddDialog(new TextPrompt(_closingDatePrompt)); AddDialog(new TextPrompt(_retryFetchingClosingDateFromUserPrompt /*, defaultLocale: culture*/)); //Checking for comment AddDialog(new TextPrompt(_commentPrompt /*, defaultLocale: culture*/)); AddDialog(new TextPrompt(_fetchingCommentFromUserPrompt)); }
protected DialogTestBase(TestFixture fixture) { this.fixture = fixture; this.state = StateAccessors.Create(); this.dialogs = new DialogSet(state.DialogContextAccessor); this.adapter = new TestAdapter() .Use(new TestSettingsMiddleware(fixture.Configuration)) .Use(new AutoSaveStateMiddleware(state.ConversationState)) .Use(new TrimIncomingMessageMiddleware()) .Use(new CreateUserMiddleware(fixture.Api)) .Use(new TranslationMiddleware(fixture.Api, this.state, fixture.Translator)); Prompt.Register(this.dialogs, fixture.Configuration, fixture.Api); }
/// <summary> /// Initializes a new instance of the class. /// </summary> /// <param name="conversationState">The managed conversation state.</param> /// <param name="loggerFactory">A <see cref="ILoggerFactory"/> that is hooked to the Azure App Service provider.</param> /// <seealso cref="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-2.1#windows-eventlog-provider"/> public ProxiCallBot(BotServices services, StateAccessors accessors, IOptions <ServicesConfig> options, IServiceProvider serviceProvider, ILoggerFactory loggerFactory) { _accessors = accessors ?? throw new System.ArgumentNullException(nameof(accessors)); _serviceProvider = serviceProvider; _loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory)); _services = services ?? throw new ArgumentNullException(nameof(services)); _servicesConfig = options.Value; _accountService = (AccountService)_serviceProvider.GetService(typeof(AccountService)); Dialogs = new DialogSet(_accessors.DialogStateAccessor); Dialogs.Add(ActivatorUtilities.CreateInstance <SearchLeadDataDialog>(_serviceProvider)); Dialogs.Add(ActivatorUtilities.CreateInstance <SearchCompanyDataDialog>(_serviceProvider)); Dialogs.Add(ActivatorUtilities.CreateInstance <CreateOpportunityDialog>(_serviceProvider)); }
/// <summary> /// Initializes a new instance of the <see cref="CarWashBot"/> class. /// </summary> /// <param name="accessors">The state accessors for managing bot state.</param> /// <param name="botConfig">The parsed .bot config file.</param> /// <param name="services">External services.</param> /// <param name="loggerFactory">Logger.</param> /// <param name="telemetryClient">Telemetry client.</param> public CarWashBot(StateAccessors accessors, BotConfiguration botConfig, BotServices services, ILoggerFactory loggerFactory, TelemetryClient telemetryClient) { _accessors = accessors ?? throw new ArgumentNullException(nameof(accessors)); if (botConfig == null) { throw new ArgumentNullException(nameof(botConfig)); } if (services == null) { throw new ArgumentNullException(nameof(services)); } _telemetryClient = telemetryClient; // Verify LUIS configuration. if (!services.LuisServices.ContainsKey(LuisConfiguration)) { throw new InvalidOperationException($"Invalid configuration. Please check your '.bot' file for a LUIS service named '{LuisConfiguration}'."); } _luis = services.LuisServices[LuisConfiguration]; // Verify QnAMaker configuration. if (!services.QnAServices.ContainsKey(QnAMakerConfiguration)) { throw new ArgumentException($"Invalid configuration. Please check your '.bot' file for a QnA service named '{QnAMakerConfiguration}'."); } _qna = services.QnAServices[QnAMakerConfiguration]; // Verify Storage configuration. if (!services.StorageServices.ContainsKey(StorageConfiguration)) { throw new ArgumentException($"Invalid configuration. Please check your '.bot' file for a Storage service named '{StorageConfiguration}'."); } _storage = services.StorageServices[StorageConfiguration]; Dialogs = new DialogSet(_accessors.DialogStateAccessor); Dialogs.Add(new NewReservationDialog(_accessors.NewReservationStateAccessor, telemetryClient)); Dialogs.Add(new ConfirmDropoffDialog(_accessors.ConfirmDropoffStateAccessor, telemetryClient)); Dialogs.Add(new CancelReservationDialog(_accessors.CancelReservationStateAccessor, telemetryClient)); Dialogs.Add(new FindReservationDialog(telemetryClient)); Dialogs.Add(new NextFreeSlotDialog(telemetryClient)); Dialogs.Add(new AuthDialog(accessors.UserProfileAccessor, _storage, telemetryClient)); Dialogs.Add(AuthDialog.LoginPromptDialog()); // Dialogs.Add(FormDialog.FromForm(NewReservationForm.BuildForm)); }
public GreetingDialog( ILogger <GreetingDialog> logger, StateAccessors accessors, IBotUserServices botUserServices) : base(GreetingDialogId) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _accessors = accessors ?? throw new ArgumentNullException(nameof(accessors)); _botUserServices = botUserServices ?? throw new ArgumentNullException(nameof(botUserServices)); InitialDialogId = Id; AddDialog(new WaterfallDialog(GreetingDialogId) .AddStep(Step1CheckRegistrationAsync) .AddStep(Step2GetCallNameAsync) .AddStep(Step3ThankYouAsync)); AddDialog(new TextPrompt(TextPromptId)); }
/// <summary> /// Initializes a new instance of the <see cref="ProactiveMessage{T}"/> class. /// </summary> /// <param name="accessors">The state accessors for managing bot state.</param> /// <param name="adapterIntegration">The <see cref="BotFrameworkAdapter"/> connects the bot to the service endpoint of the given channel.</param> /// <param name="env">Provides information about the web hosting environment an application is running in.</param> /// <param name="services">External services.</param> /// <param name="queueName">Service Bus queue name.</param> /// <param name="dialogs">List of Types of other <see cref="Dialog"/>s used when sending out the proactive message.</param> /// <param name="telemetryClient">Telemetry client.</param> public ProactiveMessage(StateAccessors accessors, IAdapterIntegration adapterIntegration, IHostingEnvironment env, BotServices services, string queueName, Dialog[] dialogs, TelemetryClient telemetryClient) { _accessors = accessors; _env = env; _botFrameworkAdapter = (BotFrameworkAdapter)adapterIntegration; _telemetryClient = telemetryClient; _dialogs = new DialogSet(_accessors.DialogStateAccessor); foreach (var dialog in dialogs) { _dialogs.Add(dialog); } // Verify Endpoint configuration. var endpointConfig = env.IsProduction() ? CarWashBot.EndpointConfiguration : CarWashBot.EndpointConfigurationDev; if (!services.EndpointServices.ContainsKey(endpointConfig)) { throw new ArgumentException($"Invalid configuration. Please check your '.bot' file for a Endpoint service named '{endpointConfig}'."); } _endpoint = services.EndpointServices[endpointConfig]; // Verify Storage configuration. if (!services.StorageServices.ContainsKey(CarWashBot.StorageConfiguration)) { throw new ArgumentException($"Invalid configuration. Please check your '.bot' file for a Storage service named '{CarWashBot.StorageConfiguration}'."); } var tableClient = services.StorageServices[CarWashBot.StorageConfiguration].CreateCloudTableClient(); _table = tableClient.GetTableReference(CarWashBot.UserStorageTableName); // Verify ServiceBus configuration. if (!services.ServiceBusServices.ContainsKey(CarWashBot.ServiceBusConfiguration)) { throw new ArgumentException($"Invalid configuration. Please check your '.bot' file for a Service Bus service named '{CarWashBot.ServiceBusConfiguration}'."); } _queueClient = new QueueClient(services.ServiceBusServices[CarWashBot.ServiceBusConfiguration], queueName, ReceiveMode.PeekLock, null); }
/// <summary> /// Initializes a new instance of the <see cref="VehicleArrivedMessage"/> class. /// </summary> /// <param name="configuration">CarWash app configuration.</param> /// <param name="accessors">The state accessors for managing bot state.</param> /// <param name="adapterIntegration">The <see cref="BotFrameworkAdapter"/> connects the bot to the service endpoint of the given channel.</param> /// <param name="env">Provides information about the web hosting environment an application is running in.</param> /// <param name="services">External services.</param> /// <param name="telemetryClient">Telemetry client.</param> public VehicleArrivedMessage(CarWashConfiguration configuration, StateAccessors accessors, IAdapterIntegration adapterIntegration, IHostingEnvironment env, BotServices services, TelemetryClient telemetryClient) : base(accessors, adapterIntegration, env, services, configuration.ServiceBusQueues.BotVehicleArrivedNotificationQueue, new Dialog[] { AuthDialog.LoginPromptDialog(), new FindReservationDialog(telemetryClient) }, telemetryClient) { }
public RequestDialog(StateAccessors state, DialogSet dialogs, IApiInterface api, IConfiguration configuration) : base(state, dialogs, api, configuration) { this.translator = new Translator(configuration); }
public UpdateDialog(StateAccessors state, DialogSet dialogs, IApiInterface api, IConfiguration configuration) : base(state, dialogs, api, configuration) { }
/// <summary> /// Initializes a new instance of the <see cref="WashStartedMessage"/> class. /// </summary> /// <param name="configuration">CarWash app configuration.</param> /// <param name="accessors">The state accessors for managing bot state.</param> /// <param name="adapterIntegration">The <see cref="BotFrameworkAdapter"/> connects the bot to the service endpoint of the given channel.</param> /// <param name="env">Provides information about the web hosting environment an application is running in.</param> /// <param name="services">External services.</param> public WashStartedMessage(CarWashConfiguration configuration, StateAccessors accessors, IAdapterIntegration adapterIntegration, IHostingEnvironment env, BotServices services) : base(accessors, adapterIntegration, env, services, configuration.ServiceBusQueues.BotWashStartedQueue, new Dialog[] { AuthDialog.LoginPromptDialog(), new FindReservationDialog() }) { }
/// <summary> /// Initializes a new instance of the class. /// </summary> public MeetpupDialogBot(StateAccessors stateAccessors) { _stateAccessors = stateAccessors; ExecuteMainDialog(_stateAccessors.DlgState); }
/// <summary> /// Initializes a new instance of the <see cref="TranslationMiddleware"/> class. /// </summary> public TranslationMiddleware(IApiInterface api, StateAccessors state, Translator translator) { this.api = api ?? throw new ArgumentNullException(nameof(api)); this.state = state ?? throw new ArgumentNullException(nameof(state)); this.translator = translator ?? throw new ArgumentNullException(nameof(translator)); }
/// <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) { var config = Configuration.Get <CarWashConfiguration>(); services.AddSingleton(config); var secretKey = Configuration.GetSection("botFileSecret")?.Value; var botFilePath = Configuration.GetSection("botFilePath")?.Value; // Loads .bot configuration file and adds a singleton that your Bot can access through dependency injection. BotConfiguration botConfig; try { botConfig = BotConfiguration.Load(botFilePath ?? @".\carwashubot.bot", secretKey); } catch (Exception) { var 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. var environment = _isProduction ? "production" : "development"; var service = botConfig.Services.FirstOrDefault(s => s.Type == "endpoint" && s.Name == environment); if (!(service is EndpointService endpointService)) { throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{environment}'."); } // Configure AppInsights services.AddApplicationInsightsTelemetry(Configuration); // Configure SnapshotCollector from application settings services.Configure <SnapshotCollectorConfiguration>(Configuration.GetSection(nameof(SnapshotCollectorConfiguration))); // Add SnapshotCollector telemetry processor. services.AddSingleton <ITelemetryProcessorFactory>(sp => new SnapshotCollectorTelemetryProcessorFactory(sp)); // Add proactive message services services.AddSingleton <DropoffReminderMessage, DropoffReminderMessage>(); services.AddSingleton <WashStartedMessage, WashStartedMessage>(); services.AddSingleton <WashCompletedMessage, WashCompletedMessage>(); services.AddSingleton <CarWashCommentLeftMessage, CarWashCommentLeftMessage>(); services.AddSingleton <VehicleArrivedMessage, VehicleArrivedMessage>(); // Memory Storage is for local bot debugging only. When the bot // is restarted, everything stored in memory will be gone. // IStorage dataStore = new MemoryStorage(); // Storage configuration name or ID from the .bot file. const string storageConfigurationId = "carwashstorage"; 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 AzureBlobStorage(blobStorageConfig.ConnectionString, storageContainer); // Create and add conversation state. var conversationState = new ConversationState(dataStore); services.AddSingleton(conversationState); // Create and add user state. var userState = new UserState(dataStore); services.AddSingleton(userState); services.AddBot <CarWashBot>(options => { options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword); // Enable the show typing middleware. options.Middleware.Add(new ShowTypingMiddleware()); // Enable the conversation transcript middleware. var transcriptStore = new AzureBlobTranscriptStore(blobStorageConfig.ConnectionString, "transcripts"); options.Middleware.Add(new TranscriptLoggerWorkaroundMiddleware(transcriptStore)); // Add Teams authentication workaround middleware. options.Middleware.Add(new TeamsAuthWorkaroundMiddleware()); // Catches any errors that occur during a conversation turn and logs them to currently // configured ILogger. ILogger logger = _loggerFactory.CreateLogger <CarWashBot>(); options.OnTurnError = async(context, exception) => { var telemetryClient = new TelemetryClient(); telemetryClient.TrackException(exception); logger.LogError($"Exception caught : {exception}"); await context.SendActivityAsync("Sorry, it looks like something went wrong."); }; }); // Create and register state accessors. // Accessors created here are passed into the IBot-derived class on every turn. services.AddSingleton(sp => { if (conversationState == null) { throw new InvalidOperationException("ConversationState must be defined and added before adding conversation-scoped state accessors."); } if (userState == null) { throw new InvalidOperationException("UserState must be defined and added before adding user-scoped state accessors."); } // Create the custom state accessor. // State accessors enable other components to read and write individual properties of state. var accessors = new StateAccessors(conversationState, userState); return(accessors); }); }
/// <summary> /// Initializes a new instance of the <see cref="CarWashCommentLeftMessage"/> class. /// </summary> /// <param name="configuration">CarWash app configuration.</param> /// <param name="accessors">The state accessors for managing bot state.</param> /// <param name="adapterIntegration">The <see cref="BotFrameworkAdapter"/> connects the bot to the service endpoint of the given channel.</param> /// <param name="env">Provides information about the web hosting environment an application is running in.</param> /// <param name="services">External services.</param> /// <param name="telemetryClient">Telemetry client.</param> public CarWashCommentLeftMessage(CarWashConfiguration configuration, StateAccessors accessors, IAdapterIntegration adapterIntegration, IHostingEnvironment env, BotServices services, TelemetryClient telemetryClient) : base(accessors, adapterIntegration, env, services, configuration.ServiceBusQueues.BotCarWashCommentLeftQueue, new Dialog[] { AuthDialog.LoginPromptDialog(), new FindReservationDialog(telemetryClient) }, telemetryClient) { _telemetryClient = telemetryClient; }