Exemple #1
0
        private static async Task <string> GetResponseResult(Type type, IAlexaRequest alexaRequest, IAlexaSession session)
        {
            var paramArgs = session is null
                ? new object[] { alexaRequest } : new object[] { alexaRequest, session };

            var instance = Activator.CreateInstance(type, paramArgs);

            return(await(Task <string>) type.GetMethod("Response").Invoke(instance, null));
        }
Exemple #2
0
        public async Task <string> Response(IAlexaRequest alexaRequest, IAlexaSession session)
        {
            session.room = await RoomContextManager.Instance.ValidateRoom(alexaRequest, session);

            session.hasRoom = session.room != null;
            if (!session.hasRoom || !session.hasRoom && !session.supportsApl) //Still go if we have a room, but we don't support APL
            {
                session.PersistedRequestData = alexaRequest;
                AlexaSessionManager.Instance.UpdateSession(session, null);
                return(await RoomContextManager.Instance.RequestRoom(alexaRequest, session));
            }

            var libraryId = ServerDataQuery.Instance.GetLibraryId(LibraryName);
            var result    = ServerDataQuery.Instance.GetItemById(libraryId);

            try
            {
#pragma warning disable 4014
                Task.Run(() => ServerController.Instance.BrowseItemAsync(session, result)).ConfigureAwait(false);
#pragma warning restore 4014
            }
            catch (BrowseCommandException)
            {
                throw new BrowseCommandException($"Couldn't browse to {result.Name}");
            }

            session.NowViewingBaseItem = result;
            //reset rePrompt data because we have fulfilled the request
            session.PersistedRequestData = null;
            AlexaSessionManager.Instance.UpdateSession(session, null);

            var genericLayoutProperties = await DataSourcePropertiesManager.Instance.GetGenericViewPropertiesAsync($"Showing the {result.Name} library", "/MoviesLibrary");

            var aplaDataSource = await DataSourcePropertiesManager.Instance.GetAudioResponsePropertiesAsync(new InternalAudioResponseQuery()
            {
                SpeechResponseType = SpeechResponseType.ItemBrowse,
                item    = result,
                session = session
            });

            var renderDocumentDirective = await RenderDocumentDirectiveManager.Instance.RenderVisualDocumentDirectiveAsync(genericLayoutProperties, session);

            var renderAudioDirective = await RenderDocumentDirectiveManager.Instance.RenderAudioDocumentDirectiveAsync(aplaDataSource);

            return(await AlexaResponseClient.Instance.BuildAlexaResponseAsync(new Response()
            {
                shouldEndSession = null,
                directives = new List <IDirective>()
                {
                    renderDocumentDirective,
                    renderAudioDirective
                }
            }, session));
        }
        public async Task <Room> ValidateRoom(IAlexaRequest alexaRequest, IAlexaSession session)
        {
            ServerController.Instance.Log.Info("Validating Intent Request Room data.");
            var request = alexaRequest.request;
            var intent  = request.intent;
            var slots   = intent.slots;
            var config  = Plugin.Instance.Configuration;

            //Already have a room data saved for the session
            ServerController.Instance.Log.Info("Checking Session Room Data.");
            if (!(session.room is null))
            {
                ServerController.Instance.Log.Info("Session Already Contains Room Data. Returning Room Data.");
                return(session.room);
            }

            //Is a user event (button press)
            if (!(request.arguments is null))
            {
                return(!HasRoomConfiguration(request.arguments[1], config)
                    ? null
                    : config.Rooms.FirstOrDefault(r => string.Equals(r.Name, request.arguments[1], StringComparison.CurrentCultureIgnoreCase)));
            }

            //Room's not mentioned in request
            ServerController.Instance.Log.Info("Checking Intent Request Room Data.");
            if (string.IsNullOrEmpty(slots.Room.value))
            {
                ServerController.Instance.Log.Info("Intent does not mention a room.");
                return(null);
            }

            if (!HasRoomConfiguration(slots.Room.value, config))
            {
                return(null);
            }

            var room = config.Rooms.FirstOrDefault(r => string.Equals(r.Name, slots.Room.value, StringComparison.CurrentCultureIgnoreCase));

            var openEmbySessions = ServerDataQuery.Instance.GetCurrentSessions().ToList();

            //device needs to be on, and emby must be open and ready for commands
            if (openEmbySessions.Exists(s => string.Equals(s.DeviceName, room?.DeviceName, StringComparison.CurrentCultureIgnoreCase)))
            {
                return(room);
            }

            //Update the user about the unfortunate state of the emby device being off.
            await AlexaResponseClient.Instance.PostProgressiveResponse($"Sorry. Access to the {room?.Name} device is currently unavailable.",
                                                                       alexaRequest.context.System.apiAccessToken, alexaRequest.request.requestId).ConfigureAwait(false);

            return(null);
        }
        private static bool SupportsApl(IAlexaRequest alexaRequest)
        {
            if (alexaRequest.context.Viewports is null)
            {
                return(false);
            }

            var viewportUtility = new ViewportUtility();
            var viewportProfile = viewportUtility.GetViewportProfile(alexaRequest.context.Viewport);

            if (viewportProfile == ViewportProfile.UNKNOWN_VIEWPORT_PROFILE)
            {
                return(false);
            }

            return(viewportUtility.ViewportSizeIsLessThen(viewportProfile, ViewportProfile.TV_LANDSCAPE_MEDIUM) &&
                   Equals(alexaRequest.context.Viewports[0].type, "APL"));
        }
