swapped to a new db locally hosted
This commit is contained in:
166
discord-bot/api.js
Normal file
166
discord-bot/api.js
Normal file
@@ -0,0 +1,166 @@
|
||||
const fetch = require('node-fetch');
|
||||
|
||||
// Resolve backend candidates (env or common local addresses). We'll try them in order
|
||||
// for each request so the bot can still reach the backend even when it binds to
|
||||
// a specific non-loopback IP.
|
||||
const envBase = process.env.BACKEND_BASE ? process.env.BACKEND_BASE.replace(/\/$/, '') : null;
|
||||
const host = process.env.BACKEND_HOST || process.env.HOST || '127.0.0.1';
|
||||
const port = process.env.BACKEND_PORT || process.env.PORT || '3002';
|
||||
const CANDIDATES = [envBase, `http://${host}:${port}`, `http://localhost:${port}`, `http://127.0.0.1:${port}`].filter(Boolean);
|
||||
|
||||
async function tryFetch(url, opts = {}) {
|
||||
// Try each candidate base until one responds successfully
|
||||
for (const base of CANDIDATES) {
|
||||
const target = `${base.replace(/\/$/, '')}${url}`;
|
||||
try {
|
||||
const res = await fetch(target, opts);
|
||||
if (res && (res.ok || res.status === 204)) {
|
||||
return res;
|
||||
}
|
||||
// if this candidate returned a non-ok status, log and continue trying others
|
||||
console.error(`Candidate ${base} returned ${res.status} ${res.statusText} for ${target}`);
|
||||
} catch (e) {
|
||||
// network error for this candidate; try next
|
||||
// console.debug(`Candidate ${base} failed:`, e && e.message ? e.message : e);
|
||||
}
|
||||
}
|
||||
// none of the candidates succeeded
|
||||
return null;
|
||||
}
|
||||
|
||||
async function safeFetchJsonPath(path, opts = {}) {
|
||||
const res = await tryFetch(path, opts);
|
||||
if (!res) return null;
|
||||
try {
|
||||
return await res.json();
|
||||
} catch (e) {
|
||||
console.error('Failed to parse JSON from backend response:', e && e.message ? e.message : e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function getServerSettings(guildId) {
|
||||
const path = `/api/servers/${guildId}/settings`;
|
||||
const json = await safeFetchJsonPath(path);
|
||||
return json || {};
|
||||
}
|
||||
|
||||
async function upsertServerSettings(guildId, settings) {
|
||||
const path = `/api/servers/${guildId}/settings`;
|
||||
try {
|
||||
const res = await tryFetch(path, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(settings),
|
||||
});
|
||||
return res && res.ok;
|
||||
} catch (e) {
|
||||
console.error(`Failed to upsert settings for ${guildId}:`, e && e.message ? e.message : e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async function getCommands(guildId) {
|
||||
const path = `/api/servers/${guildId}/commands`;
|
||||
const json = await safeFetchJsonPath(path);
|
||||
return json || [];
|
||||
}
|
||||
|
||||
async function toggleCommand(guildId, cmdName, enabled) {
|
||||
const path = `/api/servers/${guildId}/commands/${cmdName}/toggle`;
|
||||
try {
|
||||
const res = await tryFetch(path, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ enabled }),
|
||||
});
|
||||
return res && res.ok;
|
||||
} catch (e) {
|
||||
console.error(`Failed to toggle command ${cmdName} for ${guildId}:`, e && e.message ? e.message : e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async function listInvites(guildId) {
|
||||
const path = `/api/servers/${guildId}/invites`;
|
||||
const json = await safeFetchJsonPath(path);
|
||||
return json || [];
|
||||
}
|
||||
|
||||
async function addInvite(guildId, invite) {
|
||||
const path = `/api/servers/${guildId}/invites`;
|
||||
try {
|
||||
const res = await tryFetch(path, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(invite),
|
||||
});
|
||||
return res && res.ok;
|
||||
} catch (e) {
|
||||
console.error(`Failed to add invite for ${guildId}:`, e && e.message ? e.message : e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteInvite(guildId, code) {
|
||||
const path = `/api/servers/${guildId}/invites/${code}`;
|
||||
try {
|
||||
const res = await tryFetch(path, { method: 'DELETE' });
|
||||
return res && res.ok;
|
||||
} catch (e) {
|
||||
console.error(`Failed to delete invite ${code} for ${guildId}:`, e && e.message ? e.message : e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { getServerSettings, upsertServerSettings, getCommands, toggleCommand, listInvites, addInvite, deleteInvite };
|
||||
// Twitch users helpers
|
||||
async function getTwitchUsers(guildId) {
|
||||
const path = `/api/servers/${guildId}/twitch-users`;
|
||||
const json = await safeFetchJsonPath(path);
|
||||
return json || [];
|
||||
}
|
||||
|
||||
async function addTwitchUser(guildId, username) {
|
||||
const path = `/api/servers/${guildId}/twitch-users`;
|
||||
try {
|
||||
const res = await tryFetch(path, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ username }),
|
||||
});
|
||||
return res && res.ok;
|
||||
} catch (e) {
|
||||
console.error(`Failed to add twitch user ${username} for ${guildId}:`, e && e.message ? e.message : e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteTwitchUser(guildId, username) {
|
||||
const path = `/api/servers/${guildId}/twitch-users/${encodeURIComponent(username)}`;
|
||||
try {
|
||||
const res = await tryFetch(path, { method: 'DELETE' });
|
||||
return res && res.ok;
|
||||
} catch (e) {
|
||||
console.error(`Failed to delete twitch user ${username} for ${guildId}:`, e && e.message ? e.message : e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch stream status via backend proxy endpoint /api/twitch/streams?users=a,b,c
|
||||
async function tryFetchTwitchStreams(usersCsv) {
|
||||
const path = `/api/twitch/streams?users=${encodeURIComponent(usersCsv || '')}`;
|
||||
const json = await safeFetchJsonPath(path);
|
||||
return json || [];
|
||||
}
|
||||
|
||||
// Raw direct call helper (not used in most environments) — kept for legacy watcher
|
||||
async function _rawGetTwitchStreams(usersCsv) {
|
||||
// Try direct backend candidate first
|
||||
const path = `/api/twitch/streams?users=${encodeURIComponent(usersCsv || '')}`;
|
||||
const res = await tryFetch(path);
|
||||
if (!res) return [];
|
||||
try { return await res.json(); } catch (e) { return []; }
|
||||
}
|
||||
|
||||
module.exports = { getServerSettings, upsertServerSettings, getCommands, toggleCommand, listInvites, addInvite, deleteInvite, getTwitchUsers, addTwitchUser, deleteTwitchUser };
|
||||
Reference in New Issue
Block a user