184 lines
6.0 KiB
JavaScript
184 lines
6.0 KiB
JavaScript
(function () {
|
|
const statusEl = document.getElementById('status');
|
|
const logEl = document.getElementById('log');
|
|
const tokenEl = document.getElementById('token');
|
|
const guildEl = document.getElementById('guild');
|
|
const loginBtn = document.getElementById('login');
|
|
const logoutBtn = document.getElementById('logout');
|
|
const msgContentEl = document.getElementById('msgContent');
|
|
|
|
let client = null;
|
|
|
|
function banner(kind, text) {
|
|
statusEl.className = 'bs-banner bs-banner--' + kind;
|
|
statusEl.textContent = text;
|
|
}
|
|
|
|
function log(line) {
|
|
const p = document.createElement('div');
|
|
p.textContent = line;
|
|
logEl.appendChild(p);
|
|
logEl.scrollTop = logEl.scrollHeight;
|
|
}
|
|
|
|
function setBusy(on) {
|
|
loginBtn.disabled = on;
|
|
logoutBtn.disabled = on && !client;
|
|
}
|
|
|
|
function waitForDiscordJS(timeoutMs) {
|
|
timeoutMs = timeoutMs || 8000;
|
|
const started = Date.now();
|
|
return new Promise(function (resolve, reject) {
|
|
function tick() {
|
|
const dj = window.BridgeSwarm && window.BridgeSwarm.DiscordJS;
|
|
if (dj && typeof dj.status === 'function') {
|
|
resolve(dj);
|
|
return;
|
|
}
|
|
if (Date.now() - started >= timeoutMs) {
|
|
reject(
|
|
new Error(
|
|
'BridgeSwarm.DiscordJS is missing. In chrome://extensions reload BridgeSwarm, then refresh this page.'
|
|
)
|
|
);
|
|
return;
|
|
}
|
|
setTimeout(tick, 50);
|
|
}
|
|
tick();
|
|
});
|
|
}
|
|
|
|
async function boot() {
|
|
await BridgeSwarmExamples.waitForBridgeSwarm();
|
|
let dj;
|
|
try {
|
|
dj = await waitForDiscordJS();
|
|
} catch (err) {
|
|
banner('err', err.message || String(err));
|
|
return;
|
|
}
|
|
let st = {};
|
|
try {
|
|
st = await dj.status();
|
|
} catch (err) {
|
|
banner('err', err.message || String(err));
|
|
return;
|
|
}
|
|
if (!st.loaded) {
|
|
banner('warn', 'discord.js did not load on the host' + (st.loadError ? ': ' + st.loadError : '.'));
|
|
return;
|
|
}
|
|
if (!st.enabled) {
|
|
banner('warn', 'Discord is off. BridgeSwarm Settings → Enable Discord, then refresh.');
|
|
return;
|
|
}
|
|
banner('ok', 'Discord pack ready. Paste a bot token and login.');
|
|
try {
|
|
await dj.ready();
|
|
} catch (_) {}
|
|
}
|
|
|
|
async function onLogin() {
|
|
const token = (tokenEl.value || '').trim();
|
|
if (!token) {
|
|
banner('warn', 'Paste a bot token first.');
|
|
return;
|
|
}
|
|
setBusy(true);
|
|
try {
|
|
const dj = await waitForDiscordJS();
|
|
await dj.ready();
|
|
const { Client, GatewayIntentBits, Events, SlashCommandBuilder, REST, Routes } = dj;
|
|
const intents = [GatewayIntentBits.Guilds];
|
|
if (GatewayIntentBits.DirectMessages) intents.push(GatewayIntentBits.DirectMessages);
|
|
if (GatewayIntentBits.GuildMessages) intents.push(GatewayIntentBits.GuildMessages);
|
|
if (msgContentEl.checked && GatewayIntentBits.MessageContent) {
|
|
intents.push(GatewayIntentBits.MessageContent);
|
|
}
|
|
if (client) {
|
|
try {
|
|
await client.destroy();
|
|
} catch (_) {}
|
|
client = null;
|
|
}
|
|
client = new Client({ intents: intents });
|
|
client.once(Events.ClientReady || Events.Ready || 'clientReady', async function (readyClient) {
|
|
const tag = (readyClient && readyClient.user && readyClient.user.tag) || (client.user && client.user.tag) || 'bot';
|
|
log('Logged in as ' + tag);
|
|
banner('ok', 'Logged in as ' + tag);
|
|
const ping = new SlashCommandBuilder().setName('ping').setDescription('Replies with pong.').toJSON();
|
|
try {
|
|
const rest = new REST().setToken(token);
|
|
const appId = readyClient.user && readyClient.user.id;
|
|
const guildId = (guildEl.value || '').trim();
|
|
if (guildId) {
|
|
await rest.put(Routes.applicationGuildCommands(appId, guildId), { body: [ping] });
|
|
log('Registered /ping for guild ' + guildId);
|
|
} else {
|
|
await rest.put(Routes.applicationCommands(appId), { body: [ping] });
|
|
log('Registered global /ping (may take up to an hour). Set a guild id for instant updates.');
|
|
}
|
|
} catch (err) {
|
|
log('slash register failed: ' + (err && err.message ? err.message : err));
|
|
}
|
|
});
|
|
client.on(Events.InteractionCreate || 'interactionCreate', async function (ix) {
|
|
if (!ix || typeof ix.isChatInputCommand !== 'function' || !ix.isChatInputCommand()) return;
|
|
if (ix.commandName !== 'ping') return;
|
|
try {
|
|
await ix.reply({ content: 'pong' });
|
|
log('/ping → pong');
|
|
} catch (err) {
|
|
log('reply failed: ' + (err && err.message ? err.message : err));
|
|
}
|
|
});
|
|
if (Events.MessageCreate) {
|
|
client.on(Events.MessageCreate, async function (message) {
|
|
if (!message || (message.author && message.author.bot)) return;
|
|
if (String(message.content || '').trim().toLowerCase() !== 'ping') return;
|
|
try {
|
|
await message.reply('pong');
|
|
log('message ping → pong');
|
|
} catch (err) {
|
|
log('message reply failed: ' + (err && err.message ? err.message : err));
|
|
}
|
|
});
|
|
}
|
|
client.on('error', function (err) {
|
|
log('client error: ' + (err && err.message ? err.message : err));
|
|
});
|
|
log('Logging in…');
|
|
await client.login(token);
|
|
} catch (err) {
|
|
banner('err', err.message || String(err));
|
|
log(err.message || String(err));
|
|
} finally {
|
|
setBusy(false);
|
|
}
|
|
}
|
|
|
|
async function onLogout() {
|
|
if (!client) return;
|
|
setBusy(true);
|
|
try {
|
|
await client.destroy();
|
|
client = null;
|
|
banner('ok', 'Client destroyed.');
|
|
log('Destroyed client.');
|
|
} catch (err) {
|
|
log(err.message || String(err));
|
|
} finally {
|
|
setBusy(false);
|
|
}
|
|
}
|
|
|
|
loginBtn.addEventListener('click', onLogin);
|
|
logoutBtn.addEventListener('click', onLogout);
|
|
|
|
BridgeSwarmExamples.waitForBridgeSwarm().then(boot).catch(function (err) {
|
|
banner('err', err.message || String(err));
|
|
});
|
|
})();
|