public async Task XDBSessions(IDialogContext context, LuisResult result)
        {
            var isAuthenticated = await context.IsAuthenticated();

            if (!isAuthenticated)
            {
                context.SetUnauthorizedMessageText(result.Query);
                await context.Forward(new AuthenticationDialog(), this.ResumeAfterAuth, context.MakeMessage(), CancellationToken.None);
            }
            else if (context.IsAdministrator() || context.IsInRole(RoleNames.BotAnalytics))
            {
                EntityRecommendation period;
                Chronic.Span         span = null;

                if (result.TryFindEntity(Constants.Entities.BuiltIn_DateTime, out period))
                {
                    var parser = new Chronic.Parser();
                    foreach (var resolution in period.Resolution)
                    {
                        if (new Regex(@"^(201[0-9])$").IsMatch(resolution.Value))
                        {
                            try
                            {
                                var year = int.Parse(resolution.Value.Substring(0, 4));
                                span = new Chronic.Span(new DateTime(year, 1, 1), new DateTime(year, 1, 1).AddYears(1));
                            }
                            catch
                            {
                            }
                        }
                        else
                        {
                            span = parser.Parse(resolution.Value);
                        }
                    }

                    if (span == null && period.Resolution.Count > 0)
                    {
                        var resolution = period.Resolution.FirstOrDefault();
                        if (new Regex(@"^(201[0-9]\-W([0-5][0-9]))$").IsMatch(resolution.Value))
                        {
                            try
                            {
                                var year = int.Parse(resolution.Value.Substring(0, 4));
                                var week = int.Parse(resolution.Value.Substring(6));
                                span = new Chronic.Span(DateHelpers.FirstDateOfWeek(year, week), DateHelpers.LastDateOfWeek(year, week));
                            }
                            catch
                            {
                            }
                        }
                        else if (new Regex(@"^(201[0-9]\-([0-1][0-9]))$").IsMatch(resolution.Value))
                        {
                            try
                            {
                                var year  = int.Parse(resolution.Value.Substring(0, 4));
                                var month = int.Parse(resolution.Value.Substring(5));
                                span = new Chronic.Span(new DateTime(year, month, 1), new DateTime(year, month, 1).AddMonths(1));
                            }
                            catch
                            {
                            }
                        }
                    }
                }

                if (span == null)
                {
                    span = new Chronic.Span(DateTime.Now, DateTime.Now.AddDays(1));
                }

                var response = await SitecoreXdbAPI.Instance(context.AccessToken()).Interactions(span.Start, span.End);

                if (response.Count > 0)
                {
                    var contacts = response.Select(i => i.ContactId).Distinct();

                    await context.PostAsync($"Between {span.Start.Value.ToString("dd-MM-yyyy")} and {span.End.Value.ToString("dd-MM-yyyy")} we've had a total of {contacts.Count()} unique contacts in {response.Count} interactions. Let's look at some facts.");

                    StringBuilder sb = new StringBuilder();

                    sb.AppendLine($"The average value was {Math.Round((double)response.Sum(i => i.Value) / response.Count, 1, MidpointRounding.ToEven)}  \n");
                    sb.AppendLine($"The average number of pages visited was {Math.Round((double)response.Sum(i => i.VisitPageCount) / response.Count, 1, MidpointRounding.ToEven)}  \n");

                    if (response.Any(i => i.CampaignId.HasValue))
                    {
                        sb.AppendLine($"{response.Count(i => i.CampaignId.HasValue)} triggered a campaign.  \n");
                    }
                    else
                    {
                        sb.AppendLine($"None of them triggered a campaign.  \n");
                    }

                    await context.PostAsync(sb.ToString());
                }
                else
                {
                    await context.PostAsync($"I'm very sorry to say that you haven't had any interactions between {span.Start} and {span.End}");
                }
            }
        }
        public async Task AuthenticateIntent(IDialogContext context, LuisResult result)
        {
            object formattedValues = null;
            var    entity          = result.Entities.FirstOrDefault(x =>
                                                                    x.Type == "builtin.datetimeV2.date" ||
                                                                    x.Type == "builtin.datetimeV2.daterange" ||
                                                                    x.Type == "builtin.datetimeV2.timerange" ||
                                                                    x.Type == "builtin.datetimeV2.time" ||
                                                                    x.Type == "builtin.datetimeV2.datetime" ||
                                                                    x.Type == "builtin.datetimeV2.datetimerange");

            entity?
            .Resolution?
            .TryGetValue("values", out formattedValues);

            // If no date indication, please ask for a date.
            if (entity == null)
            {
                await context.PostAsync($"When are you home to receive a mechanic?");

                context.Wait(MessageReceived);
                return;
            }

            // Als date time --> plan dan afspraak in in dynamics.
            // Als date time in verleden, zeg dan dat het lastig wordt om langs te komen.
            // Als geen date time en wel vraag gesteld, stel dan zelf een datum voor (random).

            Chronic.Parser       parser = new Chronic.Parser();
            EntityRecommendation date   = new EntityRecommendation();

            Chronic.Span resultSpan = null;

            if (entity.Type == "builtin.datetimeV2.daterange")
            {
                result.TryFindEntity("builtin.datetimeV2.daterange", out date);
                resultSpan = parser.Parse(date.Entity);
            }
            else if (entity.Type == "builtin.datetimeV2.date")
            {
                result.TryFindEntity("builtin.datetimeV2.date", out date);
                resultSpan = parser.Parse(date.Entity);
            }
            else if (entity.Type == "builtin.datetimeV2.timerange")
            {
                result.TryFindEntity("builtin.datetimeV2.timerange", out date);
                resultSpan = parser.Parse(date.Entity);
            }
            else if (entity.Type == "builtin.datetimeV2.time")
            {
                result.TryFindEntity("builtin.datetimeV2.time", out date);
                resultSpan = parser.Parse(date.Entity);
            }
            else if (entity.Type == "builtin.datetimeV2.datetime")
            {
                result.TryFindEntity("builtin.datetimeV2.datetime", out date);
                resultSpan = parser.Parse(date.Entity);
            }

            // If we would have used a scheduling service, we could just feed it the dates and it would come up with a suggestion...
            if (!resultSpan.Start.HasValue && !resultSpan.End.HasValue)
            {
                await context.PostAsync($"When are you home to receive a mechanic?");

                context.Wait(MessageReceived);
                return;
            }
            else if (resultSpan.Start.Value <= DateTime.Now && resultSpan.End.Value <= DateTime.Now)
            {
                await context.PostAsync($"I understand you want this issue to be resolved already, but we can't go back in time to send a mechanic.");

                context.Wait(MessageReceived);
                return;
            }
            else if (resultSpan.Start.Value.Date != resultSpan.End.Value.Date)
            {
                // We got a date range, let's pick a random date (and time).
                await context.PostAsync($"Date range, let's pick a random date");

                context.Wait(MessageReceived);
                return;
            }
            else if (resultSpan.Start.Value.TimeOfDay.Hours == 0)
            {
                // Midnight, assume that we didn't recieve a time frame and suggest some random times a day.
                // GIVE TWO OPTIONS
                await context.PostAsync($"Single time on a day.");

                context.Wait(MessageReceived);
                return;
            }
            else if (resultSpan.Start.Value.TimeOfDay.Hours == resultSpan.Start.Value.TimeOfDay.Hours)
            {
                // We got a single time on that day
                await context.PostAsync($"Sorry, there is no mechanic available at " + resultSpan.Start.Value.TimeOfDay.Hours + ".");

                this.suggestedDate = resultSpan.Start.Value.AddHours(1);
                PromptDialog.Confirm(context, this.ConfirmMechanicDateTime, $"There is one available at " + (resultSpan.Start.Value.TimeOfDay.Hours + 1) + ", should I schedule that for you?");
                return;
            }
            else if (resultSpan.Start.Value.TimeOfDay.Hours != resultSpan.Start.Value.TimeOfDay.Hours)
            {
                // Just have some fun, pick a random time on this day
                await context.PostAsync($"Timeframe on a day, pick a random time");

                context.Wait(MessageReceived);
                return;
            }
            else
            {
                // Yeah, what else?
                await context.PostAsync($"Yeah, what else? =(");

                context.Wait(MessageReceived);
                return;
            }
        }
