TwitchSongRequests
Integrate Twitch channel point rewards directly with a user's Spotify player.
Configure a channel point reward to accept a Spotify song URL, and enqueue
the song in the user's current playing session.
Inspiration
This project was inspired by Kaije, because their
Twitch channel has a channel point reward for requesting a song on Spotify. On that
fateful day, I requested multiple songs in quick succession, and they told me to hold
off on requesting songs because they have to stop working on art in order to manually
copy the Spotify URIs I was sending, in order to queue the songs in their Spotify
player. Between jobs, I coded up an initial proof of concept and the rest is history.
For Users
How do I sign up?
- Navigate to the site: https://twitchsongrequests-production.up.railway.app
- Authorize the service with Twitch
- Authorize the service with Spotify
- If it worked, you should see a
Subscribe
and Revoke Access
button
- Click
Subscribe
. If successful, you should see the UI update accordingly
- Submit an onboarding request on this GitHub project, and I will manually allowlist your Spotify account to let you access the service (this is a limitation on Spotify, not on me)
- Wait for me to manually onboard you and then you're done! Now start using it!
From Spotify
We appreciate your interest and efforts in using Spotify's open platform to innovate and build interesting integrations. However, after reviewing we found that your app does not comply with our terms and conditions for the following reasons:
The product or service is integrated with streams or content from another service. The application is integrated with other services (e.g. Twitch) in a way that is prohibited according to section III in our Developer Policy .
As much as I would love to make this more broadly accessible, looks like it goes against their ToS. This means that there will be limited access to the service, since I have to manually allowlist users. If you really want to use it, please sign up via the above steps.
How do I use it?
- Open Spotify on your computer
- Navigate to your Twitch channel
- Create a channel point reward with
TwitchSongRequests
somewhere in the title, that accepts text input
- Start playing music on Spotify (the service needs an "active" player to work)
- Find your favorite song on Spotify, copy the URI and use it as input when redeeming
- If your Spotify player has queued the song, you're good!
- If your player did not queue the song, make sure you copied the URL correctly, and use the right Channel Point reward
- If you are pretty sure you didn't mess anything up, make an issue here
- If you want to allow your viewers to submit song requests for explicit songs, you have to opt in to this by updating your preferences
- If you want to limit the length of the songs chatters can submit, specify the max song length in seconds in your preferences. Any value less than or equal to zero means any song length is allowed
Demo
Who can use it?
In order to use custom channel point rewards, you must be an affiliate or partner
streamer.
Last I checked, in order to queue songs into a player, the user must have Spotify
Premium.
How do I stop using it?
- Navigate to the site: https://twitchsongrequests-production.up.railway.app
- If you are fully authenticated, you should see a
Revoke Access
button
- Click it. This will revoke access to Twitch, which means the application won't receive new channel point redemptions
- Navigate to your Spotify account to revoke access for the service. This can't be done by the service, because they don't expose an API for it. See here for why.
- You're done!
Troubleshooting
TBD
How does it work?
The TwitchSongRequests service will authorize to your Twitch account so that the
service can listen for channel point redemption events from your channel. Once the
service receives an event, it will process that event in order to queue the given
Spotify song into your connected Spotify player.
The service requires access to read Twitch channel point redemptions, and also needs
access to modify a user's Spotify playback state. The Twitch access is needed in order
to allow the service to subscribe to the events, and the Spotify access is required to
queue the song in a user's active player.
The site uses cookies to track whether a user is authenticated or not.
Why not YouTube?
Well, the YouTube API doesn't let you queue videos outside of an iframe player,
which means I would need to embed the player inside my website. Which, I'm not
necessariliy opposed to doing, but that wasn't the original point of this.
If you want this feature, react and comment on this issue
Support the Project
I'm paying to host this service completely out of pocket. If you would like to help
pitch in for the cost of hosting (it's not that much right now), please let me know
and I'll set up a way to contribute in that way.
For Developers
Running the project
Run the project locally:
go run main.go
# or
go build .
./twitchsongrequests
Required variables
TODO - project env vars
Testing
Unit testing
go test ./... -cover -v -timeout 10s
Set up Twitch CLI
Use the Twitch CLI for local development.
Set up an EventSub subscription for testing end-to-end
Note: the Twitch CLI mock server does not support EventSub, so it can not be
used for local testing of creating subscriptions. We must use the real API
Authenticate with the Twitch CLI:
twitch token
Then, use the app access token from the above command to authentication.
Get your own user payload, and note the user ID from the response.
twitch api get /users -q login=YourTwitchUsername
The response will look something like this:
{
"data": [
{
"broadcaster_type": "affiliate",
"created_at": "2015-11-03T23:03:04Z",
"description": "A description about the user",
"display_name": "SaxyPandaBear",
"id": "1234567890",
"login": "saxypandabear",
"offline_image_url": "https://some-image1.png",
"profile_image_url": "https://some-image2.png",
"type": "",
"view_count": 1337
}
]
}
Jot down the id
in the JSON response body
Subscribe to the channel point reward redemption event, replacing the USER_ID
,
TOKEN
, CLIENT_ID
, CALLBACK_URL
, and SUB_SECRET
with your own values.
curl -X POST https://api.twitch.tv/helix/eventsub/subscriptions \
-H 'Authorization: Bearer $TOKEN' \
-H 'Client-Id: $CLIENT_ID' \
-H 'Content-Type: application/json' \
-d '{"type": "channel.channel_points_custom_reward_redemption.add", "version": "1", "condition": {"broadcaster_user_id": "$USER_ID"}, "transport": {"method": "webhook", "callback":"$CALLBACK_URL", "secret": "$SUB_SECRET"}}'
Make a note of the id
value from the response.
Verify that the subscription was made successfully:
twitch api get /eventsub/subscriptions -q user_id=$USER_ID
The response will look like:
{
"data": [
{
"condition": {
"broadcaster_user_id": "1234567890",
"reward_id": ""
},
"cost": 0,
"created_at": "2023-01-29T04:23:21.008351071Z",
"id": "abc-123-def-456",
"status": "webhook_callback_verification_pending",
"transport": {
"callback": "https://this-service/endpoint",
"method": "webhook"
},
"type": "channel.channel_points_custom_reward_redemption.add",
"version": "1"
}
],
"pagination": {
"cursor": ""
},
"total": 1
}
Run local API server to handle callback
Start the server locally
export TWITCH_CLIENT_ID=$CLIENT_ID
go run main.go
Make sure that the server is up
curl localhost:8080/
Create and send a test webhook payload to the local server
twitch event trigger add-redemption -s $SUB_SECRET -F http://localhost:8080/callback
Check the server logs to confirm that the event was received and processed.
2022/09/05 10:49:46 verified signature for subscription
2022/09/05 10:49:46 52f644c8-33da-4a30-bc81-beccb4cb678a Test Reward from CLI
Cleanup
After testing, clean up the EventSub subscription:
twitch api get /eventsub/subscriptions
# jot down the relevant EventSub subscription ID
curl -X DELETE https://api.twitch.tv/helix/eventsub/subscriptions?id=$SUB_ID -H 'Authorization: Bearer $TOKEN' -H 'Client-Id: $CLIENT_ID'
Deploying
This service is deployed directly to Railway, via the supplied Dockerfile at the root of the repo.