Exemple #5
0
        private static async Task <string> OnLaunchRequest(IAlexaRequest alexaRequest)
        {
            var context = alexaRequest.context;
            var user    = SpeechAuthorization.Instance.GetRecognizedPersonalizationProfileResult(context.System.person);

            if (user is null)
            {
                var personNotRecognizedAudioProperties = await DataSourcePropertiesManager.Instance.GetAudioResponsePropertiesAsync(new InternalAudioResponseQuery()
                {
                    SpeechResponseType = SpeechResponseType.PersonNotRecognized
                });

                return(await AlexaResponseClient.Instance.BuildAlexaResponseAsync(
                           new Response()
                {
                    shouldEndSession = true,
                    directives = new List <IDirective>()
                    {
                        await RenderDocumentDirectiveManager.Instance.RenderAudioDocumentDirectiveAsync(personNotRecognizedAudioProperties)
                    }
                }, null));
            }

            var session = AlexaSessionManager.Instance.GetSession(alexaRequest, user);
            var genericLayoutProperties = await DataSourcePropertiesManager.Instance.GetGenericViewPropertiesAsync("Welcome to Home Theater Emby Controller", "/particles");

            var skillLaunchedAudioProperties = await DataSourcePropertiesManager.Instance.GetAudioResponsePropertiesAsync(new InternalAudioResponseQuery()
            {
                SpeechResponseType = SpeechResponseType.OnLaunch
            });

            return(await AlexaResponseClient.Instance.BuildAlexaResponseAsync(new Response()
            {
                shouldEndSession = false,
                directives = new List <IDirective>()
                {
                    await RenderDocumentDirectiveManager.Instance.RenderVisualDocumentDirectiveAsync(genericLayoutProperties, session),
                    await RenderDocumentDirectiveManager.Instance.RenderAudioDocumentDirectiveAsync(skillLaunchedAudioProperties)
                }
            }, session));
        }
        public async Task <string> RequestRoom(IAlexaRequest alexaRequest, IAlexaSession session)
        {
            var genericLayoutProperties = await DataSourcePropertiesManager.Instance.GetGenericViewPropertiesAsync("Which room did you want?", "/Question");

            var aplaDataSource = await DataSourcePropertiesManager.Instance.GetAudioResponsePropertiesAsync(new InternalAudioResponseQuery()
            {
                SpeechResponseType = SpeechResponseType.RoomContext
            });

            session.PersistedRequestData = alexaRequest;
            AlexaSessionManager.Instance.UpdateSession(session, null);

            return(await AlexaResponseClient.Instance.BuildAlexaResponseAsync(new Response()
            {
                shouldEndSession = false,
                directives = new List <IDirective>()
                {
                    await RenderDocumentDirectiveManager.Instance.RenderVisualDocumentDirectiveAsync(genericLayoutProperties, session),
                    await RenderDocumentDirectiveManager.Instance.RenderAudioDocumentDirectiveAsync(aplaDataSource)
                }
            }, session));
        }
 public SequenceOnScroll(IAlexaRequest alexaRequest)
 {
     AlexaRequest = alexaRequest;
 }
