Skip to content

Commit edd6646

Browse files
authored
Support attaching oauth token in userdata on track (#110)
* Support injecting oauth token from userdata on track * remove unused import * adress PR comments, change context name, catch userdata json parting error * Move userdata oauth token checks to the context filter * use JsonBrowser to parse userdata, fix extra tab * add userData oauth to Readme
1 parent ae2b8b3 commit edd6646

File tree

4 files changed

+35
-1
lines changed

4 files changed

+35
-1
lines changed

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,17 @@ plugins:
256256
# skipInitialization: true
257257
```
258258

259+
### Passing an oauth token from your client
260+
Another option to use oauth is by using oauth access tokens that are managed from your client. In this case your
261+
bot/client provides LavaLink with the token to use when playing a track. To do this simply add the oauth access token
262+
to a track's [userData](https://lavalink.dev/api/rest#track) field in a json format when updating the player to
263+
play a track like:
264+
```json
265+
{
266+
"oauth-token": "access token to use"
267+
}
268+
```
269+
259270
## Using a `poToken`
260271
A `poToken`, also known as a "Proof of Origin Token" is a way to identify what requests originate from.
261272
In YouTube's case, this is sent as a JavaScript challenge that browsers must evaluate, and send back the resolved

common/src/main/java/dev/lavalink/youtube/http/YoutubeHttpContextFilter.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import org.slf4j.LoggerFactory;
1515

1616
import static com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity.COMMON;
17+
import static dev.lavalink.youtube.http.YoutubeOauth2Handler.OAUTH_INJECT_CONTEXT_ATTRIBUTE;
1718

1819
public class YoutubeHttpContextFilter extends BaseYoutubeHttpContextFilter {
1920
private static final Logger log = LoggerFactory.getLogger(YoutubeHttpContextFilter.class);
@@ -83,8 +84,14 @@ public void onRequest(HttpClientContext context,
8384
boolean isRequestFromOauthedClient = context.getAttribute(Client.OAUTH_CLIENT_ATTRIBUTE) == Boolean.TRUE;
8485

8586
if (isRequestFromOauthedClient && Client.PLAYER_URL.equals(request.getURI().toString())) {
87+
// Look at the userdata for any provided oauth-token
88+
String oauthToken = context.getAttribute(OAUTH_INJECT_CONTEXT_ATTRIBUTE, String.class);
8689
// only apply the token to /player requests.
87-
oauth2Handler.applyToken(request);
90+
if (oauthToken != null && !oauthToken.isEmpty()) {
91+
oauth2Handler.applyToken(request, oauthToken);
92+
} else {
93+
oauth2Handler.applyToken(request);
94+
}
8895
}
8996
}
9097

common/src/main/java/dev/lavalink/youtube/http/YoutubeOauth2Handler.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ public class YoutubeOauth2Handler {
3535
private static final String CLIENT_SECRET = "SboVhoG9s0rNafixCSGGKXAT";
3636
private static final String SCOPES = "http://gdata.youtube.com https://www.googleapis.com/auth/youtube";
3737
private static final String OAUTH_FETCH_CONTEXT_ATTRIBUTE = "yt-oauth";
38+
public static final String OAUTH_INJECT_CONTEXT_ATTRIBUTE = "yt-oauth-token";
3839

3940
private final HttpInterfaceManager httpInterfaceManager;
4041

@@ -289,6 +290,10 @@ public void applyToken(HttpUriRequest request) {
289290
}
290291
}
291292

293+
public void applyToken(HttpUriRequest request, String token) {
294+
request.setHeader("Authorization", String.format("%s %s", "Bearer", token));
295+
}
296+
292297
private HttpInterface getHttpInterface() {
293298
HttpInterface httpInterface = httpInterfaceManager.getInterface();
294299
httpInterface.getContext().setAttribute(OAUTH_FETCH_CONTEXT_ATTRIBUTE, true);

common/src/main/java/dev/lavalink/youtube/track/YoutubeAudioTrack.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.sedmelluq.discord.lavaplayer.tools.ExceptionTools;
77
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
88
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException.Severity;
9+
import com.sedmelluq.discord.lavaplayer.tools.JsonBrowser;
910
import com.sedmelluq.discord.lavaplayer.tools.io.HttpInterface;
1011
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
1112
import com.sedmelluq.discord.lavaplayer.track.AudioTrackInfo;
@@ -24,6 +25,7 @@
2425
import org.slf4j.Logger;
2526
import org.slf4j.LoggerFactory;
2627

28+
import java.io.IOException;
2729
import java.net.URI;
2830
import java.net.URISyntaxException;
2931
import java.util.Arrays;
@@ -32,6 +34,7 @@
3234
import static com.sedmelluq.discord.lavaplayer.container.Formats.MIME_AUDIO_WEBM;
3335
import static com.sedmelluq.discord.lavaplayer.tools.DataFormatTools.decodeUrlEncodedItems;
3436
import static com.sedmelluq.discord.lavaplayer.tools.Units.CONTENT_LENGTH_UNKNOWN;
37+
import static dev.lavalink.youtube.http.YoutubeOauth2Handler.OAUTH_INJECT_CONTEXT_ATTRIBUTE;
3538

3639
/**
3740
* Audio track that handles processing Youtube videos as audio tracks.
@@ -66,6 +69,14 @@ public void process(LocalAudioTrackExecutor localExecutor) throws Exception {
6669
}
6770

6871
try (HttpInterface httpInterface = sourceManager.getInterface()) {
72+
try {
73+
JsonBrowser userData = JsonBrowser.parse(getUserData().toString());
74+
if (userData.get("oauth-token") != null) {
75+
httpInterface.getContext().setAttribute(OAUTH_INJECT_CONTEXT_ATTRIBUTE, userData.get("oauth-token").text());
76+
}
77+
} catch (IOException e) {
78+
log.debug("Failed to parse token from userData", e);
79+
}
6980
Exception lastException = null;
7081

7182
for (Client client : clients) {

0 commit comments

Comments
 (0)