Пример #3
0
        public async Task StartPollAsync(CommandContext ctx)
        {
            var pollMessageUpdater = await PollMessageUpdater.Create(ctx);

            var setupMessageUpdater = await SetupMessageUpdater.Create(ctx);

            var interactivity = ctx.Client.GetInteractivity();

            var questionReponse =
                await interactivity.WaitForMessageAsync(
                    msg => msg.Author == ctx.Member && msg.ChannelId == ctx.Channel.Id,
                    _timeOut);

            if (questionReponse.TimedOut)
            {
                await ctx.ErrorAsync("You didn't respond in time. Please start over", "Timed out");

                await ctx.Channel.DeleteMessagesAsync(new[] { setupMessageUpdater.Message, pollMessageUpdater.Message });

                return;
            }

            string pollQuestion = questionReponse.Result.Content.Trim();

            if (pollQuestion.IsEmptyOrWhiteSpace())
            {
                await ctx.ErrorAsync("You didn't provide a proper poll question. Please start over", "Empty question");

                await ctx.Channel.DeleteMessagesAsync(new[] { setupMessageUpdater.Message, pollMessageUpdater.Message });

                return;
            }

            await pollMessageUpdater.SetPollTitle(pollQuestion);

            await ctx.Channel.DeleteMessageAsync(questionReponse.Result);

            await setupMessageUpdater.SetSecondInstruction();

            var timeResponse =
                await interactivity.WaitForMessageAsync(
                    msg => msg.Author == ctx.Member && msg.ChannelId == ctx.Channel.Id,
                    _timeOut);

            if (timeResponse.TimedOut)
            {
                await ctx.ErrorAsync("You didn't respond in time. Please start over", "Timed out");

                await ctx.Channel.DeleteMessagesAsync(new[] { setupMessageUpdater.Message, pollMessageUpdater.Message });

                return;
            }

            var timeParser = new Chronic.Parser(new Chronic.Options()
            {
                Context          = Chronic.Pointer.Type.Future,
                EndianPrecedence = Chronic.EndianPrecedence.Little,
                FirstDayOfWeek   = DayOfWeek.Monday
            });

            Chronic.Span parsedTime = timeParser.Parse(timeResponse.Result.Content);
            if (parsedTime == null)
            {
                await ctx.ErrorAsync("I couldn't understand this Date/Time. Please start over", "Invalid Time");

                await ctx.Channel.DeleteMessagesAsync(new[] { setupMessageUpdater.Message, pollMessageUpdater.Message });

                return;
            }

            DateTime endTime = parsedTime.ToTime();

            if (endTime < DateTime.Now)
            {
                await ctx.ErrorAsync("The provided time is in the past. Please start over", "Invalid Time");

                await ctx.Channel.DeleteMessagesAsync(new[] { setupMessageUpdater.Message, pollMessageUpdater.Message });

                return;
            }

            await pollMessageUpdater.SetEndTime(endTime);

            await ctx.Channel.DeleteMessageAsync(timeResponse.Result);

            await setupMessageUpdater.SetThirdInstruction();

            await setupMessageUpdater.AddOkButton();

            var pollAnswers = new List <PollAnswer>();

            while (true)
            {
                var addAnswerTask = interactivity.WaitForMessageAsync(
                    msg => msg.Author == ctx.Member && msg.ChannelId == ctx.Channel.Id,
                    _timeOut);
                var okTask = interactivity.WaitForButtonAsync(setupMessageUpdater.Message, ctx.Member, _timeOut);
                var result = await Task.WhenAny(addAnswerTask, okTask);

                if (result == addAnswerTask)
                {
                    var pollOptionResponse = addAnswerTask.Result;
                    if (pollOptionResponse.TimedOut)
                    {
                        if (pollAnswers.Count >= 2)
                        {
                            break;
                        }

                        await ctx.ErrorAsync("You didn't provide enough answers in time. Please start over",
                                             "Timed out");

                        await ctx.Channel.DeleteMessagesAsync(new[]
                        {
                            setupMessageUpdater.Message, pollMessageUpdater.Message
                        });

                        return;
                    }

                    var order       = pollAnswers.Count;
                    var answerValue = pollOptionResponse.Result.Content;
                    pollAnswers.Add(new PollAnswer(order, answerValue));

                    await ctx.Channel.DeleteMessageAsync(pollOptionResponse.Result);

                    await pollMessageUpdater.UpdateAnswers(pollAnswers);

                    await pollMessageUpdater.UpdateAnswersButtons(pollAnswers);
                }
                else
                {
                    if (!okTask.Result.TimedOut)
                    {
                        await okTask.Result.Result.Interaction.CreateResponseAsync(InteractionResponseType
                                                                                   .UpdateMessage);

                        if (pollAnswers.Count < 2)
                        {
                            await ctx.ErrorAsync("Not enough answer options! Please add more first!");
                        }
                        else
                        {
                            break;
                        }
                    }
                    else
                    {
                        if (pollAnswers.Count >= 2)
                        {
                            break;
                        }

                        await ctx.ErrorAsync("You didn't provide enough answers in time. Please start over",
                                             "Timed out");

                        await ctx.Channel.DeleteMessagesAsync(new[]
                        {
                            setupMessageUpdater.Message, pollMessageUpdater.Message
                        });

                        return;
                    }
                }
            }

            await ctx.Channel.DeleteMessageAsync(setupMessageUpdater.Message);

            var poll = new Poll(ctx.Guild.Id, ctx.Channel.Id, pollMessageUpdater.Message.Id, ctx.Member.Id,
                                pollQuestion, pollAnswers,
                                endTime.ToUniversalTime());

            await _pollService.AddAndStartPollAsync(poll);
        }