Exemple #8
0
 public VideoOnEnd(IAlexaRequest alexaRequest)
 {
     AlexaRequest = alexaRequest;
 }
 public TvShowsIntent(IAlexaRequest alexaRequest, IAlexaSession session)
 {
     AlexaRequest = alexaRequest;
     Session      = session;
 }
 public PlaybackProgressValueUpdate(IAlexaRequest alexaRequest)
 {
     AlexaRequest = alexaRequest;
 }
Exemple #11
0
 public CancelIntent(IAlexaRequest alexaRequest, IAlexaSession session)
 {
     AlexaRequest = alexaRequest;
     Session      = session;
 }
        public IAlexaSession GetSession(IAlexaRequest alexaRequest, User user = null)
        {
            // A UserEvent can only happen in an open session because sessions will always start with voice.
            if (string.Equals(alexaRequest.request.type, "Alexa.Presentation.APL.UserEvent"))
            {
                return(OpenSessions.FirstOrDefault(s => s.SessionId == alexaRequest.session.sessionId));
            }

            var context = alexaRequest.context;
            var system  = context.System;
            //var person = system.person;
            var amazonSession = alexaRequest.session;

            IAlexaRequest persistedRequestData = null;
            IAlexaSession sessionInfo          = null;

            //Room room                          = null;

            if (OpenSessions.Exists(s => s.SessionId.Equals(amazonSession.sessionId)))
            {
                sessionInfo = OpenSessions.FirstOrDefault(s => s.SessionId == amazonSession.sessionId);

                persistedRequestData = sessionInfo?.PersistedRequestData;
                //room = sessionInfo?.room;

                // ReSharper disable once ComplexConditionExpression
                //if (!(person is null) && !(sessionInfo?.person is null))
                //{
                //    if (string.Equals(sessionInfo.person.personId, person.personId))
                //    {
                //        return sessionInfo; // It is the same person speaking - return the sessionInfo.
                //    }
                //}

                // Remove the session from the "OpenSessions" List, and rebuild the session with the new data
                OpenSessions.RemoveAll(s => s.SessionId.Equals(alexaRequest.session.sessionId));
            }

            // Sync AMAZON session Id with our own.
            sessionInfo = new AlexaSession()
            {
                SessionId          = amazonSession.sessionId,
                EmbySessionId      = !(sessionInfo?.room is null) ? GetCorrespondingEmbySessionId(sessionInfo) : string.Empty,
                context            = context,
                EchoDeviceId       = system.device.deviceId,
                NowViewingBaseItem = sessionInfo?.NowViewingBaseItem,
                supportsApl        = SupportsApl(alexaRequest),
                room                 = sessionInfo?.room,
                hasRoom              = !(sessionInfo?.room is null),
                User                 = user,
                viewport             = GetCurrentViewport(alexaRequest),
                PersistedRequestData = persistedRequestData,
                paging               = new Paging {
                    pages = new Dictionary <int, Properties <MediaItem> >()
                }
            };

            OpenSessions.Add(sessionInfo);

            return(sessionInfo);
        }
 public void EndSession(IAlexaRequest alexaRequest)
 {
     OpenSessions.RemoveAll(s => s.SessionId.Equals(alexaRequest.session.sessionId));
 }
        private static ViewportProfile GetCurrentViewport(IAlexaRequest alexaRequest)
        {
            var viewportUtility = new ViewportUtility();

            return(viewportUtility.GetViewportProfile(alexaRequest.context.Viewport));
        }
