add /bridge info command

This commit is contained in:
janderedev 2022-04-30 23:14:48 +02:00
parent b65a1bd70c
commit a18a0f9c65
Signed by: Lea
GPG key ID: 5D5E18ACB990F57A
5 changed files with 97 additions and 5 deletions

View file

@ -23,6 +23,7 @@
"log75": "^2.2.0", "log75": "^2.2.0",
"monk": "^7.3.4", "monk": "^7.3.4",
"prom-client": "^14.0.1", "prom-client": "^14.0.1",
"revolt-api": "^0.5.3-rc.15",
"ulid": "^2.3.0", "ulid": "^2.3.0",
"xlsx": "^0.17.3" "xlsx": "^0.17.3"
}, },

View file

@ -1,10 +1,12 @@
import { Message } from "@janderedev/revolt.js";
import { ulid } from "ulid"; import { ulid } from "ulid";
import { SendableEmbed } from "revolt-api";
import { dbs } from "../.."; import { dbs } from "../..";
import CommandCategory from "../../struct/commands/CommandCategory"; import CommandCategory from "../../struct/commands/CommandCategory";
import SimpleCommand from "../../struct/commands/SimpleCommand"; import SimpleCommand from "../../struct/commands/SimpleCommand";
import MessageCommandContext from "../../struct/MessageCommandContext"; import MessageCommandContext from "../../struct/MessageCommandContext";
import { DEFAULT_PREFIX } from "../modules/command_handler"; import { DEFAULT_PREFIX } from "../modules/command_handler";
import { isBotManager, NO_MANAGER_MSG } from "../util"; import { isBotManager, isModerator, NO_MANAGER_MSG } from "../util";
const DISCORD_INVITE_URL = 'https://discord.com/api/oauth2/authorize?client_id=965692929643524136&permissions=536996864&scope=bot%20applications.commands'; // todo: read this from env or smth const DISCORD_INVITE_URL = 'https://discord.com/api/oauth2/authorize?client_id=965692929643524136&permissions=536996864&scope=bot%20applications.commands'; // todo: read this from env or smth
@ -14,10 +16,10 @@ export default {
description: 'Bridge a channel with Discord', description: 'Bridge a channel with Discord',
category: CommandCategory.Misc, category: CommandCategory.Misc,
run: async (message: MessageCommandContext, args: string[]) => { run: async (message: MessageCommandContext, args: string[]) => {
if (!await isBotManager(message)) return message.reply(NO_MANAGER_MSG);
switch(args[0]?.toLowerCase()) { switch(args[0]?.toLowerCase()) {
case 'link': { case 'link': {
if (!await isBotManager(message)) return message.reply(NO_MANAGER_MSG);
const count = await dbs.BRIDGE_CONFIG.count({ revolt: message.channel_id }); const count = await dbs.BRIDGE_CONFIG.count({ revolt: message.channel_id });
if (count) return message.reply(`This channel is already bridged.`); if (count) return message.reply(`This channel is already bridged.`);
@ -50,12 +52,16 @@ export default {
break; break;
} }
case 'unlink': { case 'unlink': {
if (!await isBotManager(message)) return message.reply(NO_MANAGER_MSG);
const res = await dbs.BRIDGE_CONFIG.remove({ revolt: message.channel_id }); const res = await dbs.BRIDGE_CONFIG.remove({ revolt: message.channel_id });
if (res.deletedCount) await message.reply(`Channel unlinked!`); if (res.deletedCount) await message.reply(`Channel unlinked!`);
else await message.reply(`Unable to unlink; no channel linked.`); else await message.reply(`Unable to unlink; no channel linked.`);
break; break;
} }
case 'unlink_all': { case 'unlink_all': {
if (!await isBotManager(message)) return message.reply(NO_MANAGER_MSG);
const query = { revolt: { $in: message.channel?.server?.channel_ids || [] } }; const query = { revolt: { $in: message.channel?.server?.channel_ids || [] } };
if (args[1] == 'CONFIRM') { if (args[1] == 'CONFIRM') {
const res = await dbs.BRIDGE_CONFIG.remove(query); const res = await dbs.BRIDGE_CONFIG.remove(query);
@ -75,6 +81,8 @@ export default {
break; break;
} }
case 'list': { case 'list': {
if (!await isBotManager(message)) return message.reply(NO_MANAGER_MSG);
const links = await dbs.BRIDGE_CONFIG.find({ revolt: { $in: message.channel?.server?.channel_ids || [] } }); const links = await dbs.BRIDGE_CONFIG.find({ revolt: { $in: message.channel?.server?.channel_ids || [] } });
await message.reply({ await message.reply({
@ -89,6 +97,67 @@ export default {
}); });
break; break;
} }
case 'info': {
try {
if (!message.reply_ids) {
return await message.reply('Please run this command again while replying to a message.');
}
if (message.reply_ids.length > 1 && !await isModerator(message, false)) {
return await message.reply(
'To avoid spam, only moderators are allowed to query bridge info for more than one message at a time.'
);
}
const messages = (await Promise.allSettled(
message.reply_ids?.map(m => message.channel!.fetchMessage(m)) || []
))
.filter(m => m.status == 'fulfilled')
.map(m => (m as PromiseFulfilledResult<Message>).value);
if (!messages.length) {
return await message.reply('Something went wrong; could not fetch the target message(s).');
}
const embeds: SendableEmbed[] = await Promise.all(messages.map(async msg => {
const bridgeData = await dbs.BRIDGED_MESSAGES.findOne({
'revolt.messageId': msg._id,
});
const embed: SendableEmbed = bridgeData ? {
url: msg.url,
title: `Message ${bridgeData?.origin == 'revolt' ? `by ${msg.author?.username}` : 'from Discord'}`,
colour: '#7e96ff',
description: `**Origin:** ${bridgeData.origin == 'revolt' ? 'Revolt' : 'Discord'}\n` +
`**Bridge Status:** ${
bridgeData.origin == 'revolt'
? (bridgeData.discord.messageId ? 'Bridged' : 'Unbridged')
: (bridgeData.revolt.messageId ? 'Bridged' : (bridgeData.revolt.nonce ? 'ID unknown' : 'Unbridged'))
}\n` +
`### Bridge Data\n` +
`Origin: \`${bridgeData.origin}\`\n` +
`Discord ID: \`${bridgeData.discord.messageId}\`\n` +
`Revolt ID: \`${bridgeData.revolt.messageId}\`\n` +
`Revolt Nonce: \`${bridgeData.revolt.nonce}\`\n` +
`Discord Channel: \`${bridgeData.channels?.discord}\`\n` +
`Revolt Channel: \`${bridgeData.channels?.revolt}\``,
} : {
url: msg.url,
title: `Message by ${msg.author?.username}`,
description: 'This message has not been bridged.',
colour: '#7e96ff',
}
return embed;
}));
await message.reply({ embeds }, false);
} catch(e) {
console.error(e);
message.reply(''+e)?.catch(() => {});
}
break;
}
case 'help': { case 'help': {
await message.reply({ await message.reply({
content: '#', content: '#',
@ -103,7 +172,9 @@ export default {
+ `then run the command: \`/bridge confirm [ID]\`.\n\n` + `then run the command: \`/bridge confirm [ID]\`.\n\n`
+ `You can list all bridges in a Revolt server by running \`${DEFAULT_PREFIX}bridge list\`\n\n` + `You can list all bridges in a Revolt server by running \`${DEFAULT_PREFIX}bridge list\`\n\n`
+ `To unlink a channel, run \`/bridge unlink\` from either Discord or Revolt. If you wish to ` + `To unlink a channel, run \`/bridge unlink\` from either Discord or Revolt. If you wish to `
+ `unbridge all channels in a Revolt server, run \`${DEFAULT_PREFIX}bridge unlink_all\`.` + `unbridge all channels in a Revolt server, run \`${DEFAULT_PREFIX}bridge unlink_all\`.\n`
+ `To view bridge info about a particular message, run \`${DEFAULT_PREFIX}bridge info\` `
+ `while replying to the message.`
} }
] ]
}); });

View file

@ -13,6 +13,7 @@ import { VoteEntry } from './bot/commands/votekick';
import ScannedUser from './struct/ScannedUser'; import ScannedUser from './struct/ScannedUser';
import BridgeRequest from './struct/BridgeRequest'; import BridgeRequest from './struct/BridgeRequest';
import BridgeConfig from './struct/BridgeConfig'; import BridgeConfig from './struct/BridgeConfig';
import BridgedMessage from './struct/BridgedMessage';
logger.info('Initializing client'); logger.info('Initializing client');
@ -36,6 +37,7 @@ const dbs = {
VOTEKICKS: db.get<VoteEntry>('votekicks'), VOTEKICKS: db.get<VoteEntry>('votekicks'),
SCANNED_USERS: db.get<ScannedUser>('scanned_users'), SCANNED_USERS: db.get<ScannedUser>('scanned_users'),
BRIDGE_CONFIG: db.get<BridgeConfig>('bridge_config'), BRIDGE_CONFIG: db.get<BridgeConfig>('bridge_config'),
BRIDGED_MESSAGES: db.get<BridgedMessage>('bridged_messages'),
BRIDGE_REQUESTS: db.get<BridgeRequest>('bridge_requests'), BRIDGE_REQUESTS: db.get<BridgeRequest>('bridge_requests'),
} }

View file

@ -0,0 +1,18 @@
export default class {
origin: 'discord'|'revolt';
discord: {
messageId?: string;
}
revolt: {
messageId?: string;
nonce?: string;
}
// Required to sync message deletions
channels?: {
discord: string;
revolt: string;
}
}

View file

@ -600,7 +600,7 @@ require-at@^1.0.6:
resolved "https://registry.yarnpkg.com/require-at/-/require-at-1.0.6.tgz#9eb7e3c5e00727f5a4744070a7f560d4de4f6e6a" resolved "https://registry.yarnpkg.com/require-at/-/require-at-1.0.6.tgz#9eb7e3c5e00727f5a4744070a7f560d4de4f6e6a"
integrity sha512-7i1auJbMUrXEAZCOQ0VNJgmcT2VOKPRl2YGJwgpHpC9CE91Mv4/4UYIUm4chGJaI381ZDq1JUicFii64Hapd8g== integrity sha512-7i1auJbMUrXEAZCOQ0VNJgmcT2VOKPRl2YGJwgpHpC9CE91Mv4/4UYIUm4chGJaI381ZDq1JUicFii64Hapd8g==
revolt-api@0.5.3-rc.15: revolt-api@0.5.3-rc.15, revolt-api@^0.5.3-rc.15:
version "0.5.3-rc.15" version "0.5.3-rc.15"
resolved "https://registry.yarnpkg.com/revolt-api/-/revolt-api-0.5.3-rc.15.tgz#abd08dd8109d0ca31be118461eabbeb6c3b7792e" resolved "https://registry.yarnpkg.com/revolt-api/-/revolt-api-0.5.3-rc.15.tgz#abd08dd8109d0ca31be118461eabbeb6c3b7792e"
integrity sha512-MYin3U+KoObNkILPf2cz+FPperynExkUu7CjzurMJCRvBncpnhb2czvWDvnhLDKBHlpo8W597xNqzQnaklV4ug== integrity sha512-MYin3U+KoObNkILPf2cz+FPperynExkUu7CjzurMJCRvBncpnhb2czvWDvnhLDKBHlpo8W597xNqzQnaklV4ug==