Пример #1
0
        // 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);
        }
Пример #2
0
        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));
        }
Пример #3
0
        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));
        }
Пример #4
0
        // 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));
        }
Пример #5
0
        // 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);
        }
Пример #6
0
        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));
        }
Пример #7
0
        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));
        }