예제 #1
0
파일: RingoBot3.cs 프로젝트: Ringobot/ringo
 private static async Task SendWelcomeMessageAsync(ITurnContext turnContext, CancellationToken cancellationToken)
 {
     foreach (var member in turnContext.Activity.MembersAdded)
     {
         if (member.Id != turnContext.Activity.Recipient.Id)
         {
             await turnContext.SendActivityAsync(
                 RingoBotMessages.Welcome(RingoBotHelper.NormalizedConversationInfo(turnContext), member.Name),
                 cancellationToken : cancellationToken);
         }
     }
 }
예제 #2
0
        public async Task Auth(ITurnContext turnContext, UserProfile userProfile, string query, CancellationToken cancellationToken)
        {
            var info = RingoBotHelper.NormalizedConversationInfo(turnContext);

            // Don't auth in group chat
            if (BotHelper.IsGroup(turnContext))
            {
                await turnContext.SendActivityAsync(
                    $"Ringo cannot authorize you in Group Chat. DM (direct message) @{info.BotName} instead.",
                    cancellationToken : cancellationToken);

                return;
            }

            // RESET
            if (query.ToLower() == "reset")
            {
                await _authService.ResetAuthorization(turnContext, cancellationToken);

                await turnContext.SendActivityAsync(RingoBotMessages.AuthHasBeenReset(info), cancellationToken);

                return;
            }

            // MAGIC NUMBER
            if (AuthService.RingoBotStateRegex.IsMatch(query))
            {
                var token = await _authService.ValidateMagicNumber(turnContext, query, cancellationToken);

                if (PlayCommand.Contains(userProfile.ResumeAfterAuthorizationWith.command))
                {
                    await Play(
                        turnContext,
                        userProfile,
                        userProfile.ResumeAfterAuthorizationWith.query,
                        cancellationToken,
                        token : token);
                }
                else if (JoinCommand.Contains(userProfile.ResumeAfterAuthorizationWith.command))
                {
                    await Join(
                        turnContext,
                        userProfile,
                        userProfile.ResumeAfterAuthorizationWith.query,
                        cancellationToken,
                        token : token);
                }

                return;
            }

            // AUTH
            var token2 = await _authService.Authorize(turnContext, cancellationToken);

            if (token2 == null)
            {
                // clear resume after auth
                userProfile.ResumeAfterAuthorizationWith = (null, null);
                return;
            }

            await turnContext.SendActivityAsync(
                "Ringo is authorized to play Spotify. Ready to rock! 😎",
                cancellationToken : cancellationToken);
        }
예제 #3
0
        public async Task Play(
            ITurnContext turnContext,
            UserProfile userProfile,
            string query,
            CancellationToken cancellationToken,
            TokenResponse token = null)
        {
            var info = RingoBotHelper.NormalizedConversationInfo(turnContext);

            // User authorised?
            token = token ?? await _authService.Authorize(turnContext, cancellationToken);

            if (token == null)
            {
                // resume after auth
                userProfile.ResumeAfterAuthorizationWith = (PlayCommand[0], query);
                return;
            }

            // Device active?
            if (!await IsDeviceActive(
                    turnContext,
                    token.Token,
                    $"{RingoBotHelper.RingoHandleIfGroupChat(turnContext)}play {query}",
                    cancellationToken))
            {
                return;
            }

            Station station = null;

            if (string.IsNullOrEmpty(query))
            {
                // Play whatever is now playing on Spotify
                station = await PlayNowPlaying(turnContext, token.Token, cancellationToken);

                if (station == null)
                {
                    return;
                }
            }
            else
            {
                // Search for a Playlist and command Spotify to Play it

                // playlist query
                string search = null;

                //if (query.Contains('#'))
                //{
                //    search = query.Substring(0, query.IndexOf('#'));
                //    hashtag = query.Substring(query.IndexOf('#') + 1);
                //}
                //else
                //{
                //    search = query;
                //}

                search = query;

                Playlist[] playlists = await _spotifyService.FindPlaylists(
                    search,
                    token.Token,
                    cancellationToken);

                if (playlists == null || !playlists.Any())
                {
                    await turnContext.SendActivityAsync($"No playlists found!", cancellationToken : cancellationToken);

                    return;
                }

                // TODO: Carousel
                Playlist playlist = playlists[0];

                if (!await IsDeviceActive(
                        turnContext,
                        token.Token,
                        $"{RingoBotHelper.RingoHandleIfGroupChat(turnContext)}play {playlist.Uri}",
                        cancellationToken,
                        playlist: playlist))
                {
                    return;
                }

                // Command Spotify to play the Playlist
                await _spotifyService.PlayPlaylist(
                    playlist.Id,
                    token.Token,
                    cancellationToken);

                if (playlist == null)
                {
                    return;
                }

                // Playlist is playing, now create a station
                station = info.IsGroup
                    ? await _ringoService.CreateConversationStation(info, playlist : playlist)
                    : await _ringoService.CreateUserStation(info, playlist : playlist);
            }

            await turnContext.SendActivityAsync(RingoBotMessages.NowPlayingStation(info, station), cancellationToken);
        }
