Skip to content

Commit b4290ec

Browse files
committed
api/vimeo: use bearer, update headers, better error handling
1 parent 773ed02 commit b4290ec

File tree

1 file changed

+62
-6
lines changed

1 file changed

+62
-6
lines changed

api/src/processing/services/vimeo.js

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,46 @@ const resolutionMatch = {
1515
"426": 240
1616
}
1717

18-
const requestApiInfo = (videoId, password) => {
18+
const genericHeaders = {
19+
Accept: 'application/vnd.vimeo.*+json; version=3.4.10',
20+
'User-Agent': 'Vimeo/11.13.0 (com.vimeo; build:250619.102023.0; iOS 18.5.0) Alamofire/5.9.0 VimeoNetworking/5.0.0',
21+
Authorization: 'Basic MTMxNzViY2Y0NDE0YTQ5YzhjZTc0YmU0NjVjNDQxYzNkYWVjOWRlOTpHKzRvMmgzVUh4UkxjdU5FRW80cDNDbDhDWGR5dVJLNUJZZ055dHBHTTB4V1VzaG41bEx1a2hiN0NWYWNUcldSSW53dzRUdFRYZlJEZmFoTTArOTBUZkJHS3R4V2llYU04Qnl1bERSWWxUdXRidjNqR2J4SHFpVmtFSUcyRktuQw==',
22+
'Accept-Language': 'en-US,en;q=0.9',
23+
}
24+
25+
let bearer = '';
26+
27+
const getBearer = async (refresh = false) => {
28+
if (bearer && !refresh) return bearer;
29+
30+
const oauthResponse = await fetch(
31+
`https://api.vimeo.com/oauth/authorize/client?sizes=216,288,300,360,640,960,1280,1920&cdm_type=fairplay`,
32+
{
33+
method: 'POST',
34+
body: JSON.stringify({
35+
scope: 'public private purchased create edit delete interact upload stats',
36+
grant_type: 'client_credentials',
37+
// device_identifier is a long ass base64 string of seemingly
38+
// random data, but it doesn't seem to be required, so we just omit it lol
39+
device_identifier: '',
40+
}),
41+
headers: {
42+
...genericHeaders,
43+
'Content-Type': 'application/json',
44+
}
45+
}
46+
)
47+
.then(a => a.json())
48+
.catch(() => {});
49+
50+
if (!oauthResponse || !oauthResponse.access_token) {
51+
return;
52+
}
53+
54+
return bearer = oauthResponse.access_token;
55+
}
56+
57+
const requestApiInfo = (bearerToken, videoId, password) => {
1958
if (password) {
2059
videoId += `:${password}`
2160
}
@@ -24,10 +63,8 @@ const requestApiInfo = (videoId, password) => {
2463
`https://api.vimeo.com/videos/${videoId}`,
2564
{
2665
headers: {
27-
Accept: 'application/vnd.vimeo.*+json; version=3.4.2',
28-
'User-Agent': 'Vimeo/10.19.0 (com.vimeo; build:101900.57.0; iOS 17.5.1) Alamofire/5.9.0 VimeoNetworking/5.0.0',
29-
Authorization: 'Basic MTMxNzViY2Y0NDE0YTQ5YzhjZTc0YmU0NjVjNDQxYzNkYWVjOWRlOTpHKzRvMmgzVUh4UkxjdU5FRW80cDNDbDhDWGR5dVJLNUJZZ055dHBHTTB4V1VzaG41bEx1a2hiN0NWYWNUcldSSW53dzRUdFRYZlJEZmFoTTArOTBUZkJHS3R4V2llYU04Qnl1bERSWWxUdXRidjNqR2J4SHFpVmtFSUcyRktuQw==',
30-
'Accept-Language': 'en'
66+
...genericHeaders,
67+
Authorization: `Bearer ${bearerToken}`,
3168
}
3269
}
3370
)
@@ -151,9 +188,28 @@ export default async function(obj) {
151188
if (quality < 240) quality = 240;
152189
if (!quality || obj.isAudioOnly) quality = 9000;
153190

154-
const info = await requestApiInfo(obj.id, obj.password);
191+
const bearerToken = await getBearer();
192+
if (!bearerToken) {
193+
return { error: "fetch.fail" };
194+
}
195+
196+
let info = await requestApiInfo(bearerToken, obj.id, obj.password);
155197
let response;
156198

199+
// auth error, try to refresh the token
200+
if (info?.error_code === 8003) {
201+
const newBearer = await getBearer(true);
202+
if (!newBearer) {
203+
return { error: "fetch.fail" };
204+
}
205+
info = await requestApiInfo(newBearer, obj.id, obj.password);
206+
}
207+
208+
// if there's still no info, then return a generic error
209+
if (!info || info.error_code) {
210+
return { error: "fetch.empty" };
211+
}
212+
157213
if (obj.isAudioOnly) {
158214
response = await getHLS(info.config_url, { ...obj, quality });
159215
}

0 commit comments

Comments
 (0)