-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathworker.js
129 lines (112 loc) · 3.81 KB
/
worker.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
addEventListener("fetch", (event) => {
var url = new URL(event.request.url);
// Simple routing
var route = url.pathname.replaceAll("/", "");
switch (route) {
case "hello":
event.respondWith(handleHello(event.request));
break;
case "authorize":
event.respondWith(handleAuthorization(event.request));
break;
case "callback":
event.respondWith(handleCallback(event.request));
break;
case "get-now-playing":
event.respondWith(handleNowPlaying(event.request));
break;
default:
event.respondWith(new Response("ERROR: Unsupported request."));
}
});
async function handleHello(request) {
return new Response("Hello!, This is my first middleware thingy.");
}
async function handleAuthorization(request) {
var state = "SPOTIFY_WIDGET"; // TODO: No use? remove?
var url = new URL(request.url);
var callback_url = `${url.protocol}//${url.hostname}/callback`;
var scope = "user-read-currently-playing";
var params = {
response_type: "code",
client_id: CLIENT_ID,
scope: scope,
redirect_uri: callback_url,
state: state,
};
// https://howchoo.com/javascript/how-to-turn-an-object-into-query-string-parameters-in-javascript
var queryString = Object.keys(params)
.map((key) => key + "=" + params[key])
.join("&");
return Response.redirect(
"https://accounts.spotify.com/authorize?" + queryString,
302
);
}
async function handleCallback(request) {
var url = new URL(request.url);
var callback_url = `${url.protocol}//${url.hostname}/callback`;
var code = url.searchParams.get("code") || null;
var state = url.searchParams.get("state") || null; // TODO: Might remove later?
if (state === "SPOTIFY_WIDGET") {
return fetch("https://accounts.spotify.com/api/token", {
method: "post",
headers: {
Authorization: "Basic " + btoa(CLIENT_ID + ":" + CLIENT_SECRET),
"Content-Type": "application/x-www-form-urlencoded",
},
body: `code=${code}&redirect_uri=${callback_url}&grant_type=authorization_code`,
})
.then((response) => {
if (response.status === 200) {
return response.json();
} else
return new Response("Something went wrong, retry authorization :/");
})
.then((data) => {
return new Response(`Your refresh token is: ${data.refresh_token}`);
});
} else return new Response("Something went wrong, retry authorization :/");
}
async function handleNowPlaying(request) {
// Get a new access token everytime :D << Easy way out (Without checking expire time)
var access_token = await fetch("https://accounts.spotify.com/api/token", {
method: "post",
headers: {
Authorization: "Basic " + btoa(CLIENT_ID + ":" + CLIENT_SECRET),
"Content-Type": "application/x-www-form-urlencoded",
},
body: `grant_type=refresh_token&refresh_token=${REFRESH_TOKEN}`,
})
.then((response) => {
// TODO: Check errors here
return response.json();
})
.then((data) => {
return data.access_token;
});
var songData = await fetch(
"https://api.spotify.com/v1/me/player/currently-playing",
{
headers: {
Authorization: "Bearer " + access_token,
},
}
).then((response) => {
// TODO: Check errors here
return response.text();
});
// https://mcculloughwebservices.com/2016/09/23/handling-a-null-response-from-an-api/
// If response is empty throw error
if (!songData) songData = { ERROR: "Couldn't retrieve now playing." };
else songData = JSON.parse(songData);
// Add CORS to allow requests from any domain
const corsHeaders = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET",
"Access-Control-Max-Age": "86400",
};
return new Response(JSON.stringify(songData, null, 2), {
headers: corsHeaders,
});
}