-
Notifications
You must be signed in to change notification settings - Fork 2
/
api.js
84 lines (70 loc) · 2.76 KB
/
api.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
/*
* This module handles automating the OAuth2 token and refresh token
*/
import fetch from "node-fetch";
import apiData from "./data/api.json" assert { type: "json" };
import * as fs from "fs/promises";
export default async function checkOAuthStatus() {
// If Oauth is due to expire OR OAuth returns a 404, then:
if (isOAuthExpired()) {
const response = await refreshOAuth();
const json = await response.json();
await checkRefreshInJSON(json);
}
}
function isOAuthExpired() {
const currentTime = new Date() / 1000; // in seconds
const lastRefreshTime = apiData.LAST_REFRESH;
// Check to see if the currentTime is within 5 minutes of the expiration or over:
if (currentTime - lastRefreshTime >= apiData.OA_EXPIRE - 300) {
console.log("OAuth is expired");
return true;
}
console.log("OAuth is not expired");
return false;
}
function refreshOAuth() {
// When OAuth is expired && this function called, build fetch URL:
const TWITCH_REFRESH_URL = `https://id.twitch.tv/oauth2/token`;
// Fetch new OAuth token:
return fetch(TWITCH_REFRESH_URL, {
method: "POST",
body: `client_id=${apiData.CLIENT_ID}&client_secret=${apiData.CLIENT_SECRET}&grant_type=refresh_token&refresh_token=${apiData.REFRESH_TOKEN}`,
headers: {
"Content-Type": `application/x-www-form-urlencoded`,
},
});
}
async function checkRefreshInJSON(json) {
if (json.message === `Invalid refresh token`) {
getNewRefreshToken();
} else {
await updateJSON(json);
}
}
async function updateJSON(response) {
// Update values in JSON object w/ values from API response:
apiData.OA_TOKEN = response.access_token;
apiData.OA_EXPIRE = response.expires_in;
apiData.LAST_REFRESH = new Date() / 1000; // in seconds
const JSONObj = JSON.stringify(apiData);
const targetFile = "./data/api.json";
// Overwrite api.json w/ updated JSON Object:
await fs.writeFile(targetFile, JSONObj, "utf-8");
}
function getNewRefreshToken() {
console.log(
"Need new Refresh Token :(. Not able to refresh token at this time."
);
}
/* f wherever you want to access the data you use `getApiData()`,
and only in that function you use `require`, and only the first time that it gets called,
then `require` will only be called later on in the program's execution,
not when the files get loaded as an import
Another option is, create an api.js file. Requiring that file will return the
object you store in module.exports inside of that file. Any file that requires
api.js will get a reference to that same object. It doesn't matter if that object
is empty at the beginning of the project. Later on, you can set values on that object
(e.g. module.exports.token = blabla). And any file that required api.js will be able
to access whatever data you store in that object.
*/