예제 #4
0
        private async Task <Station> PlayNowPlaying(ITurnContext turnContext, string token, CancellationToken cancellationToken)
        {
            // no query so start / resume station
            // Play whatever the user is currently playing on Spotify

            var info          = RingoBotHelper.NormalizedConversationInfo(turnContext);
            var channelUserId = RingoBotHelper.ChannelUserId(turnContext);

            SpotifyApi.NetCore.CurrentPlaybackContext nowPlaying = await _spotifyService.GetUserNowPlaying(token);

            if (nowPlaying == null || !nowPlaying.IsPlaying || nowPlaying.Context == null)
            {
                if (nowPlaying.IsPlaying && nowPlaying.Context == null)
                {
                    await turnContext.SendActivityAsync(RingoBotMessages.NowPlayingNoContext(info), cancellationToken);
                }
                else if (nowPlaying.IsPlaying && !new[] { "playlist", "album" }.Contains(nowPlaying.Context.Type))
                {
                    await turnContext.SendActivityAsync(
                        RingoBotMessages.NowPlayingNotSupported(info, nowPlaying.Context.Type), cancellationToken);
                }
                else
                {
                    await turnContext.SendActivityAsync(RingoBotMessages.NotPlayingAnything(info), cancellationToken);
                }

                return(null);
            }

            await _spotifyService.TurnOffShuffleRepeat(token, nowPlaying);

            Station station = null;

            switch (nowPlaying.Context.Type)
            {
            case "playlist":
                var playlist = await _spotifyService.GetPlaylist(token, nowPlaying.Context.Uri);

                station = info.IsGroup
                        ? await _ringoService.CreateConversationStation(info, playlist : playlist)
                        : await _ringoService.CreateUserStation(info, playlist : playlist);

                break;

            case "album":
                var album = await _spotifyService.GetAlbum(token, nowPlaying.Context.Uri);

                station = info.IsGroup
                        ? await _ringoService.CreateConversationStation(info, album : album)
                        : await _ringoService.CreateUserStation(info, album : album);

                break;

            default:
                await turnContext.SendActivityAsync(
                    RingoBotMessages.NowPlayingNotSupported(info, nowPlaying.Context.Type), cancellationToken);

                break;
            }

            return(station);
        }
예제 #5
0
        public async Task Join(
            ITurnContext turnContext,
            UserProfile userProfile,
            string query,
            CancellationToken cancellationToken,
            TokenResponse token = null)
        {
            ConversationInfo info = RingoBotHelper.NormalizedConversationInfo(turnContext);

            if (string.IsNullOrEmpty(query) || (!query.StartsWith('#') && !query.StartsWith('@')))
            {
                // must specify #channel or @username in DM to join a Station
                await turnContext.SendActivityAsync(
                    RingoBotMessages.JoinWhat(),
                    cancellationToken : cancellationToken);

                return;
            }

            Station station = null;

            //if (string.IsNullOrEmpty(query))
            //{
            //    // just `join` in group chat: Play the current channel station
            //    station = await _ringoService.GetChannelStation(info);
            //}
            //else if (query.StartsWith('@'))
            if (query.StartsWith('@'))
            {
                // user station
                station = await _ringoService.GetUserStation(info, query.Substring(1));
            }
            else if (query.StartsWith('#'))
            {
                // could either be a channel station or hashtag station
                station = await _ringoService.GetChannelStation(info, query.Substring(1));
            }

            //if (station == null && query.StartsWith('@'))
            //{
            //    await CreateAndJoinUserStation(turnContext, query, cancellationToken);
            //    return;
            //}

            if (station == null)
            {
                await turnContext.SendActivityAsync(
                    RingoBotMessages.CouldNotFindStation(info, query),
                    cancellationToken : cancellationToken);

                return;
            }

            TokenResponse stationToken = await _authService.GetAccessToken(station.Owner.Id);

            // get user and their token
            token = token ?? await _authService.Authorize(turnContext, cancellationToken);

            if (token == null)
            {
                // resume after auth
                userProfile.ResumeAfterAuthorizationWith = (JoinCommand[0], query);
                return;
            }

            if (!await IsDeviceActive(
                    turnContext,
                    token.Token,
                    $"{RingoBotHelper.RingoHandleIfGroupChat(turnContext)}join {query}",
                    cancellationToken,
                    station.Playlist))
            {
                return;
            }

            // Join
            try
            {
                if (await _spotifyService.JoinPlaylist(
                        query,
                        token.Token,
                        station,
                        stationToken.Token,
                        cancellationToken))
                {
                    await turnContext.SendActivityAsync(
                        RingoBotMessages.UserHasJoined(info, station),
                        cancellationToken : cancellationToken);
                }
                else
                {
                    // station no longer playing. Start it up!
                    //await turnContext.SendActivityAsync(
                    //    RingoBotMessages.StationNoLongerPlaying(info, station),
                    //    cancellationToken: cancellationToken);

                    _logger.LogInformation($"RingobotNet.RingoBotCommands: User {station.Owner.Username} is no longer playing station \"{station.Name}\". Starting station up again with {info.FromName} as owner.");

                    switch (station.SpotifyContextType)
                    {
                    case Station.SpotifyContextTypeAlbum:
                        await _spotifyService.PlayAlbum(station.SpotifyUri, token.Token, cancellationToken);

                        break;

                    case Station.SpotifyContextTypePlaylist:
                        await _spotifyService.PlayPlaylist(station.SpotifyUri, token.Token, cancellationToken);

                        break;

                    default:
                        throw new NotSupportedException($"{station.SpotifyContextType} is not a supported SpotifyContextType");
                    }

                    await _ringoService.ChangeStationOwner(station, info);

                    await turnContext.SendActivityAsync(RingoBotMessages.NowPlayingStation(info, station), cancellationToken);
                }
            }
            catch (SpotifyApi.NetCore.SpotifyApiErrorException ex)
            {
                await turnContext.SendActivityAsync(RingoBotMessages.SpotifyError(info, ex, $"join {query}"), cancellationToken : cancellationToken);
            }
        }