add /bridge info
command
This commit is contained in:
parent
b65a1bd70c
commit
a18a0f9c65
5 changed files with 97 additions and 5 deletions
|
@ -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"
|
||||||
},
|
},
|
||||||
|
|
|
@ -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.`
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
|
@ -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'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
18
bot/src/struct/BridgedMessage.ts
Normal file
18
bot/src/struct/BridgedMessage.ts
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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==
|
||||||
|
|
Loading…
Reference in a new issue