Пример #1
0
        // 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));
            });
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
            }
        }