Exemple #15
0
 public goBack(IAlexaRequest alexaRequest)
 {
     AlexaRequest = alexaRequest;
 }
 public NowPlayingEventUpdateRequest(IAlexaRequest alexaRequest)
 {
     AlexaRequest = alexaRequest;
 }
 public UserEventPlaybackStart(IAlexaRequest alexaRequest)
 {
     AlexaRequest = alexaRequest;
 }
 public UserEventShowItemListSequenceTemplate(IAlexaRequest alexaRequest)
 {
     AlexaRequest = alexaRequest;
 }
Exemple #19
0
        private async Task <string> OnIntentRequest(IAlexaRequest alexaRequest)
        {
            IAlexaSession session = null;

            var request = alexaRequest.request;
            var intent  = request.intent;
            var context = alexaRequest.context;
            var system  = context.System;
            var person  = system.person;

            if (!IsVoiceAuthenticationAccountLinkRequest(intent)) // create a session
            {
                if (!(person is null))
                {
                    if (!SpeechAuthorization.Instance.UserPersonalizationProfileExists(person))
                    {
                        return(await AlexaResponseClient.Instance.BuildAlexaResponseAsync(new Response()
                        {
                            shouldEndSession = true,
                            outputSpeech = new OutputSpeech()
                            {
                                phrase = "You are not a recognized user. Please take moment to register your voice profile.",
                            }
                        }, null));
                    }
                }

                var user = SpeechAuthorization.Instance.GetRecognizedPersonalizationProfileResult(person);

                session = AlexaSessionManager.Instance.GetSession(alexaRequest, user);

                //There can not be a room intent request without any prior session context data.
                if (session.PersistedRequestData is null && IsRoomNameIntentRequest(intent))
                {
                    //end the session.
                    return(await new NotUnderstood(alexaRequest, session).Response());
                }
            }

            try
            {
                /*
                 * Amazon Alexa Custom SKill Console does not allow "." in skill names.
                 * This would make creating namespace paths easier.
                 * Instead we save the skill name with "_", which replaces the "." in the reflected path to the corresponding .cs file.
                 * Replace the "_" (underscore) with a "." (period) to create the proper reflection path to the corresponding IntentRequest file.
                 */
                var intentName = intent.name.Replace("_", ".");
                ServerController.Instance.Log.Info($"Intent Name Route to {intentName}");
                return(await GetResponseResult(Type.GetType($"AlexaController.Api.IntentRequest.{intentName}"), alexaRequest, session));
            }
            catch (Exception exception)
            {
                var dataSource = await DataSourcePropertiesManager.Instance.GetGenericViewPropertiesAsync(exception.Message, "/particles");

                return(await AlexaResponseClient.Instance.BuildAlexaResponseAsync(new Response()
                {
                    shouldEndSession = true,
                    outputSpeech = new OutputSpeech()
                    {
                        phrase = $"{Ssml.SayWithEmotion($"Sorry, I was unable to do that. {exception.Message}", Emotion.excited, Intensity.low)}",
                    },

                    directives = new List <IDirective>()
                    {
                        await RenderDocumentDirectiveManager.Instance.RenderVisualDocumentDirectiveAsync(dataSource, session)
                    }
                }, session));
            }
        }
 public MoviesIntent(IAlexaRequest alexaRequest, IAlexaSession session)
 {
     AlexaRequest = alexaRequest;
     Session      = session;
 }
Exemple #21
0
        private static async Task <string> OnSessionEndRequest(IAlexaRequest alexaRequest)
        {
            await Task.Run(() => AlexaSessionManager.Instance.EndSession(alexaRequest));

            return(null);
        }
 public UserEventShowBaseItemDetailsTemplate(IAlexaRequest alexaRequest)
 {
     AlexaRequest = alexaRequest;
 }
Exemple #23
0
        private static async Task <string> OnUserEvent(IAlexaRequest alexaRequest)
        {
            var request = alexaRequest.request;

            return(await GetResponseResult(Type.GetType($"AlexaController.Api.UserEvent.{request.source.type}.{request.source.handler}.{request.arguments[0]}"), alexaRequest, null));
        }