Apologies if this has been answered elsewhere, i tried searching but couldn’t find it.
I’ve written a script (with the help of AI) to display current track info for an overlay.
The issue i’m having is it works perfectly for 5 minutes and then console explodes with error about token not being valid and for the life of me i’m unable to get the script to automate this process using the grant flow (not implicit)
Here is an example of the script that deals with that side of things and hopefully someone infinitely smarter than i can see where i’m going wrong…
async function refreshAccessToken(url, params, isNightbot = false) {
if (isNightbot && isNightbotRefreshing) {
console.log("Nightbot refresh already in progress, skipping.");
return false;
}
if (isNightbot) isNightbotRefreshing = true;
try {
console.log(`Attempting to refresh ${isNightbot ? 'Nightbot' : 'Twitch'} token...`);
if (isNightbot) {
console.log("Nightbot refreshToken:", nightbotConfig.refreshToken); // Added logging
}
const response = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams(params)
});
if (!response.ok) {
const errorData = await response.text();
console.error(`Token refresh failed with status: ${response.status}`, errorData);
return false;
}
const data = await response.json();
if (data.access_token) {
if (isNightbot) {
nightbotConfig.accessToken = data.access_token;
if (data.refresh_token) {
nightbotConfig.refreshToken = data.refresh_token;
}
console.log('Nightbot token refreshed successfully:', data.access_token.substring(0, 10) + '...');
console.log("Nightbot accessToken updated:", nightbotConfig.accessToken.substring(0, 10) + "...");
} else {
twitchConfig.accessToken = data.access_token;
if (data.refresh_token) {
twitchConfig.refreshToken = data.refresh_token;
}
console.log('Twitch token refreshed successfully:', data.access_token.substring(0, 10) + '...');
}
return true;
} else {
console.error(`${isNightbot ? 'Nightbot' : 'Twitch'} token refresh failed:`, data);
return false;
}
} catch (error) {
console.error(`Error refreshing ${isNightbot ? 'Nightbot' : 'Twitch'} access token:`, error);
return false;
} finally {
if (isNightbot) isNightbotRefreshing = false;
}
}
async function validateTwitchToken() {
try {
const response = await fetch("https://id.twitch.tv/oauth2/validate", {
headers: { "Authorization": `OAuth ${twitchConfig.accessToken}` }
});
if (!response.ok) {
console.warn("Twitch token expired. Refreshing...");
await refreshTwitchAccessToken();
} else {
console.log("Twitch token is still valid.");
}
} catch (error) {
console.error("Error validating Twitch token:", error);
await refreshTwitchAccessToken();
}
}
async function validateNightbotToken() {
try{
const response = await fetch("https://api.nightbot.tv/1/me", {
headers: {"Authorization": `Bearer ${nightbotConfig.accessToken}`}
});
if (!response.ok){
console.warn("Nightbot token Expired. Refreshing...");
await refreshNightbotAccessToken();
} else{
console.log("Nightbot token is still valid");
}
} catch(error) {
console.error("error validating Nightbot token:", error);
await refreshNightbotAccessToken();
}
}
async function refreshNightbotAccessToken() {
return await refreshAccessToken('https://api.nightbot.tv/oauth2/token', {
grant_type: 'refresh_token',
refresh_token: nightbotConfig.refreshToken,
client_id: nightbotConfig.clientId,
client_secret: nightbotConfig.clientSecret
}, true);
}
async function refreshTwitchAccessToken() {
return await refreshAccessToken('https://id.twitch.tv/oauth2/token', {
client_id: twitchConfig.clientId,
client_secret: twitchConfig.clientSecret,
grant_type: 'refresh_token',
refresh_token: twitchConfig.refreshToken
});
}
async function loadTrack() {
try {
let response = await fetch('https://api.nightbot.tv/1/song_requests/queue', {
headers: { 'Authorization': `Bearer ${nightbotConfig.accessToken}` }
});
if (response.status === 401) {
console.log("Nightbot token expired, refreshing...");
const refreshed = await refreshNightbotAccessToken();
if (refreshed) {
response = await fetch('https://api.nightbot.tv/1/song_requests/queue', {
headers: { 'Authorization': `Bearer ${nightbotConfig.accessToken}` }
});
} else {
console.error("Nightbot token refresh failed, cannot load track.");
document.getElementById('currentTrack').textContent = 'Track info not available.';
return;
}
}
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}