add discord 'Message Info' context menu entry
This commit is contained in:
parent
ccb652f737
commit
755609901c
1 changed files with 134 additions and 50 deletions
|
@ -3,13 +3,16 @@
|
||||||
import { client } from "./client";
|
import { client } from "./client";
|
||||||
import { REST } from '@discordjs/rest';
|
import { REST } from '@discordjs/rest';
|
||||||
import { Routes } from 'discord-api-types/v9';
|
import { Routes } from 'discord-api-types/v9';
|
||||||
import { BRIDGE_CONFIG, BRIDGE_REQUESTS, logger } from "..";
|
import { BRIDGED_MESSAGES, BRIDGE_CONFIG, BRIDGE_REQUESTS, logger } from "..";
|
||||||
import { TextChannel } from "discord.js";
|
import { MessageEmbed, TextChannel } from "discord.js";
|
||||||
|
import { revoltFetchMessage, revoltFetchUser } from "../util";
|
||||||
|
import { client as revoltClient } from "../revolt/client";
|
||||||
|
|
||||||
const COMMANDS: any[] = [
|
const COMMANDS: any[] = [
|
||||||
{
|
{
|
||||||
name: 'bridge',
|
name: 'bridge',
|
||||||
description: 'Confirm or delete Revolt bridges',
|
description: 'Confirm or delete Revolt bridges',
|
||||||
|
type: 1, // Slash command
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
name: 'confirm',
|
name: 'confirm',
|
||||||
|
@ -30,6 +33,11 @@ const COMMANDS: any[] = [
|
||||||
type: 1,
|
type: 1,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Message Info',
|
||||||
|
description: '',
|
||||||
|
type: 3, // Message context menu
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -59,63 +67,139 @@ client.once('ready', async () => {
|
||||||
|
|
||||||
client.on('interactionCreate', async interaction => {
|
client.on('interactionCreate', async interaction => {
|
||||||
try {
|
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
|
const ownPerms = (interaction.channel as TextChannel).permissionsFor(client.user!)!;
|
||||||
switch(interaction.commandName) {
|
switch(interaction.options.getSubcommand(true)) {
|
||||||
case 'bridge':
|
case 'confirm':
|
||||||
if (!interaction.memberPermissions?.has('MANAGE_GUILD')) {
|
if (!ownPerms.has('MANAGE_WEBHOOKS'))
|
||||||
return await interaction.reply(`\`MANAGE_GUILD\` permission is required for this.`);
|
return interaction.reply('Sorry, I lack permission to manage webhooks in this channel.');
|
||||||
}
|
|
||||||
|
|
||||||
const ownPerms = (interaction.channel as TextChannel).permissionsFor(client.user!)!;
|
const id = interaction.options.getString('id', true);
|
||||||
switch(interaction.options.getSubcommand(true)) {
|
const request = await BRIDGE_REQUESTS.findOne({ id: id });
|
||||||
case 'confirm':
|
if (!request || request.expires < Date.now()) return await interaction.reply('Unknown ID.');
|
||||||
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 bridgedCount = await BRIDGE_CONFIG.count({ discord: interaction.channelId });
|
||||||
const request = await BRIDGE_REQUESTS.findOne({ id: id });
|
if (bridgedCount > 0) return await interaction.reply('This channel is already bridged.');
|
||||||
if (!request || request.expires < Date.now()) return await interaction.reply('Unknown ID.');
|
|
||||||
|
|
||||||
const bridgedCount = await BRIDGE_CONFIG.count({ discord: interaction.channelId });
|
const webhook = await (interaction.channel as TextChannel)
|
||||||
if (bridgedCount > 0) return await interaction.reply('This channel is already bridged.');
|
.createWebhook('AutoMod Bridge', { avatar: client.user?.avatarURL() });
|
||||||
|
|
||||||
const webhook = await (interaction.channel as TextChannel)
|
await BRIDGE_REQUESTS.remove({ id: id });
|
||||||
.createWebhook('AutoMod Bridge', { avatar: client.user?.avatarURL() });
|
await BRIDGE_CONFIG.insert({
|
||||||
|
discord: interaction.channelId,
|
||||||
|
revolt: request.revolt,
|
||||||
|
discordWebhook: {
|
||||||
|
id: webhook.id,
|
||||||
|
token: webhook.token || '',
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
await BRIDGE_REQUESTS.remove({ id: id });
|
return await interaction.reply(`✅ Channel bridged!`);
|
||||||
await BRIDGE_CONFIG.insert({
|
case 'unlink':
|
||||||
discord: interaction.channelId,
|
const res = await BRIDGE_CONFIG.findOneAndDelete({ discord: interaction.channelId });
|
||||||
revolt: request.revolt,
|
if (res?._id) {
|
||||||
discordWebhook: {
|
await interaction.reply('Channel unbridged.');
|
||||||
id: webhook.id,
|
if (ownPerms.has('MANAGE_WEBHOOKS') && res.discordWebhook) {
|
||||||
token: webhook.token || '',
|
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) {
|
} catch(e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
|
Loading…
Reference in a new issue