Ejemplo n.º 1
0
        /// <summary>
        /// we call for every turn while the topic is still active
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task <bool> ContinueTopic(AlarmBotContext context)
        {
            // for messages
            if (context.Activity.Type == ActivityTypes.Message)
            {
                switch (context.RecognizedIntents.TopIntent?.Name)
                {
                case "showAlarms":
                    // allow show alarm to interrupt, but it's one turn, so we show the data without changing the topic
                    await new ShowAlarmsTopic().StartTopic(context);
                    return(await this.PromptForMissingData(context));

                case "help":
                    // show contextual help
                    await AddAlarmResponses.ReplyWithHelp(context, this.Alarm);

                    return(await this.PromptForMissingData(context));

                case "cancel":
                    // prompt to cancel
                    await AddAlarmResponses.ReplyWithCancelPrompt(context, this.Alarm);

                    this.TopicState = TopicStates.CancelConfirmation;
                    return(true);

                default:
                    return(await ProcessTopicState(context));
                }
            }
            return(true);
        }
Ejemplo n.º 2
0
        public async Task OnTurn(ITurnContext turnContext)
        {
            // Get the current ActiveTopic from my persisted conversation state
            var context = new AlarmBotContext(turnContext);

            // Trace top intent
            // await turnContext.SendActivity(context.Activity.CreateTrace("conversationState", value: context.ConversationState));
            await turnContext.TraceActivity("context.ConversationState", value : context.ConversationState);

            var handled = false;

            // if we don't have an active topic yet
            if (context.ConversationState.ActiveTopic == null)
            {
                // use the default topic
                context.ConversationState.ActiveTopic = new DefaultTopic();
                handled = await context.ConversationState.ActiveTopic.StartTopic(context);
            }
            else
            {
                // we do have an active topic, so call it
                handled = await context.ConversationState.ActiveTopic.ContinueTopic(context);
            }

            // if activeTopic's result is false and the activeTopic is NOT already the default topic
            if (handled == false && !(context.ConversationState.ActiveTopic is DefaultTopic))
            {
                // Use DefaultTopic as the active topic
                context.ConversationState.ActiveTopic = new DefaultTopic();
                await context.ConversationState.ActiveTopic.ResumeTopic(context);
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Method which is called when this topic is resumed after an interruption
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task <bool> ResumeTopic(AlarmBotContext context)
        {
            // just prompt the user to ask what they want to do
            await DefaultResponses.ReplyWithResumeTopic(context);

            return(true);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Called when the default topic is started
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task <bool> StartTopic(AlarmBotContext context)
        {
            switch (context.Activity.Type)
            {
            case ActivityTypes.ConversationUpdate:
            {
                // greet when added to conversation
                var activity = context.Activity.AsConversationUpdateActivity();
                if (activity.MembersAdded.Any(m => m.Id == activity.Recipient.Id))
                {
                    await DefaultResponses.ReplyWithGreeting(context);

                    await DefaultResponses.ReplyWithHelp(context);

                    this.Greeted = true;
                }
            }
            break;

            case ActivityTypes.Message:
                // greet on first message if we haven't already
                if (!Greeted)
                {
                    await DefaultResponses.ReplyWithGreeting(context);

                    this.Greeted = true;
                }
                return(await this.ContinueTopic(context));
            }

            return(true);
        }
        /// <summary>
        /// Called when the topic is started
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public Task <bool> StartTopic(AlarmBotContext context)
        {
            this.AlarmTitle = context.RecognizedIntents.TopIntent.Entities.Where(entity => entity.GroupName == "AlarmTitle")
                              .Select(entity => entity.ValueAs <string>()).FirstOrDefault();

            return(FindAlarm(context));
        }
        /// <summary>
        /// Called when topic is activated (SINGLE TURN)
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task <bool> StartTopic(AlarmBotContext context)
        {
            await ShowAlarms(context);

            // end the topic immediately
            return(false);
        }
Ejemplo n.º 7
0
        public async Task OnReceiveActivity(IBotContext botContext)
        {
            var context = new AlarmBotContext(botContext);

            // --- Our receive handler simply inspects the persisted ITopic class and calls to it as appropriate ---

            bool handled = false;

            // if we don't have an active topic yet
            if (context.ConversationState.ActiveTopic == null)
            {
                // use the default topic
                context.ConversationState.ActiveTopic = new DefaultTopic();
                handled = await context.ConversationState.ActiveTopic.StartTopic(context);
            }
            else
            {
                // we do have an active topic, so call it
                handled = await context.ConversationState.ActiveTopic.ContinueTopic(context);
            }

            // if activeTopic's result is false and the activeTopic is NOT already the default topic
            if (handled == false && !(context.ConversationState.ActiveTopic is DefaultTopic))
            {
                // USe DefaultTopic as the active topic
                context.ConversationState.ActiveTopic = new DefaultTopic();
                handled = await context.ConversationState.ActiveTopic.ResumeTopic(context);
            }
        }
        public async Task <bool> FindAlarm(AlarmBotContext context)
        {
            if (context.UserState.Alarms == null)
            {
                context.UserState.Alarms = new List <Alarm>();
            }

            // Ensure there are context.UserState.Alarms to delete
            if (context.UserState.Alarms.Count == 0)
            {
                await DeleteAlarmResponses.ReplyWithNoAlarms(context);

                return(false);
            }

            // Validate title
            if (!String.IsNullOrWhiteSpace(this.AlarmTitle))
            {
                if (int.TryParse(this.AlarmTitle.Split(' ').FirstOrDefault(), out int index))
                {
                    if (index > 0 && index <= context.UserState.Alarms.Count)
                    {
                        index--;
                        // Delete selected alarm and end topic
                        var alarm = context.UserState.Alarms.Skip(index).First();
                        context.UserState.Alarms.Remove(alarm);
                        await DeleteAlarmResponses.ReplyWithDeletedAlarm(context, alarm);

                        return(false); // cancel topic
                    }
                }
                else
                {
                    var parts   = this.AlarmTitle.Split(' ');
                    var choices = context.UserState.Alarms.Where(alarm => parts.Any(part => alarm.Title.Contains(part))).ToList();

                    if (choices.Count == 0)
                    {
                        await DeleteAlarmResponses.ReplyWithNoAlarmsFound(context, this.AlarmTitle);

                        return(false);
                    }
                    else if (choices.Count == 1)
                    {
                        // Delete selected alarm and end topic
                        var alarm = choices.First();
                        context.UserState.Alarms.Remove(alarm);
                        await DeleteAlarmResponses.ReplyWithDeletedAlarm(context, alarm);

                        return(false); // cancel topic
                    }
                }
            }

            // Prompt for title
            await DeleteAlarmResponses.ReplyWithTitlePrompt(context);

            return(true);
        }
 /// <summary>
 /// Called for every turn while active
 /// </summary>
 /// <param name="context"></param>
 /// <returns></returns>
 public async Task <bool> ContinueTopic(AlarmBotContext context)
 {
     if (context.Activity.Type == ActivityTypes.Message)
     {
         this.AlarmTitle = context.Activity.Text.Trim();
         return(await this.FindAlarm(context));
     }
     return(true);
 }
Ejemplo n.º 10
0
        /// <summary>
        /// Called when the add alarm topic is started
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public Task <bool> StartTopic(AlarmBotContext context)
        {
            var times = context.RecognizedIntents.TopIntent?.Entities.Where(entity => entity.GroupName == "AlarmTime")
                        .Select(entity => DateTimeOffset.Parse(entity.Value as string));

            this.Alarm = new Alarm()
            {
                // initialize from intent entities
                Title = context.RecognizedIntents.TopIntent?.Entities.Where(entity => entity.GroupName == "AlarmTitle")
                        .Select(entity => entity.Value as string).FirstOrDefault(),

                // initialize from intent entities
                Time = times.Any() ? times.First() : (DateTimeOffset?)null
            };

            return(PromptForMissingData(context));
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Continue the topic, method which is routed to while this topic is active
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task <bool> ContinueTopic(AlarmBotContext context)
        {
            switch (context.Activity.Type)
            {
            case ActivityTypes.Message:
                switch (context.RecognizedIntents.TopIntent?.Name)
                {
                case "addAlarm":
                    // switch to addAlarm topic
                    context.ConversationState.ActiveTopic = new AddAlarmTopic();
                    return(await context.ConversationState.ActiveTopic.StartTopic(context));

                case "showAlarms":
                    // switch to show alarms topic
                    context.ConversationState.ActiveTopic = new ShowAlarmsTopic();
                    return(await context.ConversationState.ActiveTopic.StartTopic(context));

                case "deleteAlarm":
                    // switch to delete alarm topic
                    context.ConversationState.ActiveTopic = new DeleteAlarmTopic();
                    return(await context.ConversationState.ActiveTopic.StartTopic(context));

                case "help":
                    // show help
                    await DefaultResponses.ReplyWithHelp(context);

                    return(true);

                default:
                    // show our confusion
                    await DefaultResponses.ReplyWithConfused(context);

                    return(true);
                }

            default:
                break;
            }

            return(true);
        }
        public static IMessageActivity GetDeleteActivity(AlarmBotContext context, IEnumerable <Alarm> alarms, string title, string message)
        {
            StringBuilder sb = new StringBuilder();
            int           i  = 1;

            if (alarms.Any())
            {
                foreach (var alarm in alarms)
                {
                    sb.AppendLine($"{i++}. {alarm.Title} {alarm.Time.Value.ToString("f")}");
                }
            }
            else
            {
                sb.AppendLine("There are no alarms defined");
            }
            i = 1;
            return(ResponseHelpers.ReplyWithSuggestions(context,
                                                        title,
                                                        $"{message}\n\n{sb.ToString()}",
                                                        alarms.Select(alarm => $"{i++} {alarm.Title}").ToArray()));
        }
Ejemplo n.º 13
0
 /// <summary>
 /// Called when this topic is resumed after being interrupted
 /// </summary>
 /// <param name="context"></param>
 /// <returns></returns>
 public Task <bool> ResumeTopic(AlarmBotContext context)
 {
     // simply prompt again based on our state
     return(this.PromptForMissingData(context));
 }
Ejemplo n.º 14
0
        private async Task <bool> ProcessTopicState(AlarmBotContext context)
        {
            string utterance = (context.Activity.AsMessageActivity().Text ?? "").Trim();

            // we ar eusing TopicState to remember what we last asked
            switch (this.TopicState)
            {
            case TopicStates.TitlePrompt:
                this.Alarm.Title = utterance;
                return(await this.PromptForMissingData(context));

            case TopicStates.TimePrompt:
                // take first one in the future if a valid time has been parsed
                var times = context.GetDateTimes();
                if (times.Any(t => t > DateTimeOffset.Now))
                {
                    this.Alarm.Time = times.FirstOrDefault(t => t > DateTimeOffset.Now);
                }
                return(await this.PromptForMissingData(context));

            case TopicStates.CancelConfirmation:
                switch (context.RecognizedIntents.TopIntent?.Name)
                {
                case "confirmYes":
                    await AddAlarmResponses.ReplyWithTopicCanceled(context);

                    // End current topic
                    return(false);

                case "confirmNo":
                    // Re-prompt user for current field.
                    await AddAlarmResponses.ReplyWithTopicCanceled(context);

                    return(await this.PromptForMissingData(context));

                default:
                    // prompt again to confirm the cancelation
                    await AddAlarmResponses.ReplyWithCancelReprompt(context, this.Alarm);

                    return(true);
                }

            case TopicStates.AddConfirmation:
                switch (context.RecognizedIntents.TopIntent?.Name)
                {
                case "confirmYes":
                    if (context.UserState.Alarms == null)
                    {
                        context.UserState.Alarms = new List <Alarm>();
                    }
                    context.UserState.Alarms.Add(this.Alarm);
                    await AddAlarmResponses.ReplyWithAddedAlarm(context, this.Alarm);

                    // end topic
                    return(false);

                case "confirmNo":
                    await AddAlarmResponses.ReplyWithTopicCanceled(context);

                    // End current topic
                    return(false);

                default:
                    return(await this.PromptForMissingData(context));
                }

            default:
                return(await this.PromptForMissingData(context));
            }
        }
 public static void ReplyWithTitlePrompt(AlarmBotContext context)
 {
     context.Reply(GetDeleteActivity(context, context.UserState.Alarms, "Delete Alarms", "What alarm do you want to delete?"));
 }
 public static void ReplyWithDeletedAlarm(AlarmBotContext context, Alarm alarm = null)
 {
     context.Reply($"I have deleted {alarm.Title} alarm");
 }
 public static void ReplyWithNoAlarms(AlarmBotContext context)
 {
     context.Reply($"There are no alarms defined.");
 }
 public static void ReplyWithNoAlarmsFound(AlarmBotContext context, string text)
 {
     context.Reply($"There were no alarms found for {(string)text}.");
 }
Ejemplo n.º 19
0
 /// <summary>
 /// Called when resuming from an interruption
 /// </summary>
 /// <param name="context"></param>
 /// <returns></returns>
 public Task <bool> ResumeTopic(AlarmBotContext context)
 {
     return(this.FindAlarm(context));
 }
 public static async Task ReplyWithDeletedAlarm(AlarmBotContext context, Alarm alarm = null)
 {
     await context.SendActivity($"I have deleted {alarm.Title} alarm");
 }
 public static async Task ReplyWithNoAlarmsFound(AlarmBotContext context, string text)
 {
     await context.SendActivity($"There were no alarms found for {(string)text}.");
 }
 public static async Task ReplyWithNoAlarms(AlarmBotContext context)
 {
     await context.SendActivity($"There are no alarms defined.");
 }
Ejemplo n.º 23
0
 public static async Task ShowAlarms(AlarmBotContext context)
 {
     await ShowAlarmsResponses.ReplyWithShowAlarms(context, context.UserState.Alarms);
 }
 public static Task ShowAlarms(AlarmBotContext context)
 {
     ShowAlarmsResponses.ReplyWithShowAlarms(context, context.UserState.Alarms);
     return(Task.CompletedTask);
 }
 public Task <bool> ResumeTopic(AlarmBotContext context)
 {
     throw new System.NotImplementedException();
 }
Ejemplo n.º 26
0
 /// <summary>
 /// Method which is called when this topic is resumed after an interruption
 /// </summary>
 /// <param name="context"></param>
 /// <returns></returns>
 public Task <bool> ResumeTopic(AlarmBotContext context)
 {
     // just prompt the user to ask what they want to do
     DefaultResponses.ReplyWithResumeTopic(context);
     return(Task.FromResult(true));
 }
 public static async Task ReplyWithTitlePrompt(AlarmBotContext context)
 {
     var deleteActivity = GetDeleteActivity(context, context.UserState.Alarms, "Delete Alarms", "What alarm do you want to delete?");
     await context.SendActivity(deleteActivity);
 }