From 755609901c54cb8e55ae9f98031b2dabe58097a3 Mon Sep 17 00:00:00 2001 From: janderedev Date: Sat, 30 Apr 2022 22:23:30 +0200 Subject: [PATCH] add discord 'Message Info' context menu entry --- bridge/src/discord/commands.ts | 184 ++++++++++++++++++++++++--------- 1 file changed, 134 insertions(+), 50 deletions(-) diff --git a/bridge/src/discord/commands.ts b/bridge/src/discord/commands.ts index 5d26c58..3a80634 100644 --- a/bridge/src/discord/commands.ts +++ b/bridge/src/discord/commands.ts @@ -3,13 +3,16 @@ 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"; +import { BRIDGED_MESSAGES, BRIDGE_CONFIG, BRIDGE_REQUESTS, logger } from ".."; +import { MessageEmbed, TextChannel } from "discord.js"; +import { revoltFetchMessage, revoltFetchUser } from "../util"; +import { client as revoltClient } from "../revolt/client"; const COMMANDS: any[] = [ { name: 'bridge', description: 'Confirm or delete Revolt bridges', + type: 1, // Slash command options: [ { name: 'confirm', @@ -30,6 +33,11 @@ const COMMANDS: any[] = [ type: 1, }, ], + }, + { + name: 'Message Info', + description: '', + type: 3, // Message context menu } ]; @@ -59,63 +67,139 @@ client.once('ready', async () => { client.on('interactionCreate', async interaction => { try { - if (!interaction.isCommand()) return; + if (interaction.isCommand()) { + logger.debug(`Command received: /${interaction.commandName}`); - 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.`); + } - // 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 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 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 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() }); - 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 || '', + } + }); - 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; + } + } + else if (interaction.isMessageContextMenu()) { + logger.debug(`Received context menu: ${interaction.targetMessage.id}`); + + switch(interaction.commandName) { + case 'Message Info': + const message = interaction.targetMessage; + const bridgeInfo = await BRIDGED_MESSAGES.findOne({ "discord.messageId": message.id }); + const messageUrl = `https://discord.com/channels/${interaction.guildId}/${interaction.channelId}/${message.id}`; + + if (!bridgeInfo) return await interaction.reply({ + ephemeral: true, + embeds: [ + new MessageEmbed() + .setAuthor({ name: 'Message info', url: messageUrl }) + .setDescription('This message has not been bridged.') + .setColor('#7e96ff'), + ], + }); + else { + const embed = new MessageEmbed(); + + embed.setColor('#7e96ff'); + embed.setAuthor({ name: 'Message info', url: messageUrl }); + + embed.addField('Origin', bridgeInfo.origin == 'discord' ? 'Discord' : 'Revolt', true); + + if (bridgeInfo.origin == 'discord') { + embed.addField( + 'Bridge Status', + bridgeInfo.revolt.messageId + ? 'Bridged' + : bridgeInfo.revolt.nonce + ? 'ID unknown' + : 'Unbridged', + true + ); + } else { + embed.addField( + 'Bridge Status', + bridgeInfo.discord.messageId + ? 'Bridged' + : 'Unbridged', + true + ); + + if (bridgeInfo.channels?.revolt) { + const channel = await revoltClient.channels.get(bridgeInfo.channels.revolt); + const revoltMsg = await revoltFetchMessage(bridgeInfo.revolt.messageId, channel); + + if (revoltMsg) { + const author = await revoltFetchUser(revoltMsg.author_id); + embed.addField( + 'Message Author', + `**@${author?.username}** (${revoltMsg.author_id})`, + ); + } + } + } + + embed.addField( + 'Bridge Data', + `Origin: \`${bridgeInfo.origin}\`\n` + + `Discord ID: \`${bridgeInfo.discord.messageId}\`\n` + + `Revolt ID: \`${bridgeInfo.revolt.messageId}\`\n` + + `Revolt Nonce: \`${bridgeInfo.revolt.nonce}\`\n` + + `Discord Channel: \`${bridgeInfo.channels?.discord}\`\n` + + `Revolt Channel: \`${bridgeInfo.channels?.revolt}\`` + ); + + return await interaction.reply({ + ephemeral: true, + embeds: [ embed ], }); - - 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);