// 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 static async Task DoWork(IConfiguration configuration, ILogger log = null) { var api = new CosmosInterface(configuration); var translator = new Translator(configuration); // The reminder message is static, so cache any translations to limit API calls. var translationCache = new Dictionary <string, string>(); // Get the current day. var day = DayFlagsHelpers.CurrentDay(); // Get all users. // TODO: this should likely be broken up so that it doesn't exceed the function time limit. var users = await api.GetUsers(); Helpers.LogInfo(log, $"Found {users.Count} users"); var queueHelper = new OutgoingMessageQueueHelpers(configuration.AzureWebJobsStorage()); foreach (var user in users) { // Check if the user should be reminded today. if (!user.ContactEnabled || !user.ReminderFrequency.HasFlag(day)) { continue; } // Check if the user should be reminded at this time. // Special case: use 6pm UTC (10am PST) if their reminder time isn't set. DateTime userReminderTime = string.IsNullOrEmpty(user.ReminderTime) ? DateTime.Parse("6:00pm") : DateTime.Parse(user.ReminderTime); // Using a 5 minute window in case the function triggers slightly early or late. if (Math.Abs((DateTime.UtcNow - userReminderTime).TotalMinutes) > 5) { continue; } var message = Phrases.Greeting.RemindToUpdate; // Check if the user's language is already cached. if (translationCache.TryGetValue(user.Language, out var translation)) { message = translation; } else { // Translate the message if necessary. if (translator.IsConfigured && user.Language != Translator.DefaultLanguage) { message = await translator.TranslateAsync(message, user.Language); } // Cache the message translationCache.Add(user.Language, message); } var data = new OutgoingMessageQueueData { PhoneNumber = user.PhoneNumber, Message = message }; await queueHelper.Enqueue(data); } }