Example #1
0
        public async Task <TokenResponse> ValidateMagicNumber(
            ITurnContext turnContext,
            string text,
            CancellationToken cancellationToken)
        {
            string channelUserId = await _userStateData.GetUserIdFromStateToken(text);

            if (channelUserId == RingoBotHelper.ChannelUserId(turnContext))
            {
                await turnContext.SendActivityAsync(
                    $"Magic Number OK. Ringo is authorized to play Spotify. Ready to rock! 😎",
                    cancellationToken : cancellationToken);

                await _userData.SetTokenValidated(channelUserId, text);

                return(await GetAccessToken(channelUserId));
            }

            _logger.LogWarning($"Invalid Magic Number \"{text}\" for channelUserId {RingoBotHelper.ChannelUserId(turnContext)}");
            await turnContext.SendActivityAsync(
                $"Magic Number is invalid or has expired. Please try again 🤔",
                cancellationToken : cancellationToken);

            return(null);
        }
Example #2
0
        /// <summary>
        /// Changes the station owner to the current conversation From user
        /// </summary>
        public async Task ChangeStationOwner(Station station, ConversationInfo info)
        {
            var    oldOwner    = station.Owner;
            string ownerUserId = RingoBotHelper.ChannelUserId(info);

            // get user
            var ownerUser = await _userData.GetUser(ownerUserId);

            station.Owner = ownerUser;
            AddOwnerToListeners(station, ownerUser, ownerUserId);

            // TODO: if a user station, change the hashtag
            if (station.IsUserStation)
            {
                station.Hashtag = RingoBotHelper.ToHashtag(info.FromName);
            }

            await _stationData.ReplaceStation(station);

            _logger.LogInformation($"RingoBotNet.Services.RingoService.ChangeStationOwner: Station {station} has changed owner from {oldOwner} to {ownerUser}.");
        }
Example #3
0
        public async Task <Station> CreateUserStation(
            ConversationInfo info,
            Album album       = null,
            Playlist playlist = null)
        {
            string name        = album?.Name ?? playlist?.Name;
            string ownerUserId = RingoBotHelper.ChannelUserId(info);

            // get user
            var ownerUser = await _userData.GetUser(ownerUserId);

            string hashtag = RingoBotHelper.ToHashtag(ownerUser.Username);

            // get station
            var stationIds = Station.EncodeIds(info, hashtag, ownerUser.Username);
            var station    = await _stationData.GetStation(stationIds);

            // save station
            if (station == null)
            {
                // new station
                station = new Station(info, hashtag, album, playlist, ownerUser, ownerUser.Username);
                await _stationData.CreateStation(station);
            }
            else
            {
                // update station context and owner
                station.Name     = name;
                station.Owner    = ownerUser;
                station.Album    = album;
                station.Playlist = playlist;
                station.Hashtag  = hashtag;

                AddOwnerToListeners(station, ownerUser, ownerUserId);

                await _stationData.ReplaceStation(station);
            }

            return(station);
        }
Example #4
0
        public async Task <TokenResponse> Authorize(ITurnContext turnContext, CancellationToken cancellationToken)
        {
            var    info   = RingoBotHelper.NormalizedConversationInfo(turnContext);
            string userId = RingoBotHelper.ChannelUserId(turnContext);

            TokenResponse token = await GetAccessToken(userId);

            if (token != null)
            {
                return(token);
            }

            // User is not authorized by Spotify
            if (BotHelper.IsGroup(turnContext))
            {
                // Don't start authorisation dance in Group chat
                await turnContext.SendActivityAsync(
                    $"Before you play or join with Ringo you need to authorize Spotify. DM (direct message) the word `\"{RingoBotCommands.AuthCommand[0]}\"` to @{info.BotName} to continue.",
                    cancellationToken : cancellationToken);

                return(null);
            }

            _logger.LogInformation($"Requesting Spotify Authorization for UserId {userId}");

            await _userData.CreateUserIfNotExists(info);

            // create state token
            string state = $"{RingoBotStatePrefix}{Guid.NewGuid().ToString("N")}".ToLower();

            // validate state token
            if (!RingoBotStateRegex.IsMatch(state))
            {
                throw new InvalidOperationException("Generated state token does not match RingoBotStateRegex");
            }

            // save state token
            await _userStateData.SaveStateToken(userId, state);

            await _userData.SaveStateToken(userId, state);

            // get URL
            string url = UserAccountsService.AuthorizeUrl(
                state,
                new[] { "user-read-playback-state", "user-modify-playback-state" },
                _config["SpotifyApiClientId"],
                _config["SpotifyAuthRedirectUri"]);

            var message = MessageFactory.Attachment(
                new Attachment
            {
                ContentType = HeroCard.ContentType,
                Content     = new HeroCard
                {
                    Text    = "Authorize Ringo bot to use your Spotify account",
                    Buttons = new[]
                    {
                        new CardAction
                        {
                            Title = "Authorize",
                            Text  = "Click to Authorize. (Opens in your browser)",
                            Value = url,
                            Type  = ActionTypes.OpenUrl,
                        },
                    },
                },
            },
                text: "To play music, Ringo needs to be authorized to use your Spotify Account.");

            await turnContext.SendActivityAsync(message, cancellationToken);

            return(null);
        }
Example #5
0
 public async Task ResetAuthorization(ITurnContext turnContext, CancellationToken cancellationToken)
 {
     await _userData.ResetAuthorization(RingoBotHelper.ChannelUserId(turnContext));
 }
Example #6
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);
        }