enable youtube oauth for login-gated tracks
CI/CD / build (push) Successful in 52s
CI/CD / deploy (push) Successful in 1m32s

This commit is contained in:
2026-08-29 18:48:55 +02:00
parent f2185f3398
commit 06c2aac6ef
3 changed files with 59 additions and 0 deletions
+7
View File
@@ -18,6 +18,13 @@ LAVALINK_URI=ws://localhost:2333
# match. Set a strong value — do NOT ship the youshallnotpass default. # match. Set a strong value — do NOT ship the youshallnotpass default.
LAVALINK_PASSWORD=change-me LAVALINK_PASSWORD=change-me
# YouTube OAuth refresh token, used for tracks YouTube refuses to serve without
# a login (age-restricted, "sign in to confirm you're not a bot"). Leave this
# commented out on the first run: Lavalink will log a google.com/device code,
# and after you authorize it logs the refresh token to paste here. Use a
# throwaway Google account. Read by the Lavalink container, not the bot.
#PLUGINS_YOUTUBE_OAUTH_REFRESHTOKEN=
# Path to the catchphrases file (one phrase per line). Optional; defaults to # Path to the catchphrases file (one phrase per line). Optional; defaults to
# catchphrases.txt in the working directory. # catchphrases.txt in the working directory.
CATCHPHRASES_FILE=catchphrases.txt CATCHPHRASES_FILE=catchphrases.txt
+35
View File
@@ -115,6 +115,41 @@ bot image and runs it alongside Lavalink. You only need Docker — no JDK.
The bot connects to Lavalink over the internal Docker network automatically, so The bot connects to Lavalink over the internal Docker network automatically, so
you don't set `LAVALINK_URI` yourself here. you don't set `LAVALINK_URI` yourself here.
## YouTube tracks that need a login
Some tracks — age-restricted ones, and anything YouTube decides to gate behind
"Sign in to confirm you're not a bot" — won't load on the anonymous clients. The
`TV` client can play them, but only with a linked Google account, so
`lavalink/application.yml` enables the plugin's OAuth flow. **Use a throwaway
Google account: Google does ban accounts for this.**
One-time setup:
```bash
docker compose up -d lavalink
docker compose logs -f lavalink
```
The logs print something like:
```
OAUTH INTEGRATION: To give youtube-source access to your account, go to
https://www.google.com/device and enter code XXXX-XXXX
```
Open that page, enter the code, and approve. Lavalink then logs the refresh
token. Put it in `.env`:
```
PLUGINS_YOUTUBE_OAUTH_REFRESHTOKEN=<the token from the logs>
```
and `docker compose up -d lavalink` again. Compose already passes `.env` into the
Lavalink container, and the variable name maps onto
`plugins.youtube.oauth.refreshToken`, so later restarts skip the device flow.
Everything that already worked keeps using the anonymous clients — `TV` is last
in the client list and only gets used when the others are refused.
## Notes ## Notes
- Queue state is kept in memory, so it resets if the bot restarts. - Queue state is kept in memory, so it resets if the bot restarts.
+17
View File
@@ -27,13 +27,30 @@ plugins:
youtube: youtube:
enabled: true enabled: true
allowSearch: true # enables the "ytsearch:" queries the bot falls back to allowSearch: true # enables the "ytsearch:" queries the bot falls back to
# Tried in order; the first one that can load the track wins. TV is last
# because it needs a signed-in account (see oauth below), but it's the only
# client that plays age-restricted / "sign in to confirm you're not a bot"
# tracks, so it's the fallback when the others get rejected.
clients: clients:
- MUSIC - MUSIC
- WEB - WEB
- WEBEMBEDDED - WEBEMBEDDED
- ANDROID_VR - ANDROID_VR
- TV
oauth:
# Links a Google account to the TV client. On first start with no refresh
# token, Lavalink logs a google.com/device code — open it, enter the code,
# and the plugin then logs a refresh token. Put that token in .env as
# PLUGINS_YOUTUBE_OAUTH_REFRESHTOKEN (docker-compose already passes .env
# into the Lavalink container, and Spring binds that name onto this key)
# so the device flow is skipped on every later start.
#
# Use a throwaway Google account. Google does ban accounts for this.
enabled: true
logging: logging:
level: level:
root: INFO root: INFO
lavalink: INFO lavalink: INFO
# Prints the device code and, after you authorize, the refresh token.
dev.lavalink.youtube.http.YoutubeOauth2Handler: INFO