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)); }
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")); }
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; }
public VideoOnEnd(IAlexaRequest alexaRequest) { AlexaRequest = alexaRequest; }
public TvShowsIntent(IAlexaRequest alexaRequest, IAlexaSession session) { AlexaRequest = alexaRequest; Session = session; }
public PlaybackProgressValueUpdate(IAlexaRequest alexaRequest) { AlexaRequest = alexaRequest; }
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)); }
public goBack(IAlexaRequest alexaRequest) { AlexaRequest = alexaRequest; }
public NowPlayingEventUpdateRequest(IAlexaRequest alexaRequest) { AlexaRequest = alexaRequest; }
public UserEventPlaybackStart(IAlexaRequest alexaRequest) { AlexaRequest = alexaRequest; }
public UserEventShowItemListSequenceTemplate(IAlexaRequest alexaRequest) { AlexaRequest = alexaRequest; }
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; }
private static async Task <string> OnSessionEndRequest(IAlexaRequest alexaRequest) { await Task.Run(() => AlexaSessionManager.Instance.EndSession(alexaRequest)); return(null); }
public UserEventShowBaseItemDetailsTemplate(IAlexaRequest alexaRequest) { AlexaRequest = alexaRequest; }
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)); }