public override async Task <IActionResult> Handle(GoogleDialogFlowRequest request, ILogger log)
        {
            var response = GoogleDialogFlowResponse.FromRequest(request);

            PopulateSessionParameters(response);

            var correspondingPrograms = await this.programRepository
                                        .SearchProgramsByCategory(response.Session.Params["dateTime"],
                                                                  response.Session.Params["channel"],
                                                                  response.Session.Params["category"]) as IEnumerable <TVProgram>;

            if (!correspondingPrograms.Any())
            {
                response.Prompt.FirstSimple = new Simple
                {
                    Speech = "Désolé, je n'ai pas trouvé de programme qui pourrait vous correspondre."
                };

                return(new OkObjectResult(response));
            }

            var content = await CreateLookupContent(correspondingPrograms, log);

            if (!response.Request.Intent.Params.ContainsKey("channel"))
            {
                await PrepareMultipleChannelAnswer(response, content, log);
            }
            else
            {
                await PrepareSingleChannelAnswer(response, content, log);
            }

            return(new OkObjectResult(response));
        }
        private async Task PrepareSingleChannelAnswer(GoogleDialogFlowResponse response, IEnumerable <LookupContent> items, ILogger log)
        {
            var channel = (await this.channelRepository.SearchChannels())
                          .Single(channel => channel.RowKey == response.Request.Intent.Params["channel"].Resolved);

            var program = items.First();

            if (!response.Request.Device.Capabilities.Contains("RICH_RESPONSE"))
            {
                response.Prompt.FirstSimple = new Simple
                {
                    Speech = $"{response.Session.Params["askedPeriod"]}, sur {channel.DisplayName} à {program.StartHour} il y a \"{program.ProgramTitle}.\""
                };
            }
            else
            {
                response.Prompt.AddContent("list", new ListResponseContent
                {
                    Title = $"{response.Session.Params["askedPeriod"]}, sur {channel.DisplayName}",
                    Items = items.Select(c => new ListItemResponseContent {
                        Key = c.Key
                    }).ToList()
                });

                response.Session.AddTypeOverride(new TypeOverride
                {
                    Name             = "prompt_program",
                    TypeOverrideMode = "TYPE_REPLACE",
                    Synonym          = new TypeOverrideSynonym
                    {
                        Entries = items.Select(c => new TypeOverrideSynonymEntry
                        {
                            Name     = c.Key,
                            Synonyms = new string[]
                            {
                                c.ChanelName,
                                c.ProgramTitle
                            },
                            Display = new SynonymEntryDisplay
                            {
                                Title       = c.Title,
                                Description = c.Description,
                                Image       = new SynonymEntryDisplayImage
                                {
                                    Url = c.IconSrc,
                                    Alt = c.Title
                                }
                            }
                        }).ToList()
                    }
                });
            }
        }
        public override Task <IActionResult> Handle(GoogleDialogFlowRequest request, ILogger log)
        {
            var response = GoogleDialogFlowResponse.FromRequest(request);

            response.Prompt.FirstSimple = new Simple
            {
                Speech = "Bonjour. Que puis-je faire pour vous ?"
            };

            response.Prompt.Override = false;

            return(Task.FromResult <IActionResult>(new OkObjectResult(response)));
        }
        private void PopulateSessionParameters(GoogleDialogFlowResponse response)
        {
            DateTimeOffset dateTime = DateTimeOffset.UtcNow;

            if (response.Request.Intent.Params.ContainsKey("category"))
            {
                response.Session.Params["askedCategory"] = response.Request.Intent.Params["category"].Original;
                response.Session.Params["category"]      = response.Request.Intent.Params["category"].Resolved;
            }
            else
            {
                response.Session.Params["category"] = string.Empty;
            }

            if (response.Request.Intent.Params.ContainsKey("channel"))
            {
                response.Session.Params["channel"] = response.Request.Intent.Params["channel"].Resolved;
            }
            else
            {
                response.Session.Params["channel"] = null;
            }

            if (response.Request.Intent.Params.ContainsKey("dateTime"))
            {
                dateTime = new DateTimeOffset(
                    DynamicHelper.CovertToInt32(response.Request.Intent.Params["dateTime"].Resolved.year, DateTimeOffset.Now.Year),
                    DynamicHelper.CovertToInt32(response.Request.Intent.Params["dateTime"].Resolved.months, DateTimeOffset.Now.Month),
                    DynamicHelper.CovertToInt32(response.Request.Intent.Params["dateTime"].Resolved.day, DateTimeOffset.Now.Day),
                    DynamicHelper.CovertToInt32(response.Request.Intent.Params["dateTime"].Resolved.hours, DateTimeOffset.Now.Hour),
                    DynamicHelper.CovertToInt32(response.Request.Intent.Params["dateTime"].Resolved.minutes, DateTimeOffset.Now.Minute),
                    0,
                    DateTimeOffset.Now.Offset
                    );

                response.Session.Params["askedPeriod"] = response.Request.Intent.Params["dateTime"].Original;
            }
            else if (response.Request.Intent.Params.ContainsKey("dateTimeToken"))
            {
                response.Session.Params["askedPeriod"] = response.Request.Intent.Params["dateTimeToken"].Original;
                dateTime = PeriodTokenHelper.GetDateTimeFromToken(response.Request.Intent.Params["dateTimeToken"].Resolved);
            }
            else
            {
                response.Session.Params["askedPeriod"] = "maintenant";
            }

            response.Session.Params["dateTime"] = dateTime;
        }
        private void PrepareRichContentAnswer(GoogleDialogFlowResponse response, IEnumerable <LookupContent> items, ILogger log)
        {
            if (!response.Request.Device.Capabilities.Contains("RICH_RESPONSE"))
            {
                return;
            }

            response.Prompt.AddContent("list", new ListResponseContent
            {
                Title = $"Au programme {response.Session.Params["askedPeriod"]} :",
                Items = items.Select(c => new ListItemResponseContent {
                    Key = c.Key
                }).ToList()
            });

            response.Session.AddTypeOverride(new TypeOverride
            {
                Name             = "prompt_program",
                TypeOverrideMode = "TYPE_REPLACE",
                Synonym          = new TypeOverrideSynonym
                {
                    Entries = items.Select(c => new TypeOverrideSynonymEntry
                    {
                        Name     = c.Key,
                        Synonyms = new string[]
                        {
                            c.ChanelName,
                            c.ProgramTitle
                        },
                        Display = new SynonymEntryDisplay
                        {
                            Title       = c.Title,
                            Description = c.Description,
                            Image       = new SynonymEntryDisplayImage
                            {
                                Url = c.IconSrc,
                                Alt = c.Title
                            }
                        }
                    }).ToList()
                }
            });
        }
        private async Task PrepareSpeechContentAnswerForSingleChannel(GoogleDialogFlowResponse response, IEnumerable <LookupContent> items, ILogger log)
        {
            var channel = (await this.channelRepository.SearchChannels())
                          .Single(channel => channel.RowKey == response.Request.Intent.Params["channel"].Resolved);

            var program = items.First();

            response.Prompt.FirstSimple = new Simple
            {
                Speech = $"{response.Session.Params["askedPeriod"]}, sur {channel.DisplayName} à {program.StartHour} il y a \"{program.ProgramTitle}.\""
            };

            response.Prompt.AddContent("list", new ListResponseContent
            {
                Title = $"{response.Session.Params["askedPeriod"]}, sur {channel.DisplayName}",
                Items = items.Select(c => new ListItemResponseContent {
                    Key = c.Key
                }).ToList()
            });
        }
        private Task PrepareSpeechContentAnswer(GoogleDialogFlowResponse response, IEnumerable <LookupContent> items, ILogger log)
        {
            return(Task.Factory.StartNew(() =>
            {
                if (!response.Request.Device.Capabilities.Contains("RICH_RESPONSE"))
                {
                    StringBuilder responseBuilder = new StringBuilder();

                    items.ToList()
                    .ForEach(c => responseBuilder.AppendLine($"{c.Category}, {c.Title}."));

                    response.Prompt.LastSimple = new Simple
                    {
                        Speech = responseBuilder.ToString()
                    };
                }

                response.Prompt.FirstSimple = new Simple
                {
                    Speech = $"Voici les programmes qui pourraient vous intéresser {response.Session.Params["askedPeriod"]} :"
                };
            }));
        }
        private Task PrepareMultipleChannelAnswer(GoogleDialogFlowResponse response, IEnumerable <LookupContent> items, ILogger log)
        {
            return(Task.Factory.StartNew(() =>
            {
                if (!response.Request.Device.Capabilities.Contains("RICH_RESPONSE"))
                {
                    response.Prompt.FirstSimple = new Simple
                    {
                        Speech = $"Voici les {response.Session.Params["askedCategory"]}s qui pourraient vous intéresser {response.Session.Params["askedPeriod"]} :"
                    };

                    StringBuilder responseBuilder = new StringBuilder();

                    items.ToList()
                    .ForEach(c => responseBuilder.AppendLine($"{c.Title}."));

                    response.Prompt.LastSimple = new Simple
                    {
                        Speech = responseBuilder.ToString()
                    };

                    response.Scene.Next = new Scene
                    {
                        Name = "actions.scene.END_CONVERSATION"
                    };
                }
                else
                {
                    response.Prompt.AddContent("list", new ListResponseContent
                    {
                        Title = $"Les {response.Session.Params["askedCategory"]}s, {response.Session.Params["askedPeriod"]} :",
                        Items = items.Select(c => new ListItemResponseContent {
                            Key = c.Key
                        }).ToList()
                    });

                    response.Session.AddTypeOverride(new TypeOverride
                    {
                        Name = "prompt_program",
                        TypeOverrideMode = "TYPE_REPLACE",
                        Synonym = new TypeOverrideSynonym
                        {
                            Entries = items.Select(c => new TypeOverrideSynonymEntry
                            {
                                Name = c.Key,
                                Synonyms = new string[]
                                {
                                    c.ChanelName,
                                    c.ProgramTitle
                                },
                                Display = new SynonymEntryDisplay
                                {
                                    Title = c.Title,
                                    Description = c.Description,
                                    Image = new SynonymEntryDisplayImage
                                    {
                                        Url = c.IconSrc,
                                        Alt = c.Title
                                    }
                                }
                            }).ToList()
                        }
                    });
                }
            }));
        }