public static async Task <SpeechletResponse> GetResults(Session session, Intent intent) { var repository = DataFactory.Create(session); string accountNameFilter = ParseAlias(intent.Slots["accountName"]?.Value); var me = await repository.GetMe(); var account = await repository.GetAccount(me.FamilyID, accountNameFilter); return(AlexaUtils.BuildSpeechletResponse(ParseResults(account, accountNameFilter), true)); }
public static async Task <SpeechletResponse> GetResults(Session session, Intent intent) { var repository = DataFactory.Create(session); string filterDateString = intent.Slots["dateFilter"]?.Value; DateTime dateFilter = (string.IsNullOrEmpty(filterDateString)) ? DateTime.Now : Convert.ToDateTime(filterDateString); var me = await repository.GetMe(); var menuItem = await repository.GetMenuItem(me.SchoolID, dateFilter); return(AlexaUtils.BuildSpeechletResponse(ParseResults(menuItem, dateFilter), true)); }
// find the song the user has requested and generate the intent response needed to begin playing it. public static async Task <AlexaUtils.SimpleIntentResponse> SearchGrooveSong(string songName, string artistName, Session session, HttpClient httpClient) { string msgSongId = ""; string msgStreamUri = ""; // first, search for the song based on songName and artistName try { var requestUri = msgSearchUri + Uri.EscapeUriString(songName + "+" + artistName) + "&" + "filters=tracks+artists&" + "source=collection"; httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", session.User.AccessToken.ToString()); var httpResponseMessage = await httpClient.GetAsync(requestUri); if (httpResponseMessage.IsSuccessStatusCode) { var httpResultString = await httpResponseMessage.Content.ReadAsStringAsync(); dynamic resultObject = JObject.Parse(httpResultString); msgSongId = resultObject.Tracks.Items[0].Id; // assume the first result is the correct one } } catch { return(null); } // now, we get the stream URL for the song based on its ID (msgId) msgStreamUri = await GetStreamUrl(msgSongId, httpClient, session); var stringToRead = "You asked Groove to play the song " + songName; if (!string.IsNullOrEmpty(artistName)) { stringToRead += " by " + artistName; } AlexaUtils.SimpleIntentResponse simpleIntentResponse = new AlexaUtils.SimpleIntentResponse() { cardText = stringToRead, ssmlString = AlexaUtils.AddSpeakTagsAndClean(stringToRead), largeImage = "groove.png", smallImage = "groove.png", musicUrl = msgStreamUri, msgId = msgSongId, }; return(simpleIntentResponse); }
public static async Task <SpeechletResponse> GetResults(Session session, Intent intent) { var repository = DataFactory.Create(session); var studentFirstName = intent.Slots["studentFirstName"]?.Value.ToProperCase(); string dateFilterString = intent.Slots["date"]?.Value; DateTime dateFilter = (string.IsNullOrEmpty(dateFilterString)) ? DateTime.Now.AddDays(-7) : Convert.ToDateTime(dateFilterString); var me = await repository.GetMe(); var student = await repository.GetStudent(me.FamilyID, studentFirstName); var missingAssignments = await repository.GetMissingAssingments(student.ID, dateFilter); return(AlexaUtils.BuildSpeechletResponse(ParseResults(missingAssignments.ToList(), student, me), true)); }
private static AlexaUtils.SimpleIntentResponse ParseResults(Account account, string accountNameFilter) { StringBuilder spokenText = new StringBuilder(); if (account == null) { spokenText.Append(AlexaUtils.AddSentenceTags($"I could not find an account named {accountNameFilter}")); spokenText.Append(AlexaUtils.AddSentenceTags($"I can lookup for the balance for accounts named cafeteria or childcare")); } else { spokenText.Append(AlexaUtils.AddSentenceTags($"The balance on your {account.Name} account is {AlexaUtils.AddSayAsTags("$" + account.Amount, InterpretAs.Unit)}")); } return(new AlexaUtils.SimpleIntentResponse() { ssmlString = AlexaUtils.AddSpeakTags(spokenText.ToString()) }); }
PlayGrooveMusic(Session session, HttpClient httpClient, IntentRequest intentRequest) { AlexaUtils.SimpleIntentResponse simpleIntentResponse = new AlexaUtils.SimpleIntentResponse(); AlexaSkillsKit.Slu.Slot objectByArtistName; AlexaSkillsKit.Slu.Slot objectName; AlexaSkillsKit.Slu.Slot objectType; intentRequest.Intent.Slots.TryGetValue("object.byArtist.name", out objectByArtistName); intentRequest.Intent.Slots.TryGetValue("object.name", out objectName); intentRequest.Intent.Slots.TryGetValue("object.type", out objectType); if (objectType.Value.ToString() == "song") { simpleIntentResponse = await SearchGrooveSong(objectName.Value, objectByArtistName.Value, session, httpClient); } else if (objectType.Value.ToString() == "album") { simpleIntentResponse = await SearchGrooveAlbum(objectName.Value, objectByArtistName.Value, session, httpClient); } return(AlexaUtils.BuildSpeechletResponse(simpleIntentResponse, true)); }
private static AlexaUtils.SimpleIntentResponse ParseResults(MenuItem menuItem, DateTime dateFilter) { StringBuilder spokenText = new StringBuilder(); string dateFilterFormatted = dateFilter.ToString(AlexaConstants.DefaultDateFormat); if (menuItem == null) { if (dateFilter.DayOfWeek == DayOfWeek.Saturday || dateFilter.DayOfWeek == DayOfWeek.Sunday) { spokenText.Append(AlexaUtils.AddSentenceTags($"There's nothing on the menu for {AlexaUtils.AddSayAsTags(dateFilterFormatted, InterpretAs.Date, "mdy")} it's the weekend")); } else { spokenText.Append(AlexaUtils.AddSentenceTags($"There's nothing on the menu for {AlexaUtils.AddSayAsTags(dateFilterFormatted, InterpretAs.Date, "mdy")}")); } } else { spokenText.Append(AlexaUtils.AddSentenceTags($"On the menu for {AlexaUtils.AddSayAsTags(dateFilterFormatted, InterpretAs.Date, "mdy")}")); spokenText.Append(AlexaUtils.AddSentenceTagsAndClean(menuItem.MealName)); spokenText.Append(AlexaUtils.AddSentenceTagsAndClean(menuItem.MealDesc)); } return(new AlexaUtils.SimpleIntentResponse() { ssmlString = AlexaUtils.AddSpeakTags(spokenText.ToString()) }); }
private static AlexaUtils.SimpleIntentResponse ParseResults(List <MissingAssignment> missingAssignments, Student student, Me me) { StringBuilder spokenText = new StringBuilder(); int count = (missingAssignments == null) ? 0 : missingAssignments.Count; if (count > 0) { string plural = (count > 1) ? "s" : ""; spokenText.Append(AlexaUtils.AddSentenceTags($"{student.FirstName} has {count} missing assignment{plural}")); } else { spokenText.Append(AlexaUtils.AddSentenceTags($"{student.FirstName} has no missing assignments")); spokenText.Append(AlexaUtils.AddSentenceTags(AlexaUtils.AddSayAsTags($"Great job, {student.FirstName}", InterpretAs.Interjection))); } if (missingAssignments != null) { foreach (var ma in missingAssignments) { spokenText.Append(AlexaUtils.AddSentenceTagsAndClean(ma.ClassName)); spokenText.Append(AlexaUtils.AddSentenceTagsAndClean(ma.Title)); spokenText.Append(AlexaUtils.AddSentenceTagsAndClean(ma.Description)); spokenText.Append(AlexaUtils.AddSentenceTags("<emphasis level='strong'>Due date</emphasis> " + AlexaUtils.AddSayAsTags(ma.DueDateFormatted, InterpretAs.Date, "mdy"))); } } return(new AlexaUtils.SimpleIntentResponse() { ssmlString = AlexaUtils.AddSpeakTags(spokenText.ToString()), largeImage = string.Format(Url.StudentPhoto, me.SchoolID, student.Picture), smallImage = Url.Logo }); }
EnqueueGrooveMusic(Context context, HttpClient httpClient, String action) { Session session = new Session() { User = new User() { AccessToken = context.System.User.AccessToken } }; // When playing an audio stream, you provide Alexa an audio token // you generate. Alexa provides the token back to you in subsequent // audio requests: i.e. enqueue the next song to play. // The format of the token we generate is: // <MusicId>?<Track> where <MusicId> is the unique identifier provided by // the Groove API for the individual song, album, or playlist the user wants to hear, and // <Track> is the index of the song in the album or playlist. If there is no <Track> // value, then the user has asked to only play a single song string[] items = context.AudioPlayer.Token.Split('?'); if (items.Length != 2) { return(null); } // if there are two items in the items[] array then an album or playlist // is being played. find out if it's a playlist or album, get the stream url, // then enqueue it, and increment the index string msgAlbumId = items[0]; int msgAlbumIndex = int.Parse(items[1]); msgAlbumIndex++; string msgStreamUri = ""; if (items[0].Contains("playlist")) { msgStreamUri = await GetSongUrlByAlbumIdAndIndex(msgAlbumId, msgAlbumIndex, httpClient, session, "playlist"); } else // it's an album that's playing { msgStreamUri = await GetSongUrlByAlbumIdAndIndex(msgAlbumId, msgAlbumIndex, httpClient, session, "album"); } if (msgStreamUri == "") { return(null); } AlexaUtils.SimpleIntentResponse simpleIntentResponse = new AlexaUtils.SimpleIntentResponse() { musicUrl = msgStreamUri, msgId = msgAlbumId + "?" + msgAlbumIndex, musicAction = action }; return(AlexaUtils.BuildSpeechletResponse(simpleIntentResponse, true)); }
// Playlists have names in Groove Music. // In this first version, users will have to refer to the playlist they want by number: 0, 1, 2, 3, etc. // For example: "Alexa, ask Groove to play playlist 1". // The number corresponds to the playlists' position in the Groove UI which also corresponds to the playlist's // position when we make an API call to get all playlsits. // We're using Alexa's pre-built slot for numbers to translate spoken numbers to their text equivalent // Parse the number the user has spoken, call the Groove API to get the playlist that corresponds to the index (number) // and do the work needed to start playing the playlist from the first song. public static async Task <SpeechletResponse> PlayGroovePlaylist(Session session, HttpClient httpClient, IntentRequest intentRequest) { AlexaSkillsKit.Slu.Slot playlistNumber; intentRequest.Intent.Slots.TryGetValue("PlaylistNumber", out playlistNumber); string msgStreamUri = ""; string msgPlaylistId = ""; string playlistName = ""; int msgPlaylistIndex = int.Parse(playlistNumber.Value); try { var requestUri = msgBaseUri + "/music/collection/playlists/browse?" + "source=collection"; httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", session.User.AccessToken.ToString()); var httpResponseMessage = await httpClient.GetAsync(requestUri); if (httpResponseMessage.IsSuccessStatusCode) { var httpResultString = await httpResponseMessage.Content.ReadAsStringAsync(); Debug.WriteLine("response is " + httpResultString); dynamic resultObject = JObject.Parse(httpResultString); msgPlaylistId = resultObject.Playlists.Items[msgPlaylistIndex].Id; playlistName = resultObject.Playlists.Items[msgPlaylistIndex].Name; msgStreamUri = await GetSongUrlByAlbumIdAndIndex(msgPlaylistId, 0, httpClient, session, "playlist"); } } catch { return(null); } var stringToRead = "You asked Groove to play playlist " + playlistNumber.Value + ", also known as " + playlistName; AlexaUtils.SimpleIntentResponse simpleIntentResponse = new AlexaUtils.SimpleIntentResponse() { cardText = stringToRead, ssmlString = AlexaUtils.AddSpeakTagsAndClean(stringToRead), largeImage = "groove.png", smallImage = "groove.png", musicUrl = msgStreamUri, // When playing an audio stream, you provide Alexa an audio token // you generate. Alexa provides the token back to you in subsequent // audio requests: i.e. enqueue the next song to play. // The format of the token we generate is: // <MusicId>?<Track> where <MusicId> is the unique identifier provided by // the Groove API for the individual song, album, or playlist the user wants to hear, and // <Track> is the index of the song in the album or playlist. If there is no <Track> // value, then the user has asked to only play a single song msgId = msgPlaylistId + "?" + "0", }; return(AlexaUtils.BuildSpeechletResponse(simpleIntentResponse, true)); }
// find the album the user has requested and generate the intent response needed to begin playing it. public static async Task <AlexaUtils.SimpleIntentResponse> SearchGrooveAlbum(string albumName, string artistName, Session session, HttpClient httpClient) { string msgAlbumId = ""; string msgStreamUri = ""; // first, search for the album based on albumName and artistName // return the value into msgAlbumId try { var requestUri = msgSearchUri + albumName + " " + artistName + "&" + "filters=albums+artists&" + "source=collection"; httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", session.User.AccessToken.ToString()); var httpResponseMessage = await httpClient.GetAsync(requestUri); if (httpResponseMessage.IsSuccessStatusCode) { var httpResultString = await httpResponseMessage.Content.ReadAsStringAsync(); dynamic resultObject = JObject.Parse(httpResultString); msgAlbumId = resultObject.Albums.Items[0].Id; // assume the first album returned (Items[0]) is the correct one msgStreamUri = await GetSongUrlByAlbumIdAndIndex(msgAlbumId, 0, httpClient, session, "album"); // get the stream URL for the first track so we can queue it up } else { return(null); } } catch { return(null); } var stringToRead = "You asked Groove to play the album " + albumName; if (!string.IsNullOrEmpty(artistName)) { stringToRead += " by " + artistName; } AlexaUtils.SimpleIntentResponse simpleIntentResponse = new AlexaUtils.SimpleIntentResponse() { cardText = stringToRead, ssmlString = AlexaUtils.AddSpeakTagsAndClean(stringToRead), largeImage = "groove.png", smallImage = "groove.png", musicUrl = msgStreamUri, // When playing an audio stream, you provide Alexa an audio token // you generate. Alexa provides the token back to you in subsequent // audio requests: i.e. enqueue the next song to play. // The format of the token we generate is: // <MusicId>?<Track> where <MusicId> is the unique identifier provided by // the Groove API for the individual song, album, or playlist the user wants to hear, and // <Track> is the index of the song in the album or playlist. If there is no <Track> // value, then the user has asked to only play a single song msgId = msgAlbumId + "?" + "0", }; return(simpleIntentResponse); }
public static async Task <SpeechletResponse> GetResults(Session session) { var simpleIntentResponse = ParseResults(); return(AlexaUtils.BuildSpeechletResponse(simpleIntentResponse, true)); }
private static AlexaUtils.SimpleIntentResponse ParseResults(List <HomeworkAssignment> homeworkAssignments, Student student, Me me, DateTime dateFilter) { StringBuilder spokenText = new StringBuilder(); int count = (homeworkAssignments == null) ? 0 : homeworkAssignments.Count; if (count > 0) { string plural = (count > 1) ? "s" : ""; spokenText.Append(AlexaUtils.AddSentenceTags($"Yes, {student.FirstName} has {count} homework assignment{plural}")); } else { spokenText.Append(AlexaUtils.AddSentenceTags($"{student.FirstName} has no homework due on {AlexaUtils.AddSayAsTags(dateFilter.ToString(AlexaConstants.DefaultDateFormat), InterpretAs.Date, "mdy")}")); spokenText.Append(AlexaUtils.AddSentenceTags(AlexaUtils.AddSayAsTags($"<phoneme alphabet='x-sampa' ph='jIpi'>Yipee</phoneme>", InterpretAs.Interjection))); } if (homeworkAssignments != null) { foreach (var ma in homeworkAssignments) { spokenText.Append(AlexaUtils.AddSentenceTagsAndClean(ma.ClassName)); spokenText.Append(AlexaUtils.AddSentenceTagsAndClean(ma.Title)); spokenText.Append(AlexaUtils.AddSentenceTagsAndClean(ma.Description)); spokenText.Append(AlexaUtils.AddSentenceTags("<emphasis level='strong'>Due date</emphasis> " + AlexaUtils.AddSayAsTags(ma.DueDateFormatted, InterpretAs.Date, "mdy"))); } } return(new AlexaUtils.SimpleIntentResponse() { ssmlString = AlexaUtils.AddSpeakTags(spokenText.ToString()), largeImage = string.Format(Url.StudentPhoto, me.SchoolID, student.Picture), smallImage = Url.Logo }); }
public static async Task <SpeechletResponse> GetUnreadEmailCount(Session session, HttpClient httpClient) //public static SpeechletResponse GetUnreadEmailCount(Session session, HttpClient httpClient) { int unreadCount = 0; int maxToRead = 5; string httpResultString = ""; // Connect to Outlook httpClient.DefaultRequestHeaders.Clear(); httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", session.User.AccessToken); //var httpResponseMessage = // httpClient.GetAsync(unreadOutlookEmailsInInbox).Result; var httpResponseMessage = await httpClient.GetAsync(unreadOutlookEmailsInInboxUri); if (httpResponseMessage.IsSuccessStatusCode) { //httpResultString = httpResponseMessage.Content.ReadAsStringAsync().Result; httpResultString = await httpResponseMessage.Content.ReadAsStringAsync(); dynamic resultObject = JObject.Parse(httpResultString); unreadCount = resultObject.value.Count; } else if (httpResponseMessage.StatusCode == System.Net.HttpStatusCode.NotFound) { httpResultString = httpResponseMessage.Content.ReadAsStringAsync().Result; dynamic resultObject = JObject.Parse(httpResultString); var errorString = resultObject.error.code; httpResponseMessage.Dispose(); if (errorString == "MailboxNotEnabledForRESTAPI" || errorString == "MailboxNotSupportedForRESTAPI") { return(AlexaUtils.BuildSpeechletResponse(new AlexaUtils.SimpleIntentResponse() { cardText = mailboxNotUpgradedMessage }, true)); } else { return(AlexaUtils.BuildSpeechletResponse(new AlexaUtils.SimpleIntentResponse() { cardText = AlexaConstants.AppErrorMessage }, true)); } } else { httpResponseMessage.Dispose(); return(AlexaUtils.BuildSpeechletResponse(new AlexaUtils.SimpleIntentResponse() { cardText = AlexaConstants.AppErrorMessage }, true)); } string cardBody = ""; string spokenString = ""; string emailMaximumNotice = "We'll read the first " + maxToRead; switch (unreadCount) { case 0: cardBody = "You have no unread email in your Outlook Inbox."; spokenString = cardBody; break; case 1: cardBody = "You have 1 unread email in your Outlook Inbox. "; spokenString = cardBody + CreateSpeechString(httpResultString); break; default: cardBody = "You have " + unreadCount + " unread emails in your Outlook Inbox. "; if (unreadCount <= maxToRead) { spokenString = cardBody + CreateSpeechString(httpResultString, unreadCount); } else { spokenString = cardBody + emailMaximumNotice + CreateSpeechString(httpResultString, maxToRead); } break; } httpResponseMessage.Dispose(); AlexaUtils.SimpleIntentResponse simpleIntentResponse = new AlexaUtils.SimpleIntentResponse() { cardText = cardBody, ssmlString = AlexaUtils.AddSpeakTagsAndClean(spokenString), largeImage = "outlook.png", smallImage = "outlook.png", }; return(AlexaUtils.BuildSpeechletResponse(simpleIntentResponse, true)); }
public static async Task <SpeechletResponse> GetOutlookEventCount(Session session, HttpClient httpClient) //public static SpeechletResponse GetUnreadEmailCount(Session session, HttpClient httpClient) { int unreadCount = 0; int maxToRead = 5; string httpResultString = ""; string myOutlookTimeZone = ""; // Connect to Outlook myOutlookTimeZone = await GetOutlookTimezone(session, httpClient); if (myOutlookTimeZone == "") { return(AlexaUtils.BuildSpeechletResponse(new AlexaUtils.SimpleIntentResponse() { cardText = mailboxNotUpgradedMessage }, true)); } // convert time zone string value returned from Outlook API (myOutlookTimeZone) into .NET standard myZone = TimeZoneInfo.FindSystemTimeZoneById(myOutlookTimeZone); // calculate the local time using myZone value to offset UTC myTimeNow = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, myZone); // convert local time to a string to be used in the API query myTimeNowString = myTimeNow.ToString("yyyy-MM-ddTHH:mm"); // make a string that's the end of the local date's day (23:59 / 11:59PM) based on myTimeNow year-month-date myTimeNowEndOfDayString = myTimeNow.ToString("yyyy-MM-ddT") + "23:59"; httpClient.DefaultRequestHeaders.Clear(); httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", session.User.AccessToken); httpClient.DefaultRequestHeaders.Add("Prefer", "Outlook.timezone = \"" + myOutlookTimeZone + "\""); //var httpResponseMessage = // httpClient.GetAsync(unreadOutlookEmailsInInbox).Result; var httpResponseMessage = await httpClient.GetAsync(outlookEventsUri + "&startDateTime=" + myTimeNowString + "&endDAteTime=" + myTimeNowEndOfDayString); if (httpResponseMessage.IsSuccessStatusCode) { //httpResultString = httpResponseMessage.Content.ReadAsStringAsync().Result; httpResultString = await httpResponseMessage.Content.ReadAsStringAsync(); dynamic resultObject = JObject.Parse(httpResultString); unreadCount = resultObject.value.Count; } else if (httpResponseMessage.StatusCode == System.Net.HttpStatusCode.NotFound) { httpResultString = httpResponseMessage.Content.ReadAsStringAsync().Result; dynamic resultObject = JObject.Parse(httpResultString); var errorString = resultObject.error.code; httpResponseMessage.Dispose(); if (errorString == "MailboxNotEnabledForRESTAPI" || errorString == "MailboxNotSupportedForRESTAPI") { return(AlexaUtils.BuildSpeechletResponse(new AlexaUtils.SimpleIntentResponse() { cardText = mailboxNotUpgradedMessage }, true)); } else { return(AlexaUtils.BuildSpeechletResponse(new AlexaUtils.SimpleIntentResponse() { cardText = AlexaConstants.AppErrorMessage }, true)); } } else { httpResponseMessage.Dispose(); return(AlexaUtils.BuildSpeechletResponse(new AlexaUtils.SimpleIntentResponse() { cardText = AlexaConstants.AppErrorMessage }, true)); } string cardBody = ""; string spokenString = ""; string emailMaximumNotice = "We'll read the first " + maxToRead; switch (unreadCount) { case 0: cardBody = "You have no events remaining on today's calendar"; spokenString = cardBody; break; case 1: cardBody = "You have 1 event remaining on today's calendar. "; spokenString = cardBody + CreateSpeechString(httpResultString); break; default: cardBody = "You have " + unreadCount + " events remaining on today's calendar. "; if (unreadCount <= maxToRead) { spokenString = cardBody + CreateSpeechString(httpResultString, unreadCount); } else { spokenString = cardBody + emailMaximumNotice + CreateSpeechString(httpResultString, maxToRead); } break; } httpResponseMessage.Dispose(); AlexaUtils.SimpleIntentResponse simpleIntentResponse = new AlexaUtils.SimpleIntentResponse() { cardText = cardBody, ssmlString = AlexaUtils.AddSpeakTagsAndClean(spokenString), largeImage = "outlook.png", smallImage = "outlook.png", }; return(AlexaUtils.BuildSpeechletResponse(simpleIntentResponse, true)); }