--[[
HOW TO MAKE THIS WORK ON YOUR ACCOUNT:
> go to spotify.com
> open inspect element
> go to "Application"
> search for "sp_dc" and copy the ID
> DO NOT SHARE THIS SP_DC TOKEN WITH ANYBODY.
> now grab this script's link and make it a run command
> run it like this: "r/(name of the command you made)/(your token)"
]]
--[[
ERROR SOLUTIONS:
404 Error (Not Found): make sure your spotify is open
Attempt to concatenate string with nil: make sure you provided a third run argument
]]
local CLICK_COOLDOWN = 10 -- cooldown on the amount of times a player can click (in seconds)
script.Name = "make me listen to a spotify song"
-- creating
local main_part = Instance.new("Part")
main_part.Name = "Main"
main_part.Anchored = true
main_part.Locked = true
main_part.Position = Vector3.new(0, 2.5, 15)
main_part.Size = Vector3.new(5, 5, 0)
--main_part.Transparency = 1
main_part.Color = Color3.fromRGB(27, 42, 53)
main_part.Parent = script
local surface_gui = Instance.new("SurfaceGui")
surface_gui.PixelsPerStud = 60
surface_gui.SizingMode = Enum.SurfaceGuiSizingMode.PixelsPerStud
surface_gui.Parent = main_part
local background = Instance.new("Frame")
background.Name = "Background"
background.BackgroundTransparency = 1
--background.BackgroundColor3 = Color3.fromRGB(27, 42, 53)
background.BorderSizePixel = 0
background.Size = UDim2.fromScale(1, 1)
background.Parent = surface_gui
local shuffle_background = Instance.new("Frame")
shuffle_background.Name = "ShuffleBackground"
shuffle_background.BackgroundTransparency = 1
shuffle_background.Position = UDim2.fromScale(0, 1/3)
shuffle_background.Size = UDim2.fromScale(1, 1/3)
shuffle_background.Parent = background
local recently_queued do
recently_queued = Instance.new("TextLabel")
recently_queued.Name = "RecentlyQueued"
recently_queued.AnchorPoint = Vector2.new(0, 1)
recently_queued.BackgroundTransparency = 1
recently_queued.Position = UDim2.fromScale(0, 1)
recently_queued.Size = UDim2.fromScale(1, 0.075)
recently_queued.FontFace = Font.new("rbxasset://fonts/families/Inconsolata.json", Enum.FontWeight.Regular, Enum.FontStyle.Normal)
recently_queued.TextColor3 = Color3.new(1,1,1)
recently_queued.Text = "Recently queued: None"
recently_queued.TextWrapped = true
recently_queued.Parent = shuffle_background
local cooldown = Instance.new("TextLabel")
cooldown.Name = "Cooldown"
cooldown.BackgroundTransparency = 1
cooldown.Size = UDim2.fromScale(1, 0.075)
cooldown.FontFace = Font.new("rbxasset://fonts/families/Inconsolata.json", Enum.FontWeight.Regular, Enum.FontStyle.Normal)
cooldown.TextColor3 = Color3.new(1,1,1)
cooldown.Text = `({CLICK_COOLDOWN} second cooldown per player)`
cooldown.TextWrapped = true
cooldown.Parent = shuffle_background
end
local description = Instance.new("TextLabel")
description.Name = "Description"
description.BackgroundTransparency = 1
description.Size = UDim2.fromScale(1, 1/3) -- 1/3 = 0.333...
description.TextColor3 = Color3.new(1,1,1)
description.FontFace = Font.new("rbxasset://fonts/families/Inconsolata.json", Enum.FontWeight.Regular, Enum.FontStyle.Normal)
description.Text = "Add a RANDOM SONG (yes, ANY song) to my queue (please don't):"
description.TextSize = 14
description.TextWrapped = true
description.Parent = background
local shuffle_click do
local shuffle_part = Instance.new("Part")
shuffle_part.Name = "ShufflePart"
shuffle_part.Anchored = true
shuffle_part.Size = Vector3.new(3.767, 1.266, 0.05)
shuffle_part.Position = Vector3.new(0, 2.5, 14.975)
shuffle_part.Transparency = 1
shuffle_part.Parent = main_part
shuffle_click = Instance.new("ClickDetector")
shuffle_click.Parent = shuffle_part
local shuffle_button = Instance.new("TextButton")
shuffle_button.Name = "Shuffle"
shuffle_button.BackgroundColor3 = Color3.new(0, 1, 0)
shuffle_button.AnchorPoint = Vector2.new(.5, .5)
shuffle_button.Position = UDim2.fromScale(.5, .5)
shuffle_button.Size = UDim2.fromScale(0.75, 0.75)
shuffle_button.TextColor3 = Color3.new(1,1,1)
shuffle_button.Text = "Yes, I hate you. Add a song to the queue."
shuffle_button.FontFace = Font.new("rbxasset://fonts/families/Inconsolata.json", Enum.FontWeight.Bold, Enum.FontStyle.Italic)
shuffle_button.TextStrokeTransparency = 0
shuffle_button.TextSize = 14
shuffle_button.TextWrapped = true
shuffle_button.Parent = shuffle_background
end
local currently_playing = Instance.new("TextLabel")
currently_playing.Name = "CurrentlyPlaying"
currently_playing.BackgroundTransparency = 1
currently_playing.Position = UDim2.fromScale(0, 2/3) -- 2/3 = 0.666...
currently_playing.Size = UDim2.fromScale(1, 1/3)
currently_playing.TextColor3 = Color3.new(1,1,1)
currently_playing.Text = "Currently playing:\nNone\nAlbum: None\nArtist: None"
currently_playing.FontFace = Font.new("rbxasset://fonts/families/Inconsolata.json", Enum.FontWeight.Regular, Enum.FontStyle.Italic)
currently_playing.TextSize = 14
currently_playing.TextWrapped = true
currently_playing.Parent = background
local queue_background do
local queue_part = Instance.new("Part")
queue_part.Name = "Queue"
queue_part.Color = Color3.fromRGB(27, 42, 53)
queue_part.Size = Vector3.new(3.5, 4.5, 0)
queue_part.Position = Vector3.new(-4.75, 2.75, 15)
queue_part.Anchored = true
queue_part.Parent = script
local queue_gui = Instance.new("SurfaceGui")
queue_gui.PixelsPerStud = 60
queue_gui.SizingMode = Enum.SurfaceGuiSizingMode.PixelsPerStud
queue_gui.Parent = queue_part
queue_background = Instance.new("ScrollingFrame")
queue_background.Name = "QueueBackground"
queue_background.BackgroundTransparency = 1
queue_background.Position = UDim2.fromScale(0, 0)
queue_background.Size = UDim2.fromScale(1, 1)
queue_background.AutomaticCanvasSize = Enum.AutomaticSize.XY
queue_background.VerticalScrollBarInset = Enum.ScrollBarInset.ScrollBar
queue_background.ScrollBarThickness = 6
queue_background.BorderSizePixel = 0
queue_background.CanvasSize = UDim2.fromScale(0, 0)
queue_background.Parent = queue_gui
local grid_layout = Instance.new("UIGridLayout")
grid_layout.CellPadding = UDim2.fromScale(0, 0)
grid_layout.CellSize = UDim2.fromScale(1, 0.2)
grid_layout.SortOrder = Enum.SortOrder.LayoutOrder
grid_layout.Parent = queue_background
local description = Instance.new("TextLabel")
description.Name = "Description"
description.BackgroundTransparency = 1
-- grid_layout controls position and size
description.LayoutOrder = -2
description.FontFace = Font.new("rbxasset://fonts/families/Inconsolata.json", Enum.FontWeight.Regular, Enum.FontStyle.Italic)
description.Text = "(Songs in bold and italics are songs added into the queue via this script)"
description.TextColor3 = Color3.new(1, 1, 1)
description.TextWrapped = true
description.TextSize = 14
description.Parent = queue_background
local description_padding = Instance.new("UIPadding")
description_padding.PaddingLeft = UDim.new(.05, 0)
description_padding.PaddingRight = UDim.new(.05, 0)
description_padding.Parent = description
local top_song = Instance.new("TextLabel")
top_song.Name = "TopSong"
top_song.BackgroundTransparency = 1
-- grid_layout controls position and size
top_song.LayoutOrder = -1
top_song.FontFace = Font.new("rbxasset://fonts/families/Inconsolata.json", Enum.FontWeight.Bold, Enum.FontStyle.Normal)
top_song.Text = "Songs in queue:"
top_song.TextColor3 = Color3.new(1, 1, 1)
top_song.TextWrapped = true
top_song.TextSize = 20
top_song.Parent = queue_background
end
-- main
local http_service = game:GetService("HttpService")
local token = http_service:JSONDecode(http_service:GetAsync("https://open.spotify.com/get_access_token?reason=transport&productType=web_player", false, {
["App-platform"] = "WebPlayer",
["cookie"] = "sp_dc=" .. ...
}))
local access_token = token.accessToken
local recently_added_tracks = {}
local function get_random_song()
local random_wildcards = {
"pop",
"dance pop",
"rap",
"pop rap",
"post teen pop",
"rock",
"latin",
"hip hop",
"trap",
"modern rock",
"edm",
"pop rock",
"tropical house",
"reggaeton",
"melodic rap",
"electropop",
"latin pop",
"classic rock",
"mellow gold",
"album rock",
"southern hip hop",
"soft rock",
"post grunge",
"indie pop",
"alternative metal",
"permanent wave",
"r and b",
"contemporary country",
"neo mellow",
"uk pop",
"canadian pop",
"electro house",
"urban contemporary",
"tropical",
"alternative rock",
"hard rock",
"folk rock",
"nu metal",
"k pop",
"country",
"country road",
"grupera",
"trap latino",
"rock en espanol",
"adult standards",
"viral pop",
"alternative r and b",
"atl hip hop",
"german hip hop",
"gangster rap",
"regional mexican",
"indietronica",
"indie rock",
"big room",
"latin hip hop",
"underground hip hop",
"art rock",
"banda",
"dance rock",
"europop",
"roots rock",
"new wave pop",
"soul",
"chamber pop",
"country rock",
"french hip hop",
"indie folk",
"modern alternative rock",
"emo rap",
"mexican pop",
"indie poptimism",
"house",
"norteno",
"art pop",
"canadian hip hop",
"latin alternative",
"latin rock",
"sertanejo universitario",
"reggaeton flow",
"pop urbaine",
"toronto rap",
"garage rock",
"stomp and holler",
"hip pop",
"spanish pop",
"latin arena pop",
"boy band",
"psychedelic rock",
"lo fi beats",
"pop punk",
"metal",
"pop edm",
"neo soul",
"singer songwriter",
"funk",
"folk",
"progressive house",
"funk carioca",
"ranchera",
"new wave",
}
local wildcard_selected = random_wildcards[math.random(1, #random_wildcards)]
local track
for i = 1, 50 do
local response = http_service:RequestAsync({
Url = `https://api.spotify.com/v1/search?q=genre:%22{wildcard_selected}%22&type=track&market=GB&offset={math.random(1, 200)}`,
Method = "GET",
Headers = {
["authorization"] = "Bearer " .. access_token;
};
})
local song_info = http_service:JSONDecode(response.Body)["tracks"]["items"]
local track_info = song_info[math.random(1, 20)]
track = track_info
break
end
return true, track
end
local function get_currently_playing_song()
local response = http_service:RequestAsync({
Url = "https://api.spotify.com/v1/me/player/currently-playing",
Method = "GET",
Headers = {
["Content-Type"] = "application/json",
["Authorization"] = "Bearer " .. access_token;
};
})
local status = response.StatusCode
if status == 200 then
local data = http_service:JSONDecode(response.Body).item
return true, data
else
if not response or response.Body == "" then
local success
repeat
task.wait(1)
success, response = get_currently_playing_song()
until success
return success, response
else
warn(response)
return false, http_service:JSONDecode(response.Body).error.message
end
end
end
local function update_playing()
local success, data = get_currently_playing_song()
local song = data.name
local album = data.album.name
local artist = data.artists[1].name
local text_to_show = "Currently listening to:"
text_to_show ..= "\n" .. song
text_to_show ..= "\nAlbum: " .. album
text_to_show ..= "\nArtist: " .. artist
currently_playing.Text = text_to_show
end
local function update_queue(uri)
local response = http_service:PostAsync(
`https://api.spotify.com/v1/me/player/queue?uri={uri}`,
http_service:JSONEncode({}),
Enum.HttpContentType.ApplicationJson,
false,
{
["Authorization"] = "Bearer " .. access_token;
}
)
local status = response.StatusCode
return true
end
local function generate_text(text : string, parent : Instance)
local label = Instance.new("TextLabel")
label.BackgroundTransparency = 1
label.FontFace = Font.new("rbxasset://fonts/families/Inconsolata.json", Enum.FontWeight.Regular, Enum.FontStyle.Normal)
label.TextColor3 = Color3.new(1,1,1)
label.Text = text
label.TextWrapped = true
label.Parent = parent
return label
end
local function read_and_update_queue_gui()
local response = http_service:RequestAsync({
Url = "https://api.spotify.com/v1/me/player/queue",
Method = "GET",
Headers = {
["Content-Type"] = "application/json",
["Authorization"] = "Bearer " .. access_token;
};
})
local status = response.StatusCode
if status == 200 then
local body = http_service:JSONDecode(response.Body)
local queue = body.queue
for _, track in queue do
--warn(track.name)
local label = generate_text(track.name, queue_background)
label.Name = "QueuedTrack"
if table.find(recently_added_tracks, label.Text) then
label.FontFace = Font.new("rbxasset://fonts/families/Inconsolata.json", Enum.FontWeight.SemiBold, Enum.FontStyle.Italic)
end
label.TextSize = 16
label:SetAttribute("New", true)
end
for _, obj in queue_background:GetChildren() do
if obj:IsA("UIGridLayout") then
continue
end
if obj.Name == "TopSong" or obj.Name == "Description" then
continue
end
if obj:GetAttribute("New") then
obj:SetAttribute("New", nil)
continue
end
local found_track = false
for _, track in queue do
local name = track.name
if name == track then
found_track = true
break
end
end
if found_track then
continue
end
obj:Destroy()
end
else
return http_service:JSONDecode(response.Body).error.message
end
end
local function add_to_queue()
local success, random_song = get_random_song()
local song_id = random_song.uri
update_queue(song_id)
local song_name = random_song.name
table.insert(recently_added_tracks, song_name)
read_and_update_queue_gui()
return song_name
end
local function play_sound(id)
local sound = Instance.new("Sound")
sound.SoundId = id
sound.PlayOnRemove = true
sound.Volume = 2
sound.Parent = shuffle_click.Parent
sound:Destroy()
end
local player_cooldowns = {}
shuffle_click.MouseClick:Connect(function(plr)
local cooldown_found = player_cooldowns[plr.Name]
if cooldown_found then
if tick() - cooldown_found > CLICK_COOLDOWN then
player_cooldowns[plr.Name] = nil
else
return
end
end
player_cooldowns[plr.Name] = tick()
play_sound("rbxasset://sounds/button.wav")
print(`{plr.Name} just clicked the button.`)
local song_added = add_to_queue()
recently_queued.Text = `Recently queued: {song_added}`
print(`Song called '{song_added}' has been added to your queue!`)
end)
while true do
update_playing()
read_and_update_queue_gui()
task.wait(1)
end