AutoMod/bridge/src/discord/commands.ts
2022-04-24 14:06:02 +02:00

124 lines
5 KiB
TypeScript

// fuck slash commands
import { client } from "./client";
import { REST } from '@discordjs/rest';
import { Routes } from 'discord-api-types/v9';
import { BRIDGE_CONFIG, BRIDGE_REQUESTS, logger } from "..";
import { TextChannel } from "discord.js";
const COMMANDS: any[] = [
{
name: 'bridge',
description: 'Confirm or delete Revolt bridges',
options: [
{
name: 'confirm',
description: 'Confirm a bridge initiated from Revolt',
type: 1, // Subcommand
options: [
{
name: "id",
description: "The bridge request ID",
required: true,
type: 3,
}
],
},
{
name: 'unlink',
description: 'Unbridge the current channel',
type: 1,
},
],
}
];
const rest = new REST({ version: '9' }).setToken(process.env['DISCORD_TOKEN']!);
client.once('ready', async () => {
try {
logger.info(`Refreshing application commands.`);
if (process.env.NODE_ENV != 'production' && process.env.DEV_GUILD) {
await rest.put(
Routes.applicationGuildCommands(client.user!.id, process.env.DEV_GUILD),
{ body: COMMANDS },
);
logger.done(`Application commands for ${process.env.DEV_GUILD} have been updated.`);
} else {
await rest.put(
Routes.applicationCommands(client.user!.id),
{ body: COMMANDS },
);
logger.done(`Global application commands have been updated.`);
}
} catch(e) {
console.error(e);
}
});
client.on('interactionCreate', async interaction => {
try {
if (!interaction.isCommand()) return;
logger.debug(`Command received: /${interaction.commandName}`);
// The revolutionary Jan command handler
switch(interaction.commandName) {
case 'bridge':
if (!interaction.memberPermissions?.has('MANAGE_GUILD')) {
return await interaction.reply(`\`MANAGE_GUILD\` permission is required for this.`);
}
const ownPerms = (interaction.channel as TextChannel).permissionsFor(client.user!)!;
switch(interaction.options.getSubcommand(true)) {
case 'confirm':
if (!ownPerms.has('MANAGE_WEBHOOKS'))
return interaction.reply('Sorry, I lack permission to manage webhooks in this channel.');
const id = interaction.options.getString('id', true);
const request = await BRIDGE_REQUESTS.findOne({ id: id });
if (!request || request.expires < Date.now()) return await interaction.reply('Unknown ID.');
const bridgedCount = await BRIDGE_CONFIG.count({ discord: interaction.channelId });
if (bridgedCount > 0) return await interaction.reply('This channel is already bridged.');
const webhook = await (interaction.channel as TextChannel)
.createWebhook('AutoMod Bridge', { avatar: client.user?.avatarURL() });
await BRIDGE_REQUESTS.remove({ id: id });
await BRIDGE_CONFIG.insert({
discord: interaction.channelId,
revolt: request.revolt,
discordWebhook: {
id: webhook.id,
token: webhook.token || '',
}
});
return await interaction.reply(`✅ Channel bridged!`);
case 'unlink':
const res = await BRIDGE_CONFIG.findOneAndDelete({ discord: interaction.channelId });
if (res?._id) {
await interaction.reply('Channel unbridged.');
if (ownPerms.has('MANAGE_WEBHOOKS') && res.discordWebhook) {
try {
const hooks = await (interaction.channel as TextChannel).fetchWebhooks();
if (hooks.get(res?.discordWebhook?.id)) await hooks.get(res?.discordWebhook?.id)
?.delete('Channel has been unbridged');
} catch(_) {}
}
}
else await interaction.reply('This channel is not bridged.');
break;
default: await interaction.reply('Unknown subcommand');
}
break;
}
} catch(e) {
console.error(e);
if (interaction.isCommand()) interaction.reply('An error has occurred: ' + e).catch(() => {});
}
});