import * as config from "./config"; import fetch, { Response as FetchResponse } from "node-fetch"; export interface TokenPair { access_token: string; refresh_token: string; } // Refresh the API token. Returns true on success and false on failure. async function refreshApiToken(tokens: TokenPair): Promise { return fetch("https://id.twitch.tv/oauth2/token", { method: 'POST', body: new URLSearchParams({ client_id: config.twitchClientId, client_secret: config.twitchSecret, grant_type: "refresh_token", refresh_token: tokens.refresh_token }) }).then(async (res: FetchResponse) => { if (res.status == 200) { var data = await (res.json() as Promise); tokens.access_token = data.access_token; tokens.refresh_token = data.refresh_token; return true; } else { return false; } }) } // Send an API request. On success, return the specified data. On failure, // attempt to refresh the API token and retry export async function apiRequest(tokens: TokenPair, endpoint: string): Promise { var headers = { "Authorization": "Bearer " + tokens.access_token, "Client-ID": config.twitchClientId }; return fetch("https://api.twitch.tv/helix" + endpoint, { headers: headers }) .then((res: FetchResponse) => { if (res.status == 200) { return res.json(); } else { if (refreshApiToken(tokens)) { return fetch("https://api.twitch.tv/helix" + endpoint, { headers: headers }) .then(async (res: FetchResponse) => { if (res.status == 200) { return res.json(); } else { console.log("Failed API request:"); console.log("Request URL: https://api.twitch.tv/helix" + endpoint); console.log("Headers: "); console.log(headers); console.log("Response: "); console.log(await res.json()); return false; } }) } else { return false; } } }) } // Check if API token is valid. Checks Twitch's OAuth validation endpoint. If // success, return true. If failure, return the result of attempting to refresh // the API token. export async function isApiTokenValid(tokens: TokenPair) { return fetch("https://id.twitch.tv/oauth2/validate", { headers: {'Authorization': `OAuth ${tokens.access_token}`} }).then((res: FetchResponse) => { if (res.status == 200) { return true; } else { return refreshApiToken(tokens); } }) }