Closed addreeh closed 10 months ago
I mean i am trying with the auth example:
// Copyright (c) 2020 hayribakici. All rights reserved. Use of this source code
// is governed by a BSD-style license that can be found in the LICENSE file.
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:spotify/spotify.dart';
final _scopes = [
AuthorizationScope.playlist.modifyPrivate,
AuthorizationScope.playlist.modifyPublic,
AuthorizationScope.library.read,
AuthorizationScope.library.modify,
AuthorizationScope.connect.readPlaybackState,
AuthorizationScope.connect.modifyPlaybackState,
AuthorizationScope.listen.readRecentlyPlayed,
AuthorizationScope.follow.read
];
void main() async {
var keyMap = await _getApiKeys();
var credentials = SpotifyApiCredentials(keyMap.key, keyMap.value);
var spotify = await _getUserAuthenticatedSpotifyApi(credentials);
if (spotify == null) {
exit(0);
}
await _user(spotify);
await _currentlyPlaying(spotify);
await _devices(spotify);
await _followingArtists(spotify);
await _shuffle(true, spotify);
await _shuffle(false, spotify);
await _playlists(spotify);
await _savedTracks(spotify);
await _recentlyPlayed(spotify);
await _getShow(spotify);
await _listShows(spotify);
await _savedShows(spotify);
await _saveAndRemoveShow(spotify);
await _getEpisode(spotify);
await _listEpisodes(spotify);
await _savedEpisodes(spotify);
await _saveAndRemoveEpisode(spotify);
await _clearPlaylist(spotify);
await _reorderItemsInPlaylist(spotify);
await _replaceItemsInPlaylist(spotify);
// exit(0);
}
Future<MapEntry<String, String>> _getApiKeys() async {
return MapEntry(
"c71ca5e3735c44d19f10161b88a5923c", "c38cedd20e444629999786810c522790");
}
Future<SpotifyApi?> _getUserAuthenticatedSpotifyApi(
SpotifyApiCredentials credentials) async {
var redirect = "http://127.0.0.1:5500";
var grant = SpotifyApi.authorizationCodeGrant(credentials);
var authUri =
grant.getAuthorizationUrl(Uri.parse(redirect!), scopes: _scopes);
print(
'Please paste this url \n\n$authUri\n\nto your browser and enter the redirected url:');
var redirectUrl;
var userInput =
"http://127.0.0.1:5500/?code=AQCiRXc7Jjlww5sS3b9q9NXQnlRLIiRqN7LwCH9xgzOC1AEZCOOHf1uBNnRI8_BZP0hl1qwTM9cvoaYoN47o2PU6puY6Ur31OqWeoOtJYXCxcWsstBxPNgyj1t5il_ibqrATu18Tf0dvbAm7lwqlQ7r8y4SxGZ4Xx6ouT-kDtV4aLFLlijAvXdWhhA6t7NLjqWrtYDAhq24ptNLp6kLZBSPjUjh8RXmlhwCdiJlhQgyGVxukS65gfkpP39XD68mcwmnf-uh8Wt7sS7WpkdPxXojdz4fe-FcBXVWZWChy3IDfZtCcYCsTyayA0VWFYVWSkC98wjqaMlIpf0gkLF68bASoERj3-Qp_zOy4H66dbAEit7P_gvafOZLfN4337gBHEp85VRJl2OzvREqe-BvxHWSTfCvO9DwlXdBepKH5UTehFYgls5HU2_RQzMbgb27GRdb6gm-WpHaQYDgxu3zJ2-FRJ8SCPrAw";
if (userInput == null || (redirectUrl = Uri.tryParse(userInput)) == null) {
print('Invalid redirect url');
return null;
}
print(redirectUrl.queryParameters);
var client =
await grant.handleAuthorizationResponse(redirectUrl.queryParameters);
return SpotifyApi.fromClient(client);
}
Future<void> _currentlyPlaying(SpotifyApi spotify) async =>
await spotify.player.currentlyPlaying().then((PlaybackState? a) {
if (a?.item == null) {
print('Nothing currently playing.');
return;
}
print('Currently playing: ${a?.item?.name}');
}).catchError(_prettyPrintError);
Future<void> _user(SpotifyApi spotify) async {
print('User\'s data:');
await spotify.me.get().then((user) {
var buffer = StringBuffer();
buffer.write('id:');
buffer.writeln(user.id);
buffer.write('name:');
buffer.writeln(user.displayName);
buffer.write('email:');
buffer.writeln(user.email);
buffer.write('type:');
buffer.writeln(user.type);
buffer.write('birthdate:');
buffer.writeln(user.birthdate);
buffer.write('country:');
buffer.writeln(user.country);
buffer.write('followers:');
buffer.writeln(user.followers?.href);
buffer.write('country:');
buffer.writeln(user.country);
print(buffer.toString());
});
}
Future<void> _devices(SpotifyApi spotify) async =>
await spotify.player.devices().then((Iterable<Device>? devices) {
if (devices == null || devices.isEmpty) {
print('No devices currently playing.');
return;
}
print('Listing ${devices.length} available devices:');
print(devices.map((device) => device.name).join(', '));
}).catchError(_prettyPrintError);
Future<void> _followingArtists(SpotifyApi spotify) async {
var cursorPage = spotify.me.following(FollowingType.artist);
await cursorPage.first().then((cursorPage) {
print(cursorPage.items!.map((artist) => artist.name).join(', '));
}).catchError((ex) => _prettyPrintError(ex));
}
Future<void> _shuffle(bool state, SpotifyApi spotify) async {
await spotify.player.shuffle(state).then((player) {
print('Shuffle: ${player?.isShuffling}');
}).catchError((ex) => _prettyPrintError(ex));
}
Future<void> _playlists(SpotifyApi spotify) async {
await spotify.playlists.me.all(1).then((playlists) {
var lists = playlists.map((playlist) => playlist.name).join(', ');
print('Playlists: $lists');
}).catchError(_prettyPrintError);
}
Future<void> _savedTracks(SpotifyApi spotify) async {
var stream = spotify.tracks.me.saved.stream();
print('Saved Tracks:\n');
await for (final page in stream) {
var items = page.items?.map((e) => e.track?.name).join(', ');
print(items);
}
}
Future<void> _recentlyPlayed(SpotifyApi spotify) async {
var stream = spotify.me.recentlyPlayed().stream();
await for (final page in stream) {
var items = page.items?.map((e) => e.track?.name).join(', ');
print(items);
}
}
Future<void> _getShow(SpotifyApi spotify) async {
var response = await spotify.shows.get('3kbLJJLzRGsAKESODPSbiB');
print(response.name);
}
Future<void> _listShows(SpotifyApi spotify) async {
var response = await spotify.shows.list(['3kbLJJLzRGsAKESODPSbiB']);
for (final show in response) {
print(show.name);
}
}
Future<void> _savedShows(SpotifyApi spotify) async {
print('Users saved shows');
var response = spotify.me.savedShows().stream();
await for (final page in response) {
var names = page.items?.map((e) => e.name).join(', ');
print(names);
}
}
Future<void> _saveAndRemoveShow(SpotifyApi spotify) async {
print('Saving show with id 4XPl3uEEL9hvqMkoZrzbx5');
await spotify.me.saveShows(['4XPl3uEEL9hvqMkoZrzbx5']);
var saved = await spotify.me.containsSavedShows(['4XPl3uEEL9hvqMkoZrzbx5']);
print('Checking is 4XPl3uEEL9hvqMkoZrzbx5 is in saved shows...');
print(saved);
print('Removing show wish id 4XPl3uEEL9hvqMkoZrzbx5');
await spotify.me.removeShows(['4XPl3uEEL9hvqMkoZrzbx5']);
print('Checking is 4XPl3uEEL9hvqMkoZrzbx5 is in saved shows...');
saved = await spotify.me.containsSavedShows(['4XPl3uEEL9hvqMkoZrzbx5']);
print(saved);
}
Future<void> _getEpisode(SpotifyApi spotify) async {
print('\nRetriving Information about episode with id 2TkVS48EgJwFUMiH8UwqGL');
var episode = await spotify.episodes.get('2TkVS48EgJwFUMiH8UwqGL');
print('${episode.name} - ${episode.show?.name}');
}
Future<void> _listEpisodes(SpotifyApi spotify) async {
print(
'\nRetriving Information about episodes 2TkVS48EgJwFUMiH8UwqGL, 4Bje2xtE4VxqO2HO1PQdsG');
var episodes = await spotify.episodes
.list(['2TkVS48EgJwFUMiH8UwqGL', '4Bje2xtE4VxqO2HO1PQdsG']);
for (final episode in episodes) {
print('${episode.name} - ${episode.show?.name}');
}
}
Future<void> _savedEpisodes(SpotifyApi spotify) async {
print('Users saved episodes:');
var episodes = spotify.me.savedEpisodes().stream();
await for (final page in episodes) {
var names = page.items?.map((e) => e.name).join(', ');
print(names);
}
}
Future<void> _saveAndRemoveEpisode(spotify) async {
print('Saving episode with id 4Bje2xtE4VxqO2HO1PQdsG');
await spotify.me.saveShows(['4Bje2xtE4VxqO2HO1PQdsG']);
var saved = await spotify.me.containsSavedShows(['4Bje2xtE4VxqO2HO1PQdsG']);
print('Checking is 4Bje2xtE4VxqO2HO1PQdsG is in saved shows...');
print(saved);
print('Removing show wish id 4Bje2xtE4VxqO2HO1PQdsG');
await spotify.me.removeShows(['4Bje2xtE4VxqO2HO1PQdsG']);
print('Checking is 4Bje2xtE4VxqO2HO1PQdsG is in saved shows...');
saved = await spotify.me.containsSavedShows(['4Bje2xtE4VxqO2HO1PQdsG']);
print(saved);
}
Future<Playlist> _createPrivatePlaylist(SpotifyApi spotify) async {
var userId = (await spotify.me.get()).id;
var name = 'My awesome playlist';
print('Creating dummy Playlist with name \'$name\'');
var playlist =
await spotify.playlists.createPlaylist(userId ?? '', name, public: false);
await spotify.playlists.addTracks([
'spotify:track:34HKskUook8LY2JFy6e4Ob',
'spotify:track:0F0MA0ns8oXwGw66B2BSXm'
], playlist.id ?? '');
return playlist;
}
Future<void> _removePrivatePlaylist(
SpotifyApi spotify, String playlistId) async {
print('Removing playlist $playlistId');
await spotify.playlists.unfollowPlaylist(playlistId);
}
Future<void> _clearPlaylist(SpotifyApi spotify) async {
print('Clearing Playlist');
var playlist = await _createPrivatePlaylist(spotify);
var tracks = await _getPlaylistTracks(spotify, playlist.id ?? '');
print('Tracks before: ${tracks.map((e) => e.name)}');
await spotify.playlists.clear(playlist.id ?? '');
tracks = await _getPlaylistTracks(spotify, playlist.id ?? '');
print('Tracks after: ${tracks.map((e) => e.name)}');
await _removePrivatePlaylist(spotify, playlist.id ?? '');
}
Future<void> _reorderItemsInPlaylist(SpotifyApi spotify) async {
print('Reordering Playlist');
var playlist = await _createPrivatePlaylist(spotify);
var playlistId = playlist.id ?? '';
var tracks = await _getPlaylistTracks(spotify, playlistId);
print('Tracks before: ${tracks.map((e) => e.name)}');
// reorders the first element to the end of the playlist
await spotify.playlists
.reorder(playlistId, rangeStart: 0, insertBefore: tracks.length);
tracks = await _getPlaylistTracks(spotify, playlistId);
print('Tracks after: ${tracks.map((e) => e.name)}');
await _removePrivatePlaylist(spotify, playlist.id ?? '');
}
Future<void> _replaceItemsInPlaylist(SpotifyApi spotify) async {
print('Replacing Playlist');
var playlist = await _createPrivatePlaylist(spotify);
var playlistId = playlist.id ?? '';
var tracks = await _getPlaylistTracks(spotify, playlistId);
print('Tracks before: ${tracks.map((e) => e.name)}');
// replaces the whole playlist with only the first item
await spotify.playlists.replace(playlistId, [tracks.first.uri ?? '']);
tracks = await _getPlaylistTracks(spotify, playlistId);
print('Tracks after: ${tracks.map((e) => e.name)}');
await _removePrivatePlaylist(spotify, playlist.id ?? '');
}
Future<Iterable<Track>> _getPlaylistTracks(
SpotifyApi spotify, String playlistId) async {
var tracksPage = spotify.playlists.getTracksByPlaylistId(playlistId);
return (await tracksPage.first()).items ?? [];
}
FutureOr<Null> _prettyPrintError(Object error) {
if (error is SpotifyException) {
print('${error.status} : ${error.message}');
} else {
print(error);
}
}
But i am always getting errors like these:
Performing hot restart...
Restarted application in 3.161ms.
I/flutter ( 6474): Please paste this url
I/flutter ( 6474):
I/flutter ( 6474): https://accounts.spotify.com/authorize?response_type=code&client_id=c71ca5e3735c44d19f10161b88a5923c&redirect_uri=http%3A%2F%2F127.0.0.1%3A5500&code_challenge=-sO1L_O2SkqC59iUbIveyHdOihgcNd64Kenxr2pouKE&code_challenge_method=S256&scope=playlist-modify-private+playlist-modify-public+user-library-read+user-library-modify+user-read-playback-state+user-modify-playback-state+user-read-recently-played+user-follow-read
I/flutter ( 6474):
I/flutter ( 6474): to your browser and enter the redirected url:
I/flutter ( 6474): {code: AQCiRXc7Jjlww5sS3b9q9NXQnlRLIiRqN7LwCH9xgzOC1AEZCOOHf1uBNnRI8_BZP0hl1qwTM9cvoaYoN47o2PU6puY6Ur31OqWeoOtJYXCxcWsstBxPNgyj1t5il_ibqrATu18Tf0dvbAm7lwqlQ7r8y4SxGZ4Xx6ouT-kDtV4aLFLlijAvXdWhhA6t7NLjqWrtYDAhq24ptNLp6kLZBSPjUjh8RXmlhwCdiJlhQgyGVxukS65gfkpP39XD68mcwmnf-uh8Wt7sS7WpkdPxXojdz4fe-FcBXVWZWChy3IDfZtCcYCsTyayA0VWFYVWSkC98wjqaMlIpf0gkLF68bASoERj3-Qp_zOy4H66dbAEit7P_gvafOZLfN4337gBHEp85VRJl2OzvREqe-BvxHWSTfCvO9DwlXdBepKH5UTehFYgls5HU2_RQzMbgb27GRdb6gm-WpHaQYDgxu3zJ2-FRJ8SCPrAw}
E/flutter ( 6474): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: OAuth authorization error (invalid_grant): code_verifier was incorrect.
E/flutter ( 6474): #0 _handleErrorResponse (package:oauth2/src/handle_access_token_response.dart:155:3)
E/flutter ( 6474): #1 handleAccessTokenResponse (package:oauth2/src/handle_access_token_response.dart:41:7)
E/flutter ( 6474): #2 AuthorizationCodeGrant._handleAuthorizationCode (package:oauth2/src/authorization_code_grant.dart:320:23)
E/flutter ( 6474): <asynchronous suspension>
E/flutter ( 6474): #3 _getUserAuthenticatedSpotifyApi (package:flutter_application_1/main.dart:79:7)
E/flutter ( 6474): <asynchronous suspension>
E/flutter ( 6474): #4 main (package:flutter_application_1/main.dart:25:17)
E/flutter ( 6474): <asynchronous suspension>
E/flutter ( 6474):
I will take a look at this this week.
for future issues, if you have to paste long code, I suggest using the <details></details>
toggle:
<details>
<summary>Expand</summary>
* Bullet
* Points
* and stuff
</details>
moreover, you could also just reference the file (or mention the file name), if it is in this library. No need to paste the whole file.
And finally, you can use code highlighting with
```dart
class Main {
}
resulting in
```dart
class Main {
}
MMM oh thanks for the tips, so is there are not a way to log in with spotify yet?
I tried this and I get the code from the url:
But i can not get login or getting user info:
I/flutter ( 4809): Server running on localhost:3000
D/EGL_emulation( 4809): app_time_stats: avg=27514.51ms min=294.25ms max=54734.78ms count=2
I/flutter ( 4809): https://accounts.spotify.com/authorize?response_type=code&client_id=c71ca5e3735c44d19f10161b88a5923c&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fcallback&code_challenge=Y2U241dEItpM4HATVQRMr0FWHbHQ_0iFEGu3Cwn9eu8&code_challenge_method=S256&scope=playlist-modify-private+playlist-modify-public+user-library-read+user-library-modify+user-read-playback-state+user-modify-playback-state+user-read-recently-played+user-follow-read
D/EGL_emulation( 4809): app_time_stats: avg=1614.50ms min=1614.50ms max=1614.50ms count=1
I/flutter ( 4809): Response URI: http://localhost:3000/callback?code=AQB7k2GEUkfM_QueAFky-r7mb-9wysVFqHDkTa4w4cQAJouabDPEnZ1ZQ9PYOBICivUkdnq7x8PLEmIXCUcK96E5WcVkJfxh2nMm_-Kn71yUzBO6vZS923lMcsJUziC7d3hrEUAMEy1iApOD30zxbi-F5WPRNXeDFPvPCClJ97WUoUva2pVNxulto8Ji6g3Ve23IQqCjA0LgWRRufGV3e38Qbscs283hzW5zU9uy_oRy9dOaBTRVJl_0iFNTHmqpNpAAZs5x9rkp5B6jPIQyVTYveSQhG23l4ry88_-WsgoVVWdW3tLGTzG6D8U0Tbnj0LLRsSIjlBIyy-ZeGnClHm_XzoMcrHI_yuUDN5I581CEs65mP-B7uNlCoWxakOxcYbxVQapjqwYuCk1iA6PY3CYnxZBzkeKnRV-DiQQQ0QywUWpl-1MDu6YbH42_8OUVX6BCQHeRWJhKqKCB_eJrjXkIIR9NeBFyJYH77D-mqEcs
I/flutter ( 4809): Instance of 'SpotifyApi'
I/flutter ( 4809): Error handling request: Bad state: The authorization URL has not yet been generated.
I am not sure, how localhost
is available on mobile devices. I think you have to give spotify a real responseUrl
(e.g. your github profile page).
(I am not 100% sure of this, though. Maybe @rinukkusu knows more about this)
Just to have more inputs about this, does that mean you guys are thinking of adding support to other login flows available in the spotify sdk?
I tried this and I get the code from the url:
My Code But i can not get login or getting user info:
I/flutter ( 4809): Server running on localhost:3000 D/EGL_emulation( 4809): app_time_stats: avg=27514.51ms min=294.25ms max=54734.78ms count=2 I/flutter ( 4809): https://accounts.spotify.com/authorize?response_type=code&client_id=c71ca5e3735c44d19f10161b88a5923c&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fcallback&code_challenge=Y2U241dEItpM4HATVQRMr0FWHbHQ_0iFEGu3Cwn9eu8&code_challenge_method=S256&scope=playlist-modify-private+playlist-modify-public+user-library-read+user-library-modify+user-read-playback-state+user-modify-playback-state+user-read-recently-played+user-follow-read D/EGL_emulation( 4809): app_time_stats: avg=1614.50ms min=1614.50ms max=1614.50ms count=1 I/flutter ( 4809): Response URI: http://localhost:3000/callback?code=AQB7k2GEUkfM_QueAFky-r7mb-9wysVFqHDkTa4w4cQAJouabDPEnZ1ZQ9PYOBICivUkdnq7x8PLEmIXCUcK96E5WcVkJfxh2nMm_-Kn71yUzBO6vZS923lMcsJUziC7d3hrEUAMEy1iApOD30zxbi-F5WPRNXeDFPvPCClJ97WUoUva2pVNxulto8Ji6g3Ve23IQqCjA0LgWRRufGV3e38Qbscs283hzW5zU9uy_oRy9dOaBTRVJl_0iFNTHmqpNpAAZs5x9rkp5B6jPIQyVTYveSQhG23l4ry88_-WsgoVVWdW3tLGTzG6D8U0Tbnj0LLRsSIjlBIyy-ZeGnClHm_XzoMcrHI_yuUDN5I581CEs65mP-B7uNlCoWxakOxcYbxVQapjqwYuCk1iA6PY3CYnxZBzkeKnRV-DiQQQ0QywUWpl-1MDu6YbH42_8OUVX6BCQHeRWJhKqKCB_eJrjXkIIR9NeBFyJYH77D-mqEcs I/flutter ( 4809): Instance of 'SpotifyApi' I/flutter ( 4809): Error handling request: Bad state: The authorization URL has not yet been generated.
I am still working to do this code work, with this code I get the code that the response uri of spotify returns:
I/flutter ( 4809): Response URI: http://localhost:3000/callback?code=AQB7k2GEUkfM_QueAFky-r7mb-9wysVFqHDkTa4w4cQAJouabDPEnZ1ZQ9PYOBICivUkdnq7x8PLEmIXCUcK96E5WcVkJfxh2nMm_-Kn71yUzBO6vZS923lMcsJUziC7d3hrEUAMEy1iApOD30zxbi-F5WPRNXeDFPvPCClJ97WUoUva2pVNxulto8Ji6g3Ve23IQqCjA0LgWRRufGV3e38Qbscs283hzW5zU9uy_oRy9dOaBTRVJl_0iFNTHmqpNpAAZs5x9rkp5B6jPIQyVTYveSQhG23l4ry88_-WsgoVVWdW3tLGTzG6D8U0Tbnj0LLRsSIjlBIyy-ZeGnClHm_XzoMcrHI_yuUDN5I581CEs65mP-B7uNlCoWxakOxcYbxVQapjqwYuCk1iA6PY3CYnxZBzkeKnRV-DiQQQ0QywUWpl-1MDu6YbH42_8OUVX6BCQHeRWJhKqKCB_eJrjXkIIR9NeBFyJYH77D-mqEcs
but I dont know what I need to log in with my account, do I need anything else than this code?
@ahmedo100 since spotify is not supporting any other login flows other than the one mentioned in their documentation, I would say, no.
@ahmedo100 since spotify is not supporting any other login flows other than the one mentioned in their documentation, I would say, no.
But is there anyway to log in with flutter? I have searching a lot and i didnt found a clear way to do this.
This maybe a hack but what you could do is to include the spotify android and ios sdk into your flutter app and call the android login activity (for android) from your flutter app. Since you are then getting some sort of client secret from spotify, you could bind it in your flutter app. I haven't tried this and I don't know if that is even possible, that is the first thing that came into my mind when I lookend into the android sdk documentation. If anyone knows more, that would be great.
This maybe a hack but what you could do is to include the spotify android and ios sdk into your flutter app and call the android login activity (for android) from your flutter app. Since you are then getting some sort of client secret from spotify, you could bind it in your flutter app. I haven't tried this and I don't know if that is even possible, that is the first thing that came into my mind when I lookend into the android sdk documentation. If anyone knows more, that would be great.
And for flutter web? My idea is to host the app on firebase ...
Since flutter web is a webapp and thus using the spotify web-API, there is no way other than the supported OAuth flows.
In order to be logged in, you need a real response
uri, since localhost
propably won't work. You could use for example your github profile page as a response uri and paste it back to the terminal. This worked for me.
Is there any way to log in with an spotify account easily? I mean for example clicking a button and redirecting the user to the spotify log in or something like that?