-
-
Save marco79cgn/79a6a265d978dc22cc2a12058b24e02b to your computer and use it in GitHub Desktop.
let spotifyCredentials | |
let widget = await createWidget() | |
Script.setWidget(widget) | |
Script.complete() | |
async function createWidget() { | |
let widget = new ListWidget() | |
let spotifyIcon = await getImage("spotify-icon.png") | |
widget.backgroundColor = new Color("1e2040") | |
// load spotify credentials from iCloud Drive | |
spotifyCredentials = await loadSpotifyCredentials() | |
if(spotifyCredentials != null) { | |
widget.url = "spotify://" | |
let nowPlaying = await loadNowPlaying() | |
if(nowPlaying != null) { | |
widget.setPadding(20,12, 8, 8) | |
let cleanTitle = nowPlaying.item.name.split(" (")[0] | |
cleanTitle = cleanTitle.split(" - ")[0] | |
const artist = nowPlaying.item.artists[0].name | |
// console.log("Now Playing: " + cleanTitle + " - " + artist) | |
// cover art | |
const coverUrl = nowPlaying.item.album.images[0].url | |
let coverImage = await loadImage(coverUrl) | |
let row = widget.addStack() | |
let stack = row.addStack() | |
stack.layoutHorizontally() | |
stack.size = new Size(105,105) | |
let cover = stack.addImage(coverImage) | |
cover.cornerRadius = 6 | |
cover.borderColor = new Color("#1DB954") | |
cover.borderWidth = 3 | |
stack.addSpacer(10) | |
let stack2 = row.addStack() | |
stack2.layoutVertically() | |
let spotifyIconImage = stack2.addImage(spotifyIcon) | |
stack2.addSpacer(10) | |
let shuffleIcon = await getImage("shuffle-icon.png") | |
let shuffleIconImage = stack2.addImage(shuffleIcon) | |
if(nowPlaying.shuffle_state == true) { | |
shuffleIconImage.imageOpacity = 1 | |
} else { | |
shuffleIconImage.imageOpacity = 0.3 | |
} | |
let repeatIcon = await getImage("repeat-icon.png") | |
stack2.addSpacer(10) | |
let repeatIconImage = stack2.addImage(repeatIcon) | |
if(nowPlaying.repeat_state === "off") { | |
repeatIconImage.imageOpacity = 0.3 | |
} else { | |
repeatIconImage.imageOpacity = 1.0 | |
} | |
// add title and artist | |
let titleTxt = widget.addText(cleanTitle) | |
titleTxt.font = Font.semiboldSystemFont(11) | |
titleTxt.textColor = Color.white() | |
titleTxt.lineLimit = 1 | |
widget.addSpacer(2) | |
let artistTxt = widget.addText(artist) | |
artistTxt.font = Font.boldSystemFont(11) | |
artistTxt.textColor = new Color("#1DB954") | |
artistTxt.lineLimit = 1 | |
widget.addSpacer() | |
} else { | |
// Spotify playback stopped | |
let spotifyImage = widget.addImage(spotifyIcon) | |
spotifyImage.imageSize = new Size(25,25) | |
spotifyImage.rightAlignImage() | |
widget.addSpacer(10) | |
let offIcon = await getImage("offline-icon.png") | |
let offImage = widget.addImage(offIcon) | |
offImage.imageSize = new Size(50,50) | |
offImage.centerAlignImage() | |
widget.addSpacer(5) | |
let playbackText = widget.addText("Playback stopped") | |
playbackText.font = Font.semiboldSystemFont(11) | |
playbackText.textColor = Color.white() | |
playbackText.centerAlignText() | |
widget.addSpacer() | |
} | |
} else { | |
// no credentials found | |
let spotifyImage = widget.addImage(spotifyIcon) | |
spotifyImage.imageSize = new Size(25,25) | |
spotifyImage.rightAlignImage() | |
widget.addSpacer(10) | |
console.log("Could not find Spotify credentials!") | |
let ts = widget.addText("Couldn't find your spotify credentials in iCloud Drive. \n\n Please tap me for setup instructions.") | |
ts.textColor = Color.white() | |
ts.font = Font.boldSystemFont(11) | |
ts.leftAlignText() | |
widget.url = "https://gist.github.com/marco79cgn/79a6a265d978dc22cc2a12058b24e02b#gistcomment-3469230" | |
} | |
return widget | |
} | |
// get nowPlaying via Spotify Web API | |
async function loadNowPlaying() { | |
const req = new Request("https://api.spotify.com/v1/me/player") | |
req.headers = { "Authorization": "Bearer " + spotifyCredentials.accessToken, "Content-Type": "application/json" } | |
let npResult = await req.load() | |
if (req.response.statusCode == 401) { | |
// access token expired, trying to refresh | |
let success = await refreshSpotifyAccessToken() | |
if(success) { | |
return await loadNowPlaying() | |
} else { | |
return null | |
} | |
} else if (req.response.statusCode == 204) { | |
// no playback | |
return null | |
} else if (req.response.statusCode == 200) { | |
npResult = JSON.parse(npResult.toRawString()) | |
} | |
return npResult | |
} | |
// load and validate spotify credentials from iCloud Drive | |
async function loadSpotifyCredentials() { | |
let fm = FileManager.iCloud() | |
let dir = fm.documentsDirectory() | |
let path = fm.joinPath(dir, "spotify-credentials.json") | |
let spotifyCredentials | |
if(fm.fileExists(path)) { | |
await fm.downloadFileFromiCloud(path) | |
let spotifyCredentialsFile = Data.fromFile(path) | |
spotifyCredentials = JSON.parse(spotifyCredentialsFile.toRawString()) | |
if (isNotEmpty(spotifyCredentials.clientId) | |
&& isNotEmpty(spotifyCredentials.clientSecret) | |
&& isNotEmpty(spotifyCredentials.accessToken) | |
&& isNotEmpty(spotifyCredentials.refreshToken)) { | |
return spotifyCredentials | |
} | |
} | |
return null | |
} | |
// helper function to check not empty strings | |
function isNotEmpty(stringToCheck) { | |
if (stringToCheck != null && stringToCheck.length > 0) { | |
return true | |
} else { | |
return false | |
} | |
} | |
// The Spotify access token expired so we get a new one by using the refresh token (Authorization Flow) | |
async function refreshSpotifyAccessToken() { | |
if(spotifyCredentials != null) { | |
let req = new Request("https://accounts.spotify.com/api/token") | |
req.method = "POST" | |
req.headers = { "Content-Type": "application/x-www-form-urlencoded" } | |
req.body = "grant_type=refresh_token&refresh_token=" + spotifyCredentials.refreshToken + "&client_id=" + spotifyCredentials.clientId + "&client_secret=" + spotifyCredentials.clientSecret | |
let result = await req.loadJSON() | |
spotifyCredentials.accessToken = result.access_token | |
let fm = FileManager.iCloud() | |
let dir = fm.documentsDirectory() | |
let path = fm.joinPath(dir, "spotify-credentials.json") | |
fm.write(path, Data.fromString(JSON.stringify(spotifyCredentials))) | |
return true | |
} | |
return false | |
} | |
// get images from local filestore or download them once | |
async function getImage(image) { | |
let fm = FileManager.local() | |
let dir = fm.documentsDirectory() | |
let path = fm.joinPath(dir, image) | |
if(fm.fileExists(path)) { | |
return fm.readImage(path) | |
} else { | |
// download once | |
let imageUrl | |
switch (image) { | |
case 'spotify-icon.png': | |
imageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/1/19/Spotify_logo_without_text.svg/240px-Spotify_logo_without_text.svg.png" | |
break | |
case 'shuffle-icon.png': | |
imageUrl = "https://www.iconsdb.com/icons/download/white/shuffle-128.png" | |
break | |
case 'repeat-icon.png': | |
imageUrl = "https://www.iconsdb.com/icons/download/white/repeat-128.png" | |
break | |
case 'offline-icon.png': | |
imageUrl = "http://cdn.1001freedownloads.com/vector/thumb/98366/clarity-shutdown-icon.png" | |
break | |
default: | |
console.log(`Sorry, couldn't find ${image}.`); | |
} | |
let iconImage = await loadImage(imageUrl) | |
fm.writeImage(path, iconImage) | |
return iconImage | |
} | |
} | |
// helper function to download an image from a given url | |
async function loadImage(imgUrl) { | |
const req = new Request(imgUrl) | |
return await req.loadImage() | |
} |
This worked for me before, but now when the shortcut attempts to get authorization, the web page shows
INVALID_CLIENT: Invalid redirect URI
, and the shortcut returnsInvalid grant. Your code is probably expired! Please try again.
I've tried deleting both the script and the shortcut, but the problem persists.
Edit: Never mind. I must have edited the redirect URI in the app I created in Spotify.
Please go to your Spotify developer dashboard, choose your client, edit settings and enter https://example.com/callback as redirect URI. Save it. It should work afterwards.
Thanks, yes, that was it.
Thanks for the cool widget!
How do change the background to transparent?
Hey get the message that it can’t find my credentials? Also when I run the Spotify with workflow it says my client I’d and secret are invalid
I have a couple of weeks modifying your code, to create my own version of the widget, but I would like to select 'play',pause','next','previous' as buttons with functions in the widget, only I don't know how to add them. I already add a function(play), but I don't know how to add more than one.
I'll attach more screenshots and a video later so you can see the problem and if you like I can send you the code directly to see if you can make the addition of these.By the way, I hope it wasn't wrong for me to take your code without asking to modify it.
Excuse my English, I speak Spanish, but I understand English a little bit.
Hey. Does your widget "update" work as you planned it? I am really interested in a version giving me the possibility to play/pause (etc.). Thanks!
I have a couple of weeks modifying your code, to create my own version of the widget, but I would like to select 'play',pause','next','previous' as buttons with functions in the widget, only I don't know how to add them. I already add a function(play), but I don't know how to add more than one.
I'll attach more screenshots and a video later so you can see the problem and if you like I can send you the code directly to see if you can make the addition of these.By the way, I hope it wasn't wrong for me to take your code without asking to modify it.
Excuse my English, I speak Spanish, but I understand English a little bit.
How do you start the function „play“?
So how do you add a button to a widget?
Could you share your code so I can analyse it to maybe help?
I would like to see the next/ back button and play/pause button on the small widget! Is this possible?
See what I wrote under „Optionally“:
https://gist.github.com/marco79cgn/79a6a265d978dc22cc2a12058b24e02b#gistcomment-3470482got it! but look at the size of the spotify icons
I have tested all the solutions according to the author's reply to you, but it still doesn't work, how did you solve it.
I have a couple of weeks modifying your code, to create my own version of the widget, but I would like to select 'play',pause','next','previous' as buttons with functions in the widget, only I don't know how to add them. I already add a function(play), but I don't know how to add more than one.
I'll attach more screenshots and a video later so you can see the problem and if you like I can send you the code directly to see if you can make the addition of these.
By the way, I hope it wasn't wrong for me to take your code without asking to modify it.
Excuse my English, I speak Spanish, but I understand English a little bit.How do you start the function „play“? So how do you add a button to a widget? Could you share your code so I can analyse it to maybe help?
Can you share that widget with the play and pause buttons?
Sorry to bother if you don't have these widgets now, but if you do can you share them?
Thanks in advance!
Whoever made it, I am very grateful for making the music playback widget from Spotify
But this only has a little problem with the playback being slow to update so there is a delay when the next new song is played. This widget doesn't immediately change it to the song that is currently playing but was delayed for some time, and it changes by itself. Hopefully it will be improved in the future. once again I am very grateful.
Why doesn't Spotify directly have a playback widget, only a playlist widget? I don't know, maybe there will be one later, adios thank you.
The usual method used by Spotify Downloader Playlists to download music files is to extract audio from Spotify's servers or use their official APIs. These programs submit requests to access particular songs, playlists, or albums in order to simulate user interactions. After being recovered, the music is transformed into downloadable file types, such as FLAC or MP3.
The actual method used by download Spotify++ for mac files is to extract audio from Spotify servers or use Spotify official apls.
Follow the prompts and select Non-Commercial for the type of integration that we're creating pwgbarracks (if you are creating a non-commercial app, that is).
This statement suggests that the method employed to download Spotify++ for ios involves either extracting audio directly from Spotify servers or utilizing official Spotify applications. The term "Spotify++" typically refers to a modified version of the Spotify app that may offer additional features not available in the official release. However, it's important to note that using modified versions of apps may violate terms of service and could potentially lead to account issues. Always ensure that your actions are in compliance with the app's policies and legal guidelines.
The method of Using Spotify++ for iOS involves accessing Spotify servers or official apps to download modified features. While this version may offer extra functionalities, it's important to note potential violations of terms of service and account risks. Always ensure compliance with app policies and legal guidelines.
You're going to need to be using Node version 10x or higher for this to work. The reason for that is because the code that talks to Spotify relies on the URLSearchParams global.
Installation and Setup
Clone or fork my repo over at https://github.com/stemmlerjs/stemmlerjs-graph to follow along.
Run the following commands to clone, install, and set up the project.
git clone git@github.com:stemmlerjs/stemmlerjs-graph.git
cd stemmlerjs-graph
npm install
mv .env.template .env higgs domino
Creating a Spotify Developers Account
Go to the Spotify Developers Dashboard and sign up for an account.
When you're all signed up, you'll get to the Spotify Developers Dashboard that shows your applications. Click "Create An App".
Spotify Downloader Playlists disrupt traditional listening methods, enabling users to download curated playlists effortlessly. This innovation challenges conventional streaming by offering offline access to personalized collections, reshaping how users consume music on the platform. Its convenience and versatility redefine the music listening experience.
Thanks for sharing. This statement explains how to get Spotify++ on iOS. It says you can either get music from Spotify directly or use official Spotify apps. "Spotify++" means a changed version of Spotify with extra features. But, remember, using changed apps might break the rules, and your account could have problems. Make sure you follow the app's rules to stay safe.
Gratitude for sharing. This assertion makes sense of how for get Spotify++ on iOS. It says you can either get music from Spotify straightforwardly or utilize official Spotify applications. "Spotify++" signifies a changed form of Spotify with additional highlights. Be that as it may, recollect, utilizing changed applications could disrupt the guidelines, and your record could have issues. Ensure you keep the application's guidelines to remain safe.
I was also looking for the same kind of widget for my spotify mod apk. I searched a lot of threads and forums for this but most of them were not working properly but this one is just awesome.
This innovation challenges conventional streaming, i was also looking for the same kind of widget on blacktoon.
The method of Using Spotify++ for iOS involves accessing Spotify servers or official apps to download modified features. While this version may offer extra functionalities, it's important to note potential violations of terms of service and account risks. Always ensure compliance with app policies and legal guidelines.
Yes, speak well. and for the android version, i found this one very well. That's working 100% and have all the Spotify Premium Apk features.
I also agree with the comments of "walderhonx"
As well as, i also check and found it is working well and has all the guidelines regarding Spotify Premium Apk music.
Hey dear, no doubt method of Using Spotify++ for iOS involves accessing Spotify servers to download modified features. While this version may offer also extra functionalities. Anyhow, you can easily download it.
This worked for me before, but now when the shortcut attempts to get authorization, the web page shows
INVALID_CLIENT: Invalid redirect URI
, and the shortcut returnsInvalid grant. Your code is probably expired! Please try again.
I've tried deleting both the script and the shortcut, but the problem persists.
Edit: Never mind. I must have edited the redirect URI in the app I created in Spotify.