mirror of
https://github.com/janderedev/automod.git
synced 2024-12-22 10:45:27 +00:00
Migrate to revolt.js 7.0
This commit is contained in:
parent
9685bc5608
commit
b3ee6094ce
4
.gitmodules
vendored
Normal file
4
.gitmodules
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[submodule "revolt.js"]
|
||||||
|
path = revolt.js
|
||||||
|
url = https://github.com/revoltchat/revolt.js
|
||||||
|
branch = insert/feat/store-rewrite
|
|
@ -13,7 +13,6 @@
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@janderedev/revolt.js": "latest",
|
|
||||||
"@types/monk": "^6.0.0",
|
"@types/monk": "^6.0.0",
|
||||||
"automod": "^0.1.0",
|
"automod": "^0.1.0",
|
||||||
"axios": "^0.22.0",
|
"axios": "^0.22.0",
|
||||||
|
@ -24,7 +23,8 @@
|
||||||
"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.16",
|
"revolt-api": "latest",
|
||||||
|
"revolt.js": "^7.0.0",
|
||||||
"ulid": "^2.3.0",
|
"ulid": "^2.3.0",
|
||||||
"xlsx": "^0.17.3"
|
"xlsx": "^0.17.3"
|
||||||
},
|
},
|
||||||
|
@ -33,6 +33,7 @@
|
||||||
},
|
},
|
||||||
"packageManager": "yarn@3.2.1",
|
"packageManager": "yarn@3.2.1",
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"automod": "portal:../lib"
|
"automod": "portal:../lib",
|
||||||
|
"revolt.js": "portal:../revolt.js"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { commands, DEFAULT_PREFIX, ownerIDs } from "../../modules/command_handle
|
||||||
import child_process from 'child_process';
|
import child_process from 'child_process';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { User } from "@janderedev/revolt.js/dist/maps/Users";
|
import { User } from "revolt.js";
|
||||||
import { adminBotLog } from "../../logging";
|
import { adminBotLog } from "../../logging";
|
||||||
import CommandCategory from "../../../struct/commands/CommandCategory";
|
import CommandCategory from "../../../struct/commands/CommandCategory";
|
||||||
import { getMutualServers, parseUserOrId } from "../../util";
|
import { getMutualServers, parseUserOrId } from "../../util";
|
||||||
|
@ -17,11 +17,11 @@ const BLACKLIST_MESSAGE = (username: string) => `\`@${username}\` has been banne
|
||||||
const sudoOverrides: { [key: string]: number|null } = {}
|
const sudoOverrides: { [key: string]: number|null } = {}
|
||||||
|
|
||||||
const isSudo = (user: User): boolean => {
|
const isSudo = (user: User): boolean => {
|
||||||
return !!(sudoOverrides[user._id] && sudoOverrides[user._id]! > Date.now());
|
return !!(sudoOverrides[user.id] && sudoOverrides[user.id]! > Date.now());
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateSudoTimeout = (user: User) => {
|
const updateSudoTimeout = (user: User) => {
|
||||||
sudoOverrides[user._id] = Date.now() + (1000 * 60 * 5);
|
sudoOverrides[user.id] = Date.now() + (1000 * 60 * 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
const getCommitHash = (): Promise<string|null> => new Promise((resolve) => {
|
const getCommitHash = (): Promise<string|null> => new Promise((resolve) => {
|
||||||
|
@ -57,23 +57,22 @@ export default {
|
||||||
const pjson = JSON.parse((await fs.promises.readFile(path.join(process.cwd(), 'package.json'))).toString());
|
const pjson = JSON.parse((await fs.promises.readFile(path.join(process.cwd(), 'package.json'))).toString());
|
||||||
let msg = `# AutoMod stats\n`
|
let msg = `# AutoMod stats\n`
|
||||||
+ `### Cache\n`
|
+ `### Cache\n`
|
||||||
+ `Servers: \`${client.servers.size}\`\n`
|
+ `Servers: \`${client.servers.size()}\`\n`
|
||||||
+ `Channels: \`${client.channels.size}\`\n`
|
+ `Channels: \`${client.channels.size()}\`\n`
|
||||||
+ `Users: \`${client.users.size}\`\n`
|
+ `Users: \`${client.users.size()}\`\n`
|
||||||
+ `### Misc\n`
|
+ `### Misc\n`
|
||||||
+ `Command count: \`${commands.length}\`\n`
|
+ `Command count: \`${commands.length}\`\n`
|
||||||
+ `Environment: \`${process.env.NODE_ENV || 'testing'}\`\n`
|
+ `Environment: \`${process.env.NODE_ENV || 'testing'}\`\n`
|
||||||
+ `Commit hash: \`${await getCommitHash() || 'Unknown'}\`\n`
|
+ `Commit hash: \`${await getCommitHash() || 'Unknown'}\`\n`
|
||||||
+ `### Packages\n`
|
+ `### Packages\n`
|
||||||
+ `revolt.js: \`${pjson.dependencies['@janderedev/revolt.js']}\`\n`
|
+ `revolt.js: \`${pjson.dependencies['revolt.js']}\`\n`
|
||||||
+ `discord.js: \`${pjson.dependencies['discord.js']}\`\n`
|
+ `discord.js: \`${pjson.dependencies['discord.js']}\`\n`
|
||||||
+ `axios: \`${pjson.dependencies['axios']}\`\n`
|
+ `axios: \`${pjson.dependencies['axios']}\`\n`
|
||||||
+ `log75: \`${pjson.dependencies['log75']}\`\n`
|
+ `log75: \`${pjson.dependencies['log75']}\`\n`
|
||||||
+ `typescript: \`${pjson.devDependencies['typescript']}\`\n`
|
+ `typescript: \`${pjson.devDependencies['typescript']}\`\n`
|
||||||
+ `### Connection\n`
|
+ `### Connection\n`
|
||||||
+ `API Endpoint: \`${client.apiURL}\`\n`
|
+ `API Endpoint: \`${client.options.baseURL}\`\n`
|
||||||
+ `Heartbeat: \`${client.heartbeat}\`\n`
|
+ `Ping: \`${client.events.ping() ?? 'Unknown'}\`\n`
|
||||||
+ `Ping: \`${client.websocket.ping ?? 'Unknown'}\`\n`
|
|
||||||
+ `### Bot configuration\n`
|
+ `### Bot configuration\n`
|
||||||
+ `Owners: \`${ownerIDs.length}\` (${ownerIDs.join(', ')})\n`;
|
+ `Owners: \`${ownerIDs.length}\` (${ownerIDs.join(', ')})\n`;
|
||||||
|
|
||||||
|
@ -87,7 +86,7 @@ export default {
|
||||||
case 'on': {
|
case 'on': {
|
||||||
if (isSudo(message.author!)) return message.reply('You are already in sudo mode!');
|
if (isSudo(message.author!)) return message.reply('You are already in sudo mode!');
|
||||||
|
|
||||||
sudoOverrides[message.author_id] = Date.now() + (1000 * 60 * 5);
|
sudoOverrides[message.authorId!] = Date.now() + (1000 * 60 * 5);
|
||||||
|
|
||||||
let msg = `# %emoji% Sudo mode enabled\n`
|
let msg = `# %emoji% Sudo mode enabled\n`
|
||||||
+ `In sudo mode, you will be able to run any command regardless of your server permissions.\n`
|
+ `In sudo mode, you will be able to run any command regardless of your server permissions.\n`
|
||||||
|
@ -106,7 +105,7 @@ export default {
|
||||||
case 'off': {
|
case 'off': {
|
||||||
if (!isSudo(message.author!)) return message.reply('You currently not in sudo mode.');
|
if (!isSudo(message.author!)) return message.reply('You currently not in sudo mode.');
|
||||||
|
|
||||||
sudoOverrides[message.author_id] = null;
|
sudoOverrides[message.authorId!] = null;
|
||||||
|
|
||||||
let msg = `# %emoji% Sudo mode disabled.`;
|
let msg = `# %emoji% Sudo mode disabled.`;
|
||||||
const sentMsg = await message.reply(msg.replace('%emoji%', ':unlock:'), false);
|
const sentMsg = await message.reply(msg.replace('%emoji%', ':unlock:'), false);
|
||||||
|
@ -138,7 +137,7 @@ export default {
|
||||||
const target = await parseUserOrId(args.shift() || '');
|
const target = await parseUserOrId(args.shift() || '');
|
||||||
if (!target) return message.reply('Specified user could not be found.');
|
if (!target) return message.reply('Specified user could not be found.');
|
||||||
|
|
||||||
const res = await dbs.USERS.findOne({ id: target._id });
|
const res = await dbs.USERS.findOne({ id: target.id });
|
||||||
|
|
||||||
if (!res) await message.reply(`Nothing stored about this user.`);
|
if (!res) await message.reply(`Nothing stored about this user.`);
|
||||||
else await message.reply(`\`\`\`json\n${JSON.stringify(res, null, 4)}\n\`\`\``);
|
else await message.reply(`\`\`\`json\n${JSON.stringify(res, null, 4)}\n\`\`\``);
|
||||||
|
@ -149,12 +148,12 @@ export default {
|
||||||
case 'blacklist': {
|
case 'blacklist': {
|
||||||
const target = await parseUserOrId(args.shift() || '');
|
const target = await parseUserOrId(args.shift() || '');
|
||||||
if (!target) return message.reply('Specified user could not be found.');
|
if (!target) return message.reply('Specified user could not be found.');
|
||||||
if (target._id == message.author_id) return message.reply(`no`);
|
if (target.id == message.authorId) return message.reply(`no`);
|
||||||
|
|
||||||
await dbs.USERS.update({
|
await dbs.USERS.update({
|
||||||
id: target._id,
|
id: target.id,
|
||||||
}, {
|
}, {
|
||||||
$setOnInsert: { id: target._id },
|
$setOnInsert: { id: target.id },
|
||||||
$set: { globalBlacklist: true }
|
$set: { globalBlacklist: true }
|
||||||
}, { upsert: true });
|
}, { upsert: true });
|
||||||
|
|
||||||
|
@ -167,23 +166,23 @@ export default {
|
||||||
const mutuals = getMutualServers(target);
|
const mutuals = getMutualServers(target);
|
||||||
for (const server of mutuals) {
|
for (const server of mutuals) {
|
||||||
if (server.havePermission('BanMembers')) {
|
if (server.havePermission('BanMembers')) {
|
||||||
const config = await dbs.SERVERS.findOne({ id: server._id });
|
const config = await dbs.SERVERS.findOne({ id: server.id });
|
||||||
if (config?.allowBlacklistedUsers) continue;
|
if (config?.allowBlacklistedUsers) continue;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await server.banUser(target._id, {
|
await server.banUser(target.id, {
|
||||||
reason: BLACKLIST_BAN_REASON,
|
reason: BLACKLIST_BAN_REASON,
|
||||||
});
|
});
|
||||||
bannedServers++;
|
bannedServers++;
|
||||||
|
|
||||||
if (server.system_messages?.user_banned) {
|
if (server.systemMessages?.user_banned) {
|
||||||
const channel = server.channels.find(c => c!._id == server.system_messages!.user_banned);
|
const channel = server.channels.find(c => c!.id == server.systemMessages!.user_banned);
|
||||||
if (channel && channel.havePermission('SendMessage')) {
|
if (channel && channel.havePermission('SendMessage')) {
|
||||||
await channel.sendMessage(BLACKLIST_MESSAGE(target.username));
|
await channel.sendMessage(BLACKLIST_MESSAGE(target.username));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
console.error(`Failed to ban in ${server._id}: ${e}`);
|
console.error(`Failed to ban in ${server.id}: ${e}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -205,9 +204,9 @@ export default {
|
||||||
if (!target) return message.reply('Specified user could not be found.');
|
if (!target) return message.reply('Specified user could not be found.');
|
||||||
|
|
||||||
await dbs.USERS.update({
|
await dbs.USERS.update({
|
||||||
id: target._id,
|
id: target.id,
|
||||||
}, {
|
}, {
|
||||||
$setOnInsert: { id: target._id },
|
$setOnInsert: { id: target.id },
|
||||||
$set: { globalBlacklist: false }
|
$set: { globalBlacklist: false }
|
||||||
}, { upsert: true });
|
}, { upsert: true });
|
||||||
|
|
||||||
|
@ -221,9 +220,9 @@ export default {
|
||||||
if (!target) return message.reply('Specified user could not be found.');
|
if (!target) return message.reply('Specified user could not be found.');
|
||||||
|
|
||||||
await dbs.USERS.update({
|
await dbs.USERS.update({
|
||||||
id: target._id,
|
id: target.id,
|
||||||
}, {
|
}, {
|
||||||
$setOnInsert: { id: target._id },
|
$setOnInsert: { id: target.id },
|
||||||
$set: { blacklistReason: args.join(' ') || undefined }
|
$set: { blacklistReason: args.join(' ') || undefined }
|
||||||
}, { upsert: true });
|
}, { upsert: true });
|
||||||
|
|
||||||
|
@ -235,12 +234,12 @@ export default {
|
||||||
case 'ignore': {
|
case 'ignore': {
|
||||||
const target = await parseUserOrId(args.shift() || '');
|
const target = await parseUserOrId(args.shift() || '');
|
||||||
if (!target) return message.reply('Specified user could not be found.');
|
if (!target) return message.reply('Specified user could not be found.');
|
||||||
if (target._id == message.author_id) return message.reply(`no`);
|
if (target.id == message.authorId) return message.reply(`no`);
|
||||||
|
|
||||||
await dbs.USERS.update(
|
await dbs.USERS.update(
|
||||||
{ id: target._id },
|
{ id: target.id },
|
||||||
{
|
{
|
||||||
$setOnInsert: { id: target._id },
|
$setOnInsert: { id: target.id },
|
||||||
$set: { ignore: true },
|
$set: { ignore: true },
|
||||||
},
|
},
|
||||||
{ upsert: true }
|
{ upsert: true }
|
||||||
|
@ -254,12 +253,12 @@ export default {
|
||||||
case 'unignore': {
|
case 'unignore': {
|
||||||
const target = await parseUserOrId(args.shift() || '');
|
const target = await parseUserOrId(args.shift() || '');
|
||||||
if (!target) return message.reply('Specified user could not be found.');
|
if (!target) return message.reply('Specified user could not be found.');
|
||||||
if (target._id == message.author_id) return message.reply(`no`);
|
if (target.id == message.authorId) return message.reply(`no`);
|
||||||
|
|
||||||
await dbs.USERS.update(
|
await dbs.USERS.update(
|
||||||
{ id: target._id },
|
{ id: target.id },
|
||||||
{
|
{
|
||||||
$setOnInsert: { id: target._id },
|
$setOnInsert: { id: target.id },
|
||||||
$set: { ignore: false },
|
$set: { ignore: false },
|
||||||
},
|
},
|
||||||
{ upsert: true }
|
{ upsert: true }
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import SimpleCommand from "../../../struct/commands/SimpleCommand";
|
import SimpleCommand from "../../../struct/commands/SimpleCommand";
|
||||||
import { hasPerm, parseUser } from "../../util";
|
import { parseUser } from "../../util";
|
||||||
import { client, dbs } from "../../..";
|
import { client, dbs } from "../../..";
|
||||||
import { User } from "@janderedev/revolt.js/dist/maps/Users";
|
import { User } from "revolt.js";
|
||||||
import MessageCommandContext from "../../../struct/MessageCommandContext";
|
import MessageCommandContext from "../../../struct/MessageCommandContext";
|
||||||
import CommandCategory from "../../../struct/commands/CommandCategory";
|
import CommandCategory from "../../../struct/commands/CommandCategory";
|
||||||
|
|
||||||
|
@ -14,10 +14,10 @@ export default {
|
||||||
syntax: SYNTAX,
|
syntax: SYNTAX,
|
||||||
category: CommandCategory.Config,
|
category: CommandCategory.Config,
|
||||||
run: async (message: MessageCommandContext, args: string[]) => {
|
run: async (message: MessageCommandContext, args: string[]) => {
|
||||||
if (!hasPerm(message.member!, 'ManageServer'))
|
if (!message.member?.hasPermission(message.member.server!, 'ManageServer'))
|
||||||
return message.reply('You need **ManageServer** permission to use this command.');
|
return message.reply('You need **ManageServer** permission to use this command.');
|
||||||
|
|
||||||
let config = await dbs.SERVERS.findOne({ id: message.serverContext._id });
|
let config = await dbs.SERVERS.findOne({ id: message.serverContext.id });
|
||||||
let admins = config?.botManagers ?? [];
|
let admins = config?.botManagers ?? [];
|
||||||
let user: User|null;
|
let user: User|null;
|
||||||
|
|
||||||
|
@ -28,12 +28,12 @@ export default {
|
||||||
user = await parseUser(args[1]);
|
user = await parseUser(args[1]);
|
||||||
if (!user) return message.reply('I can\'t find that user.');
|
if (!user) return message.reply('I can\'t find that user.');
|
||||||
|
|
||||||
if (admins.indexOf(user._id) > -1) return message.reply('This user is already added as bot admin.');
|
if (admins.indexOf(user.id) > -1) return message.reply('This user is already added as bot admin.');
|
||||||
|
|
||||||
admins.push(user._id);
|
admins.push(user.id);
|
||||||
await dbs.SERVERS.update({ id: message.serverContext._id }, { $set: { botManagers: admins } });
|
await dbs.SERVERS.update({ id: message.serverContext.id }, { $set: { botManagers: admins } });
|
||||||
|
|
||||||
message.reply(`✅ Added [@${user.username}](/@${user._id}) to bot admins.`);
|
message.reply(`✅ Added [@${user.username}](/@${user.id}) to bot admins.`);
|
||||||
break;
|
break;
|
||||||
case 'remove':
|
case 'remove':
|
||||||
case 'delete':
|
case 'delete':
|
||||||
|
@ -43,12 +43,12 @@ export default {
|
||||||
user = await parseUser(args[1]);
|
user = await parseUser(args[1]);
|
||||||
if (!user) return message.reply('I can\'t find that user.');
|
if (!user) return message.reply('I can\'t find that user.');
|
||||||
|
|
||||||
if (admins.indexOf(user._id) == -1) return message.reply('This user is not added as bot admin.');
|
if (admins.indexOf(user.id) == -1) return message.reply('This user is not added as bot admin.');
|
||||||
|
|
||||||
admins = admins.filter(a => a != user?._id);
|
admins = admins.filter(a => a != user?.id);
|
||||||
await dbs.SERVERS.update({ id: message.serverContext._id }, { $set: { botManagers: admins } });
|
await dbs.SERVERS.update({ id: message.serverContext.id }, { $set: { botManagers: admins } });
|
||||||
|
|
||||||
message.reply(`✅ Removed [@${user.username}](/@${user._id}) from bot admins.`);
|
message.reply(`✅ Removed [@${user.username}](/@${user.id}) from bot admins.`);
|
||||||
break;
|
break;
|
||||||
case 'list':
|
case 'list':
|
||||||
case 'ls':
|
case 'ls':
|
||||||
|
|
|
@ -7,7 +7,7 @@ import SimpleCommand from "../../../struct/commands/SimpleCommand";
|
||||||
import MessageCommandContext from "../../../struct/MessageCommandContext";
|
import MessageCommandContext from "../../../struct/MessageCommandContext";
|
||||||
import { checkMessageForFilteredWords } from "../../modules/antispam";
|
import { checkMessageForFilteredWords } from "../../modules/antispam";
|
||||||
import { DEFAULT_PREFIX } from "../../modules/command_handler";
|
import { DEFAULT_PREFIX } from "../../modules/command_handler";
|
||||||
import { embed, EmbedColor, getAutumnURL, getDmChannel, isBotManager, NO_MANAGER_MSG, sanitizeMessageContent } from "../../util";
|
import { embed, EmbedColor, getDmChannel, isBotManager, NO_MANAGER_MSG, sanitizeMessageContent } from "../../util";
|
||||||
|
|
||||||
const WORDLIST_DEFAULT_MESSAGE = '<@{{user_id}}>, the message you sent contained a blocked word.';
|
const WORDLIST_DEFAULT_MESSAGE = '<@{{user_id}}>, the message you sent contained a blocked word.';
|
||||||
|
|
||||||
|
@ -28,10 +28,10 @@ export default {
|
||||||
return message.reply('Your server is currently listed in server discovery. As part of Revolt\'s [Discover Guidelines](<https://support.revolt.chat/kb/safety/discover-guidelines>), all servers on Discover are enrolled to AutoMod\'s antispam features.');
|
return message.reply('Your server is currently listed in server discovery. As part of Revolt\'s [Discover Guidelines](<https://support.revolt.chat/kb/safety/discover-guidelines>), all servers on Discover are enrolled to AutoMod\'s antispam features.');
|
||||||
}
|
}
|
||||||
|
|
||||||
await dbs.SERVERS.update({ id: message.serverContext._id }, { $set: { allowBlacklistedUsers: true } });
|
await dbs.SERVERS.update({ id: message.serverContext.id }, { $set: { allowBlacklistedUsers: true } });
|
||||||
await message.reply('Globally blacklisted users will no longer get banned in this server. Previously banned users will need to be unbanned manually.');
|
await message.reply('Globally blacklisted users will no longer get banned in this server. Previously banned users will need to be unbanned manually.');
|
||||||
} else if (args[0] == 'no') {
|
} else if (args[0] == 'no') {
|
||||||
await dbs.SERVERS.update({ id: message.serverContext._id }, { $set: { allowBlacklistedUsers: false } });
|
await dbs.SERVERS.update({ id: message.serverContext.id }, { $set: { allowBlacklistedUsers: false } });
|
||||||
await message.reply('Globally blacklisted users will now get banned in this server.');
|
await message.reply('Globally blacklisted users will now get banned in this server.');
|
||||||
} else {
|
} else {
|
||||||
await message.reply(`Please specify either 'yes' or 'no' to toggle this setting.`);
|
await message.reply(`Please specify either 'yes' or 'no' to toggle this setting.`);
|
||||||
|
@ -41,7 +41,7 @@ export default {
|
||||||
|
|
||||||
case 'spam_detection': {
|
case 'spam_detection': {
|
||||||
if (args[0] == 'on') {
|
if (args[0] == 'on') {
|
||||||
await dbs.SERVERS.update({ id: message.serverContext._id }, { $set: { antispamEnabled: true } });
|
await dbs.SERVERS.update({ id: message.serverContext.id }, { $set: { antispamEnabled: true } });
|
||||||
await message.reply('Spam detection is now enabled in this server.\nIf a user is wrongfully kicked '
|
await message.reply('Spam detection is now enabled in this server.\nIf a user is wrongfully kicked '
|
||||||
+ 'or banned, please report it here: https://rvlt.gg/jan\n\n'
|
+ 'or banned, please report it here: https://rvlt.gg/jan\n\n'
|
||||||
+ 'Please make sure to grant AutoMod permission to **Kick**, **Ban** and **Manage Messages**!');
|
+ 'Please make sure to grant AutoMod permission to **Kick**, **Ban** and **Manage Messages**!');
|
||||||
|
@ -50,11 +50,11 @@ export default {
|
||||||
return message.reply('Your server is currently listed in server discovery. As part of Revolt\'s [Discover Guidelines](<https://support.revolt.chat/kb/safety/discover-guidelines>), all servers on Discover are enrolled to AutoMod\'s antispam features.');
|
return message.reply('Your server is currently listed in server discovery. As part of Revolt\'s [Discover Guidelines](<https://support.revolt.chat/kb/safety/discover-guidelines>), all servers on Discover are enrolled to AutoMod\'s antispam features.');
|
||||||
}
|
}
|
||||||
|
|
||||||
await dbs.SERVERS.update({ id: message.serverContext._id }, { $set: { antispamEnabled: false } });
|
await dbs.SERVERS.update({ id: message.serverContext.id }, { $set: { antispamEnabled: false } });
|
||||||
await message.reply('Spam detection is now disabled in this server.');
|
await message.reply('Spam detection is now disabled in this server.');
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
const cfg = await dbs.SERVERS.findOne({ id: message.serverContext._id });
|
const cfg = await dbs.SERVERS.findOne({ id: message.serverContext.id });
|
||||||
await message.reply(`Spam detection is currently **${cfg?.antispamEnabled ? 'enabled' : 'disabled'}**. `
|
await message.reply(`Spam detection is currently **${cfg?.antispamEnabled ? 'enabled' : 'disabled'}**. `
|
||||||
+ `Please specify either 'on' or 'off' to toggle this setting.`);
|
+ `Please specify either 'on' or 'off' to toggle this setting.`);
|
||||||
}
|
}
|
||||||
|
@ -80,48 +80,48 @@ export default {
|
||||||
|
|
||||||
const channel = client.channels.get(channelInput);
|
const channel = client.channels.get(channelInput);
|
||||||
if (!channel) return message.reply('I can\'t find that channel.');
|
if (!channel) return message.reply('I can\'t find that channel.');
|
||||||
if (channel.server_id != message.channel?.server_id) return message.reply('That channel is not part of this server!');
|
if (channel.serverId != message.channel?.serverId) return message.reply('That channel is not part of this server!');
|
||||||
if (!channel.havePermission('SendMessage')) return message.reply('I don\'t have permission to **send messages** in that channel.');
|
if (!channel.havePermission('SendMessage')) return message.reply('I don\'t have permission to **send messages** in that channel.');
|
||||||
if (!channel.havePermission('SendEmbeds')) return message.reply('I don\'t have permission to **send embeds** in that channel.');
|
if (!channel.havePermission('SendEmbeds')) return message.reply('I don\'t have permission to **send embeds** in that channel.');
|
||||||
|
|
||||||
switch(args[0]?.toLowerCase()) {
|
switch(args[0]?.toLowerCase()) {
|
||||||
case 'messageupdate': {
|
case 'messageupdate': {
|
||||||
await dbs.SERVERS.update(
|
await dbs.SERVERS.update(
|
||||||
{ id: message.channel!.server_id! },
|
{ id: message.channel!.serverId! },
|
||||||
{
|
{
|
||||||
$set: {
|
$set: {
|
||||||
'logs.messageUpdate.revolt': {
|
'logs.messageUpdate.revolt': {
|
||||||
channel: channel._id,
|
channel: channel.id,
|
||||||
type: 'EMBED',
|
type: 'EMBED',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
$setOnInsert: {
|
$setOnInsert: {
|
||||||
id: message.channel!.server_id!,
|
id: message.channel!.serverId!,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ upsert: true },
|
{ upsert: true },
|
||||||
);
|
);
|
||||||
await message.reply(`Bound message update logs to <#${channel._id}>!`);
|
await message.reply(`Bound message update logs to <#${channel.id}>!`);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'modaction': {
|
case 'modaction': {
|
||||||
await dbs.SERVERS.update(
|
await dbs.SERVERS.update(
|
||||||
{ id: message.channel!.server_id! },
|
{ id: message.channel!.serverId! },
|
||||||
{
|
{
|
||||||
$set: {
|
$set: {
|
||||||
'logs.modAction.revolt': {
|
'logs.modAction.revolt': {
|
||||||
channel: channel._id,
|
channel: channel.id,
|
||||||
type: 'EMBED',
|
type: 'EMBED',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
$setOnInsert: {
|
$setOnInsert: {
|
||||||
id: message.channel!.server_id!,
|
id: message.channel!.serverId!,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ upsert: true },
|
{ upsert: true },
|
||||||
);
|
);
|
||||||
await message.reply(`Bound moderation logs to <#${channel._id}>!`);
|
await message.reply(`Bound moderation logs to <#${channel.id}>!`);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,11 +133,11 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'filter': {
|
case 'filter': {
|
||||||
const config = await dbs.SERVERS.findOne({ id: message.channel!.server_id! });
|
const config = await dbs.SERVERS.findOne({ id: message.channel!.serverId! });
|
||||||
switch(args.shift()?.toLowerCase()) {
|
switch(args.shift()?.toLowerCase()) {
|
||||||
case 'enable': {
|
case 'enable': {
|
||||||
await dbs.SERVERS.update(
|
await dbs.SERVERS.update(
|
||||||
{ id: message.channel!.server_id! },
|
{ id: message.channel!.serverId! },
|
||||||
{ $set: { wordlistEnabled: true } },
|
{ $set: { wordlistEnabled: true } },
|
||||||
{ upsert: true },
|
{ upsert: true },
|
||||||
);
|
);
|
||||||
|
@ -152,7 +152,7 @@ export default {
|
||||||
}
|
}
|
||||||
case 'disable': {
|
case 'disable': {
|
||||||
await dbs.SERVERS.update(
|
await dbs.SERVERS.update(
|
||||||
{ id: message.channel!.server_id! },
|
{ id: message.channel!.serverId! },
|
||||||
{ $set: { wordlistEnabled: false } },
|
{ $set: { wordlistEnabled: false } },
|
||||||
{ upsert: true },
|
{ upsert: true },
|
||||||
);
|
);
|
||||||
|
@ -172,7 +172,7 @@ export default {
|
||||||
if (config?.wordlist?.find(w => w.word == word)) return await message.reply('That word is already on the list!');
|
if (config?.wordlist?.find(w => w.word == word)) return await message.reply('That word is already on the list!');
|
||||||
|
|
||||||
await dbs.SERVERS.update(
|
await dbs.SERVERS.update(
|
||||||
{ id: message.channel!.server_id! },
|
{ id: message.channel!.serverId! },
|
||||||
{ $push: { wordlist: { strictness, word } } },
|
{ $push: { wordlist: { strictness, word } } },
|
||||||
{ upsert: true },
|
{ upsert: true },
|
||||||
);
|
);
|
||||||
|
@ -187,7 +187,7 @@ export default {
|
||||||
|
|
||||||
if (!config?.wordlist?.find(w => w.word == word)) return await message.reply('That word is not on the list.');
|
if (!config?.wordlist?.find(w => w.word == word)) return await message.reply('That word is not on the list.');
|
||||||
await dbs.SERVERS.update(
|
await dbs.SERVERS.update(
|
||||||
{ id: message.channel!.server_id! },
|
{ id: message.channel!.serverId! },
|
||||||
{ $pull: { wordlist: { word } } },
|
{ $pull: { wordlist: { word } } },
|
||||||
{ upsert: true },
|
{ upsert: true },
|
||||||
);
|
);
|
||||||
|
@ -199,15 +199,15 @@ export default {
|
||||||
case 'show': {
|
case 'show': {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append(
|
formData.append(
|
||||||
`wordlist_${message.channel?.server_id}`,
|
`wordlist_${message.channel?.serverId}`,
|
||||||
config?.wordlist?.map(w => `${w.strictness}\t${w.word}`).join('\n') ?? '',
|
config?.wordlist?.map(w => `${w.strictness}\t${w.word}`).join('\n') ?? '',
|
||||||
`wordlist_${message.channel?.server_id}.txt`
|
`wordlist_${message.channel?.serverId}.txt`
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const channel = await getDmChannel(message.author_id);
|
const channel = await getDmChannel(message.authorId!);
|
||||||
const res = await axios.post(
|
const res = await axios.post(
|
||||||
`${await getAutumnURL()}/attachments`,
|
`${client.configuration?.features.autumn.url}/attachments`,
|
||||||
formData,
|
formData,
|
||||||
{ headers: formData.getHeaders(), responseType: 'json' }
|
{ headers: formData.getHeaders(), responseType: 'json' }
|
||||||
);
|
);
|
||||||
|
@ -244,7 +244,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
await dbs.SERVERS.update(
|
await dbs.SERVERS.update(
|
||||||
{ id: message.channel!.server_id! },
|
{ id: message.channel!.serverId! },
|
||||||
{ $set: { wordlistAction: { action: config?.wordlistAction?.action ?? 'LOG', message: msg } } },
|
{ $set: { wordlistAction: { action: config?.wordlistAction?.action ?? 'LOG', message: msg } } },
|
||||||
{ upsert: true },
|
{ upsert: true },
|
||||||
);
|
);
|
||||||
|
@ -281,7 +281,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
await dbs.SERVERS.update(
|
await dbs.SERVERS.update(
|
||||||
{ id: message.channel!.server_id! },
|
{ id: message.channel!.serverId! },
|
||||||
{ $set: { wordlistAction: {
|
{ $set: { wordlistAction: {
|
||||||
action: action as any,
|
action: action as any,
|
||||||
message: config?.wordlistAction?.message ?? WORDLIST_DEFAULT_MESSAGE
|
message: config?.wordlistAction?.message ?? WORDLIST_DEFAULT_MESSAGE
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Message } from "@janderedev/revolt.js";
|
import { Message } from "revolt.js";
|
||||||
import { ulid } from "ulid";
|
import { ulid } from "ulid";
|
||||||
import { SendableEmbed } from "revolt-api";
|
import { SendableEmbed } from "revolt-api";
|
||||||
import { CONFIG_KEYS } from "automod/dist/misc/bridge_config_keys";
|
import { CONFIG_KEYS } from "automod/dist/misc/bridge_config_keys";
|
||||||
|
@ -30,20 +30,20 @@ export default {
|
||||||
return message.reply(NO_MANAGER_MSG);
|
return message.reply(NO_MANAGER_MSG);
|
||||||
|
|
||||||
const count = await dbs.BRIDGE_CONFIG.count({
|
const count = await dbs.BRIDGE_CONFIG.count({
|
||||||
revolt: message.channel_id,
|
revolt: message.channelId,
|
||||||
});
|
});
|
||||||
if (count)
|
if (count)
|
||||||
return message.reply(`This channel is already bridged.`);
|
return message.reply(`This channel is already bridged.`);
|
||||||
|
|
||||||
// Invalidate previous bridge request
|
// Invalidate previous bridge request
|
||||||
await dbs.BRIDGE_REQUESTS.remove({
|
await dbs.BRIDGE_REQUESTS.remove({
|
||||||
revolt: message.channel_id,
|
revolt: message.channelId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const reqId = ulid();
|
const reqId = ulid();
|
||||||
await dbs.BRIDGE_REQUESTS.insert({
|
await dbs.BRIDGE_REQUESTS.insert({
|
||||||
id: reqId,
|
id: reqId,
|
||||||
revolt: message.channel_id,
|
revolt: message.channelId,
|
||||||
expires: Date.now() + 1000 * 60 * 15,
|
expires: Date.now() + 1000 * 60 * 15,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ export default {
|
||||||
return message.reply(NO_MANAGER_MSG);
|
return message.reply(NO_MANAGER_MSG);
|
||||||
|
|
||||||
const res = await dbs.BRIDGE_CONFIG.remove({
|
const res = await dbs.BRIDGE_CONFIG.remove({
|
||||||
revolt: message.channel_id,
|
revolt: message.channelId,
|
||||||
});
|
});
|
||||||
if (res.deletedCount) await message.reply(`Channel unlinked!`);
|
if (res.deletedCount) await message.reply(`Channel unlinked!`);
|
||||||
else
|
else
|
||||||
|
@ -86,7 +86,7 @@ export default {
|
||||||
return message.reply(NO_MANAGER_MSG);
|
return message.reply(NO_MANAGER_MSG);
|
||||||
|
|
||||||
const query = {
|
const query = {
|
||||||
revolt: { $in: message.channel?.server?.channel_ids || [] },
|
revolt: { $in: Array.from(message.channel?.server?.channelIds.values() ?? []) },
|
||||||
};
|
};
|
||||||
if (args[1] == "CONFIRM") {
|
if (args[1] == "CONFIRM") {
|
||||||
const res = await dbs.BRIDGE_CONFIG.remove(query);
|
const res = await dbs.BRIDGE_CONFIG.remove(query);
|
||||||
|
@ -119,7 +119,7 @@ export default {
|
||||||
return message.reply(NO_MANAGER_MSG);
|
return message.reply(NO_MANAGER_MSG);
|
||||||
|
|
||||||
const links = await dbs.BRIDGE_CONFIG.find({
|
const links = await dbs.BRIDGE_CONFIG.find({
|
||||||
revolt: { $in: message.channel?.server?.channel_ids || [] },
|
revolt: { $in: Array.from(message.channel?.server?.channelIds.values() ?? []) },
|
||||||
});
|
});
|
||||||
|
|
||||||
await message.reply({
|
await message.reply({
|
||||||
|
@ -142,14 +142,14 @@ export default {
|
||||||
}
|
}
|
||||||
case "info": {
|
case "info": {
|
||||||
try {
|
try {
|
||||||
if (!message.reply_ids) {
|
if (!message.replyIds) {
|
||||||
return await message.reply(
|
return await message.reply(
|
||||||
"Please run this command again while replying to a message."
|
"Please run this command again while replying to a message."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
message.reply_ids.length > 1 &&
|
message.replyIds.length > 1 &&
|
||||||
!(await isModerator(message, false))
|
!(await isModerator(message, false))
|
||||||
) {
|
) {
|
||||||
return await message.reply(
|
return await message.reply(
|
||||||
|
@ -159,7 +159,7 @@ export default {
|
||||||
|
|
||||||
const messages = (
|
const messages = (
|
||||||
await Promise.allSettled(
|
await Promise.allSettled(
|
||||||
message.reply_ids?.map((m) =>
|
message.replyIds.map((m) =>
|
||||||
message.channel!.fetchMessage(m)
|
message.channel!.fetchMessage(m)
|
||||||
) || []
|
) || []
|
||||||
)
|
)
|
||||||
|
@ -179,7 +179,7 @@ export default {
|
||||||
messages.map(async (msg) => {
|
messages.map(async (msg) => {
|
||||||
const bridgeData =
|
const bridgeData =
|
||||||
await dbs.BRIDGED_MESSAGES.findOne({
|
await dbs.BRIDGED_MESSAGES.findOne({
|
||||||
"revolt.messageId": msg._id,
|
"revolt.messageId": msg.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
const embed: SendableEmbed = bridgeData
|
const embed: SendableEmbed = bridgeData
|
||||||
|
@ -237,7 +237,7 @@ export default {
|
||||||
}
|
}
|
||||||
case "status": {
|
case "status": {
|
||||||
const link = await dbs.BRIDGE_CONFIG.findOne({
|
const link = await dbs.BRIDGE_CONFIG.findOne({
|
||||||
revolt: message.channel_id,
|
revolt: message.channelId,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!link)
|
if (!link)
|
||||||
|
@ -291,7 +291,7 @@ export default {
|
||||||
|
|
||||||
if (!newVal) {
|
if (!newVal) {
|
||||||
const bridgeConfig = await dbs.BRIDGE_CONFIG.findOne({
|
const bridgeConfig = await dbs.BRIDGE_CONFIG.findOne({
|
||||||
revolt: message.channel_id,
|
revolt: message.channelId,
|
||||||
});
|
});
|
||||||
return await message.reply({
|
return await message.reply({
|
||||||
embeds: [
|
embeds: [
|
||||||
|
@ -316,10 +316,10 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
await dbs.BRIDGE_CONFIG.update(
|
await dbs.BRIDGE_CONFIG.update(
|
||||||
{ revolt: message.channel_id },
|
{ revolt: message.channelId },
|
||||||
{
|
{
|
||||||
$set: { [`config.${configKey}`]: newVal == "true" },
|
$set: { [`config.${configKey}`]: newVal == "true" },
|
||||||
$setOnInsert: { revolt: message.channel_id },
|
$setOnInsert: { revolt: message.channelId },
|
||||||
},
|
},
|
||||||
{ upsert: true }
|
{ upsert: true }
|
||||||
);
|
);
|
||||||
|
|
|
@ -23,7 +23,7 @@ export default {
|
||||||
|
|
||||||
const login: FindOneResult<PendingLogin> = await dbs.PENDING_LOGINS.findOne({
|
const login: FindOneResult<PendingLogin> = await dbs.PENDING_LOGINS.findOne({
|
||||||
code,
|
code,
|
||||||
user: message.author_id,
|
user: message.authorId,
|
||||||
confirmed: false,
|
confirmed: false,
|
||||||
exchanged: false,
|
exchanged: false,
|
||||||
invalid: false,
|
invalid: false,
|
||||||
|
@ -35,7 +35,7 @@ export default {
|
||||||
if (!login) return message.reply(`Unknown code. Make sure you're logged into the correct account.`);
|
if (!login) return message.reply(`Unknown code. Make sure you're logged into the correct account.`);
|
||||||
|
|
||||||
if (login.requirePhishingConfirmation) {
|
if (login.requirePhishingConfirmation) {
|
||||||
logger.info(`Showing phishing warning to ${message.author_id}`);
|
logger.info(`Showing phishing warning to ${message.authorId}`);
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
message.reply(
|
message.reply(
|
||||||
`# If someone told you to run this, stop!\n` +
|
`# If someone told you to run this, stop!\n` +
|
||||||
|
|
|
@ -20,8 +20,8 @@ export default {
|
||||||
|
|
||||||
if (code.toLowerCase() == 'all') {
|
if (code.toLowerCase() == 'all') {
|
||||||
const [resA, resB] = await Promise.all([
|
const [resA, resB] = await Promise.all([
|
||||||
dbs.PENDING_LOGINS.update({ user: message.author_id, invalid: false }, { $set: { invalid: true } }),
|
dbs.PENDING_LOGINS.update({ user: message.authorId, invalid: false }, { $set: { invalid: true } }),
|
||||||
dbs.SESSIONS.update({ user: message.author_id, invalid: false }, { $set: { invalid: true } }),
|
dbs.SESSIONS.update({ user: message.authorId, invalid: false }, { $set: { invalid: true } }),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (resA.nModified == 0 && resB.nModified == 0) return message.reply('There are no sessions to invalidate.');
|
if (resA.nModified == 0 && resB.nModified == 0) return message.reply('There are no sessions to invalidate.');
|
||||||
|
@ -30,7 +30,7 @@ export default {
|
||||||
} else {
|
} else {
|
||||||
const loginAttempt = await dbs.PENDING_LOGINS.findOne({
|
const loginAttempt = await dbs.PENDING_LOGINS.findOne({
|
||||||
code: code.toUpperCase(),
|
code: code.toUpperCase(),
|
||||||
user: message.author_id,
|
user: message.authorId,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!loginAttempt || loginAttempt.invalid) {
|
if (!loginAttempt || loginAttempt.invalid) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import SimpleCommand from "../../../struct/commands/SimpleCommand";
|
import SimpleCommand from "../../../struct/commands/SimpleCommand";
|
||||||
import { isBotManager, NO_MANAGER_MSG, parseUser } from "../../util";
|
import { isBotManager, NO_MANAGER_MSG, parseUser } from "../../util";
|
||||||
import { client, dbs } from "../../..";
|
import { client, dbs } from "../../..";
|
||||||
import { User } from "@janderedev/revolt.js/dist/maps/Users";
|
import { User } from "revolt.js";
|
||||||
import MessageCommandContext from "../../../struct/MessageCommandContext";
|
import MessageCommandContext from "../../../struct/MessageCommandContext";
|
||||||
import CommandCategory from "../../../struct/commands/CommandCategory";
|
import CommandCategory from "../../../struct/commands/CommandCategory";
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ export default {
|
||||||
run: async (message: MessageCommandContext, args: string[]) => {
|
run: async (message: MessageCommandContext, args: string[]) => {
|
||||||
if (!await isBotManager(message)) return message.reply(NO_MANAGER_MSG);
|
if (!await isBotManager(message)) return message.reply(NO_MANAGER_MSG);
|
||||||
|
|
||||||
let config = await dbs.SERVERS.findOne({ id: message.serverContext._id });
|
let config = await dbs.SERVERS.findOne({ id: message.serverContext.id });
|
||||||
let mods = config?.moderators ?? [];
|
let mods = config?.moderators ?? [];
|
||||||
let user: User|null;
|
let user: User|null;
|
||||||
|
|
||||||
|
@ -29,12 +29,12 @@ export default {
|
||||||
user = await parseUser(args[1]);
|
user = await parseUser(args[1]);
|
||||||
if (!user) return message.reply('I can\'t find that user.');
|
if (!user) return message.reply('I can\'t find that user.');
|
||||||
|
|
||||||
if (mods.indexOf(user._id) > -1) return message.reply('This user is already added as moderator.');
|
if (mods.indexOf(user.id) > -1) return message.reply('This user is already added as moderator.');
|
||||||
|
|
||||||
mods.push(user._id);
|
mods.push(user.id);
|
||||||
await dbs.SERVERS.update({ id: message.serverContext._id }, { $set: { moderators: mods } });
|
await dbs.SERVERS.update({ id: message.serverContext.id }, { $set: { moderators: mods } });
|
||||||
|
|
||||||
message.reply(`✅ Added [@${user.username}](/@${user._id}) to moderators.`);
|
message.reply(`✅ Added [@${user.username}](/@${user.id}) to moderators.`);
|
||||||
break;
|
break;
|
||||||
case 'remove':
|
case 'remove':
|
||||||
case 'delete':
|
case 'delete':
|
||||||
|
@ -44,12 +44,12 @@ export default {
|
||||||
user = await parseUser(args[1]);
|
user = await parseUser(args[1]);
|
||||||
if (!user) return message.reply('I can\'t find that user.');
|
if (!user) return message.reply('I can\'t find that user.');
|
||||||
|
|
||||||
if (mods.indexOf(user._id) == -1) return message.reply('This user is not added as moderator.');
|
if (mods.indexOf(user.id) == -1) return message.reply('This user is not added as moderator.');
|
||||||
|
|
||||||
mods = mods.filter(a => a != user?._id);
|
mods = mods.filter(a => a != user?.id);
|
||||||
await dbs.SERVERS.update({ id: message.serverContext._id }, { $set: { moderators: mods } });
|
await dbs.SERVERS.update({ id: message.serverContext.id }, { $set: { moderators: mods } });
|
||||||
|
|
||||||
message.reply(`✅ Removed [@${user.username}](/@${user._id}) from moderators.`);
|
message.reply(`✅ Removed [@${user.username}](/@${user.id}) from moderators.`);
|
||||||
break;
|
break;
|
||||||
case 'list':
|
case 'list':
|
||||||
case 'ls':
|
case 'ls':
|
||||||
|
|
|
@ -15,7 +15,7 @@ export default {
|
||||||
syntax: SYNTAX,
|
syntax: SYNTAX,
|
||||||
category: CommandCategory.Config,
|
category: CommandCategory.Config,
|
||||||
run: async (message: MessageCommandContext, args: string[]) => {
|
run: async (message: MessageCommandContext, args: string[]) => {
|
||||||
let config = await dbs.SERVERS.findOne({ id: message.channel!.server_id! });
|
let config = await dbs.SERVERS.findOne({ id: message.channel!.serverId! });
|
||||||
|
|
||||||
switch(args[0]?.toLowerCase()) {
|
switch(args[0]?.toLowerCase()) {
|
||||||
case 'set':
|
case 'set':
|
||||||
|
@ -31,7 +31,7 @@ export default {
|
||||||
return message.reply(val);
|
return message.reply(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
await dbs.SERVERS.update({ id: message.channel!.server_id! }, { $set: { 'prefix': newPrefix } });
|
await dbs.SERVERS.update({ id: message.channel!.serverId! }, { $set: { 'prefix': newPrefix } });
|
||||||
|
|
||||||
message.reply(`✅ Prefix has been changed from \`${oldPrefix}\` to \`${newPrefix}\`.\n${MENTION_TEXT}`);
|
message.reply(`✅ Prefix has been changed from \`${oldPrefix}\` to \`${newPrefix}\`.\n${MENTION_TEXT}`);
|
||||||
break;
|
break;
|
||||||
|
@ -45,7 +45,7 @@ export default {
|
||||||
if (!await isBotManager(message)) return message.reply(NO_MANAGER_MSG);
|
if (!await isBotManager(message)) return message.reply(NO_MANAGER_MSG);
|
||||||
|
|
||||||
if (config?.prefix != null) {
|
if (config?.prefix != null) {
|
||||||
await dbs.SERVERS.update({ id: message.channel!.server_id! }, { $set: { prefix: undefined } });
|
await dbs.SERVERS.update({ id: message.channel!.serverId! }, { $set: { prefix: undefined } });
|
||||||
}
|
}
|
||||||
|
|
||||||
message.reply(`✅ Prefix has been reset to the default: \`${DEFAULT_PREFIX}\`.`);
|
message.reply(`✅ Prefix has been reset to the default: \`${DEFAULT_PREFIX}\`.`);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { User } from "@janderedev/revolt.js/dist/maps/Users";
|
import { User } from "revolt.js";
|
||||||
import { client, dbs } from "../../..";
|
import { client, 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";
|
||||||
|
@ -15,8 +15,8 @@ export default {
|
||||||
syntax: SYNTAX,
|
syntax: SYNTAX,
|
||||||
category: CommandCategory.Config,
|
category: CommandCategory.Config,
|
||||||
run: async (message: MessageCommandContext, args: string[]) => {
|
run: async (message: MessageCommandContext, args: string[]) => {
|
||||||
let config: ServerConfig|null = await dbs.SERVERS.findOne({ id: message.serverContext._id })
|
let config: ServerConfig|null = await dbs.SERVERS.findOne({ id: message.serverContext.id })
|
||||||
if (!config) config = { id: message.channel!.server_id! };
|
if (!config) config = { id: message.channel!.serverId! };
|
||||||
if (!config.whitelist) config.whitelist = { users: [], roles: [], managers: true }
|
if (!config.whitelist) config.whitelist = { users: [], roles: [], managers: true }
|
||||||
|
|
||||||
if (!isBotManager(message)) return message.reply(NO_MANAGER_MSG);
|
if (!isBotManager(message)) return message.reply(NO_MANAGER_MSG);
|
||||||
|
@ -37,18 +37,18 @@ export default {
|
||||||
return message.reply('That role is already whitelisted.');
|
return message.reply('That role is already whitelisted.');
|
||||||
|
|
||||||
config.whitelist!.roles = [role, ...(config.whitelist!.roles ?? [])];
|
config.whitelist!.roles = [role, ...(config.whitelist!.roles ?? [])];
|
||||||
await dbs.SERVERS.update({ id: message.serverContext._id }, { $set: { whitelist: config.whitelist } });
|
await dbs.SERVERS.update({ id: message.serverContext.id }, { $set: { whitelist: config.whitelist } });
|
||||||
return message.reply(`Added role to whitelist!`);
|
return message.reply(`Added role to whitelist!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
user = await parseUser(args[1])
|
user = await parseUser(args[1])
|
||||||
if (user == null) return message.reply('I can\'t find that user or role.');
|
if (user == null) return message.reply('I can\'t find that user or role.');
|
||||||
if (user.bot != null) return message.reply('Bots cannot be whitelisted.');
|
if (user.bot != null) return message.reply('Bots cannot be whitelisted.');
|
||||||
if (config.whitelist!.users?.includes(user._id))
|
if (config.whitelist!.users?.includes(user.id))
|
||||||
return message.reply('That user is already whitelisted.');
|
return message.reply('That user is already whitelisted.');
|
||||||
|
|
||||||
config.whitelist!.users = [user._id, ...(config.whitelist!.users ?? [])];
|
config.whitelist!.users = [user.id, ...(config.whitelist!.users ?? [])];
|
||||||
await dbs.SERVERS.update({ id: message.serverContext._id }, { $set: { whitelist: config.whitelist } });
|
await dbs.SERVERS.update({ id: message.serverContext.id }, { $set: { whitelist: config.whitelist } });
|
||||||
return message.reply('Added user to whitelist!');
|
return message.reply('Added user to whitelist!');
|
||||||
break;
|
break;
|
||||||
case 'rm':
|
case 'rm':
|
||||||
|
@ -67,17 +67,17 @@ export default {
|
||||||
return message.reply('That role is not whitelisted.');
|
return message.reply('That role is not whitelisted.');
|
||||||
|
|
||||||
config.whitelist!.roles = config.whitelist!.roles.filter(r => r != role);
|
config.whitelist!.roles = config.whitelist!.roles.filter(r => r != role);
|
||||||
await dbs.SERVERS.update({ id: message.serverContext._id }, { $set: { whitelist: config.whitelist } });
|
await dbs.SERVERS.update({ id: message.serverContext.id }, { $set: { whitelist: config.whitelist } });
|
||||||
return message.reply(`Removed role from whitelist!`);
|
return message.reply(`Removed role from whitelist!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
user = await parseUser(args[1])
|
user = await parseUser(args[1])
|
||||||
if (user == null) return message.reply('I can\'t find that user or role.');
|
if (user == null) return message.reply('I can\'t find that user or role.');
|
||||||
if (!config.whitelist!.users?.includes(user._id))
|
if (!config.whitelist!.users?.includes(user.id))
|
||||||
return message.reply('That user is not whitelisted.');
|
return message.reply('That user is not whitelisted.');
|
||||||
|
|
||||||
config.whitelist!.users = config.whitelist!.users.filter(u => u != user?._id);
|
config.whitelist!.users = config.whitelist!.users.filter(u => u != user?.id);
|
||||||
await dbs.SERVERS.update({ id: message.serverContext._id }, { $set: { whitelist: config.whitelist } });
|
await dbs.SERVERS.update({ id: message.serverContext.id }, { $set: { whitelist: config.whitelist } });
|
||||||
return message.reply('Removed user from whitelist!');
|
return message.reply('Removed user from whitelist!');
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
|
@ -98,7 +98,7 @@ export default {
|
||||||
|
|
||||||
if (config.whitelist.roles?.length) {
|
if (config.whitelist.roles?.length) {
|
||||||
config.whitelist.roles
|
config.whitelist.roles
|
||||||
?.map(r => message.serverContext.roles?.[r]?.name || `Unknown role (${r})`)
|
?.map(r => message.serverContext.roles.get(r)?.name || `Unknown role (${r})`)
|
||||||
.forEach((r, index) => {
|
.forEach((r, index) => {
|
||||||
if (index < 15) str += `* ${r}\n`;
|
if (index < 15) str += `* ${r}\n`;
|
||||||
if (index == 15) str += `**${config!.whitelist!.roles!.length - 15} more role${config?.whitelist?.roles?.length == 16 ? '' : 's'}**\n`;
|
if (index == 15) str += `**${config!.whitelist!.roles!.length - 15} more role${config?.whitelist?.roles?.length == 16 ? '' : 's'}**\n`;
|
||||||
|
|
|
@ -31,11 +31,11 @@ export default {
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
await message.reply(
|
await message.reply(
|
||||||
`Server ID: ${message.channel?.server_id || 'None'}\n`
|
`Server ID: ${message.channel?.serverId || 'None'}\n`
|
||||||
+ `Server context: ${message.serverContext._id} `
|
+ `Server context: ${message.serverContext.id} `
|
||||||
+ `(${message.serverContext._id == message.channel?.server_id ? 'This server' : message.serverContext.name})\n`
|
+ `(${message.serverContext.id == message.channel?.serverId ? 'This server' : message.serverContext.name})\n`
|
||||||
+ `Channel ID: ${message.channel_id}\n`
|
+ `Channel ID: ${message.channelId}\n`
|
||||||
+ `User ID: ${message.author_id}`,
|
+ `User ID: ${message.authorId}`,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ export default {
|
||||||
removeEmptyArgs: true,
|
removeEmptyArgs: true,
|
||||||
category: CommandCategory.Misc,
|
category: CommandCategory.Misc,
|
||||||
run: async (message: MessageCommandContext, args: string[]) => {
|
run: async (message: MessageCommandContext, args: string[]) => {
|
||||||
const isBotOwner = ownerIDs.includes(message.author_id);
|
const isBotOwner = ownerIDs.includes(message.authorId!);
|
||||||
const prefix = DEFAULT_PREFIX; // TODO: fetch prefix from server config
|
const prefix = DEFAULT_PREFIX; // TODO: fetch prefix from server config
|
||||||
|
|
||||||
let searchInput = args.shift()?.toLowerCase();
|
let searchInput = args.shift()?.toLowerCase();
|
||||||
|
@ -50,7 +50,7 @@ export default {
|
||||||
let msg = `## AutoMod help\n` +
|
let msg = `## AutoMod help\n` +
|
||||||
`Type **${prefix}help [category]** to view see all commands or **${prefix}help [command]** to learn more about a command.\n\n`
|
`Type **${prefix}help [category]** to view see all commands or **${prefix}help [command]** to learn more about a command.\n\n`
|
||||||
+ `### [Open Server Settings]`
|
+ `### [Open Server Settings]`
|
||||||
+ `(<${process.env.WEB_UI_URL || 'https://automod.janderedev.xyz'}/dashboard/${message.channel?.server_id}>)\n\n`;
|
+ `(<${process.env.WEB_UI_URL || 'https://automod.janderedev.xyz'}/dashboard/${message.channel?.serverId}>)\n\n`;
|
||||||
|
|
||||||
let total = 0;
|
let total = 0;
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,8 @@ export default {
|
||||||
?.catch(console.error)
|
?.catch(console.error)
|
||||||
.then(msg => {
|
.then(msg => {
|
||||||
if (msg) msg.edit({ content: `## Ping Pong!\n`
|
if (msg) msg.edit({ content: `## Ping Pong!\n`
|
||||||
+ `WS: \`${client.websocket.ping ?? '--'}ms\`\n`
|
+ `WS: \`${client.events.ping() ?? '--'}ms\`\n`
|
||||||
+ `Msg: \`${Math.round(Date.now() - now) / 2}ms\`` });
|
+ `Msg: \`${Math.round(Date.now() - now)}ms\`` });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} as SimpleCommand;
|
} as SimpleCommand;
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import { Member } from "@janderedev/revolt.js/dist/maps/Members";
|
import { ServerMember } from "revolt.js";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
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 { hasPerm, isModerator, NO_MANAGER_MSG, parseUser } from "../../util";
|
import { isModerator, NO_MANAGER_MSG, parseUser } from "../../util";
|
||||||
|
import AutomodClient from "../../../struct/AutomodClient";
|
||||||
|
import { client } from "../../..";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'avatar',
|
name: 'avatar',
|
||||||
|
@ -23,13 +25,13 @@ export default {
|
||||||
|| args[0]?.toLowerCase() == 'clear') {
|
|| args[0]?.toLowerCase() == 'clear') {
|
||||||
// Clear server avatar
|
// Clear server avatar
|
||||||
if (!message.member) return;
|
if (!message.member) return;
|
||||||
if (!hasPerm(message.member, 'RemoveAvatars')
|
if (!message.member.hasPermission(message.member.server!, 'RemoveAvatars')
|
||||||
&& !await isModerator(message)) return message.reply(NO_MANAGER_MSG);
|
&& !await isModerator(message)) return message.reply(NO_MANAGER_MSG);
|
||||||
|
|
||||||
if (!target.avatar) {
|
if (!target.avatar) {
|
||||||
await message.reply(`\`@${targetUser.username}\` does not currently have an avatar set for this server.`);
|
await message.reply(`\`@${targetUser.username}\` does not currently have an avatar set for this server.`);
|
||||||
} else {
|
} else {
|
||||||
await clearAvatar(target);
|
await target.edit({ remove: ['Avatar'] });
|
||||||
await message.reply(`\`@${targetUser.username}\`'s server avatar has been cleared.`);
|
await message.reply(`\`@${targetUser.username}\`'s server avatar has been cleared.`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -37,9 +39,9 @@ export default {
|
||||||
|
|
||||||
await message.reply(
|
await message.reply(
|
||||||
`### \`@${targetUser.username}\`'s avatar\n` +
|
`### \`@${targetUser.username}\`'s avatar\n` +
|
||||||
(targetUser.avatar ? `[\\[Global\\]](<${targetUser.generateAvatarURL()}>)` : '[No global avatar]') +
|
(targetUser.avatar ? `[\\[Global\\]](<${targetUser.avatarURL}>)` : '[No global avatar]') +
|
||||||
' | ' +
|
' | ' +
|
||||||
(target.avatar ? `[\\[Server\\]](<${target.generateAvatarURL()}>)` : '[No server avatar]')
|
(target.avatar ? `[\\[Server\\]](<${target.avatarURL}>)` : '[No server avatar]')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
|
@ -48,17 +50,3 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} as SimpleCommand;
|
} as SimpleCommand;
|
||||||
|
|
||||||
async function clearAvatar(member: Member) {
|
|
||||||
await axios.patch(
|
|
||||||
`${member.client.apiURL}/servers/${member.server!._id}/members/${member._id.user}`,
|
|
||||||
{
|
|
||||||
remove: [ "Avatar" ],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
'x-bot-token': process.env['BOT_TOKEN']!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ import {
|
||||||
getDmChannel,
|
getDmChannel,
|
||||||
getMembers,
|
getMembers,
|
||||||
isModerator,
|
isModerator,
|
||||||
|
memberRanking,
|
||||||
NO_MANAGER_MSG,
|
NO_MANAGER_MSG,
|
||||||
parseUserOrId,
|
parseUserOrId,
|
||||||
sanitizeMessageContent,
|
sanitizeMessageContent,
|
||||||
|
@ -23,7 +24,7 @@ import Day from "dayjs";
|
||||||
import RelativeTime from "dayjs/plugin/relativeTime";
|
import RelativeTime from "dayjs/plugin/relativeTime";
|
||||||
import CommandCategory from "../../../struct/commands/CommandCategory";
|
import CommandCategory from "../../../struct/commands/CommandCategory";
|
||||||
import { SendableEmbed } from "revolt-api";
|
import { SendableEmbed } from "revolt-api";
|
||||||
import { User } from "@janderedev/revolt.js";
|
import { User } from "revolt.js";
|
||||||
import logger from "../../logger";
|
import logger from "../../logger";
|
||||||
|
|
||||||
Day.extend(RelativeTime);
|
Day.extend(RelativeTime);
|
||||||
|
@ -49,10 +50,10 @@ export default {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const userInput = !message.reply_ids?.length
|
const userInput = !message.replyIds?.length
|
||||||
? args.shift() || ""
|
? args.shift() || ""
|
||||||
: undefined;
|
: undefined;
|
||||||
if (!userInput && !message.reply_ids?.length)
|
if (!userInput && !message.replyIds?.length)
|
||||||
return message.reply({
|
return message.reply({
|
||||||
embeds: [
|
embeds: [
|
||||||
embed(
|
embed(
|
||||||
|
@ -121,13 +122,13 @@ export default {
|
||||||
|
|
||||||
const embeds: SendableEmbed[] = [];
|
const embeds: SendableEmbed[] = [];
|
||||||
const handledUsers: string[] = [];
|
const handledUsers: string[] = [];
|
||||||
const targetUsers: User | { _id: string }[] = [];
|
const targetUsers: User | { id: string }[] = [];
|
||||||
|
|
||||||
const targetInput = dedupeArray(
|
const targetInput = dedupeArray(
|
||||||
message.reply_ids?.length
|
message.replyIds?.length
|
||||||
? (
|
? (
|
||||||
await Promise.allSettled(
|
await Promise.allSettled(
|
||||||
message.reply_ids.map((msg) =>
|
message.replyIds.map((msg) =>
|
||||||
message.channel?.fetchMessage(msg)
|
message.channel?.fetchMessage(msg)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -154,10 +155,10 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Silently ignore duplicates
|
// Silently ignore duplicates
|
||||||
if (handledUsers.includes(user._id)) continue;
|
if (handledUsers.includes(user.id)) continue;
|
||||||
handledUsers.push(user._id);
|
handledUsers.push(user.id);
|
||||||
|
|
||||||
if (user._id == message.author_id) {
|
if (user.id == message.authorId!) {
|
||||||
embeds.push(
|
embeds.push(
|
||||||
embed(
|
embed(
|
||||||
"I recommend against banning yourself :yeahokayyy:",
|
"I recommend against banning yourself :yeahokayyy:",
|
||||||
|
@ -168,7 +169,7 @@ export default {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user._id == client.user!._id) {
|
if (user.id == client.user!.id) {
|
||||||
embeds.push(
|
embeds.push(
|
||||||
embed(
|
embed(
|
||||||
"I'm not going to ban myself :flushee:",
|
"I'm not going to ban myself :flushee:",
|
||||||
|
@ -194,21 +195,21 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.reply_ids?.length && targetUsers.length) {
|
if (message.replyIds?.length && targetUsers.length) {
|
||||||
let res = await yesNoMessage(
|
let res = await yesNoMessage(
|
||||||
message.channel!,
|
message.channel!,
|
||||||
message.author_id,
|
message.authorId!,
|
||||||
`This will ban the author${targetUsers.length > 1 ? 's' : ''} `
|
`This will ban the author${targetUsers.length > 1 ? 's' : ''} `
|
||||||
+ `of the message${message.reply_ids.length > 1 ? 's' : ''} you replied to.\n`
|
+ `of the message${message.replyIds.length > 1 ? 's' : ''} you replied to.\n`
|
||||||
+ `The following user${targetUsers.length > 1 ? 's' : ''} will be affected: `
|
+ `The following user${targetUsers.length > 1 ? 's' : ''} will be affected: `
|
||||||
+ `${targetUsers.map(u => `<@${u._id}>`).join(', ')}.\n`
|
+ `${targetUsers.map(u => `<@${u.id}>`).join(', ')}.\n`
|
||||||
+ `Are you sure?`,
|
+ `Are you sure?`,
|
||||||
'Confirm action'
|
'Confirm action'
|
||||||
);
|
);
|
||||||
if (!res) return;
|
if (!res) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const members = getMembers(message.serverContext._id);
|
const members = getMembers(message.serverContext.id);
|
||||||
|
|
||||||
for (const user of targetUsers) {
|
for (const user of targetUsers) {
|
||||||
try {
|
try {
|
||||||
|
@ -216,18 +217,18 @@ export default {
|
||||||
const infId = ulid();
|
const infId = ulid();
|
||||||
const infraction: Infraction = {
|
const infraction: Infraction = {
|
||||||
_id: infId,
|
_id: infId,
|
||||||
createdBy: message.author_id,
|
createdBy: message.authorId!,
|
||||||
date: Date.now(),
|
date: Date.now(),
|
||||||
reason: reason || "No reason provided",
|
reason: reason || "No reason provided",
|
||||||
server: message.serverContext._id,
|
server: message.serverContext.id,
|
||||||
type: InfractionType.Manual,
|
type: InfractionType.Manual,
|
||||||
user: user._id,
|
user: user.id,
|
||||||
actionType: "ban",
|
actionType: "ban",
|
||||||
expires: Infinity,
|
expires: Infinity,
|
||||||
};
|
};
|
||||||
const { userWarnCount } = await storeInfraction(infraction);
|
const { userWarnCount } = await storeInfraction(infraction);
|
||||||
|
|
||||||
const member = members.find((m) => m._id.user == user._id);
|
const member = members.find((m) => m.id.user == user.id);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
member &&
|
member &&
|
||||||
|
@ -244,11 +245,11 @@ export default {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (member && !member.bannable) {
|
if (member && !memberRanking(member).bannable) {
|
||||||
embeds.push(
|
embeds.push(
|
||||||
embed(
|
embed(
|
||||||
`I don't have permission to ban \`${
|
`I don't have permission to ban \`${
|
||||||
member?.user?.username || user._id
|
member?.user?.username || user.id
|
||||||
}\`.`,
|
}\`.`,
|
||||||
null,
|
null,
|
||||||
EmbedColor.SoftError
|
EmbedColor.SoftError
|
||||||
|
@ -281,11 +282,11 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await message.serverContext.banUser(user._id, {
|
await message.serverContext.banUser(user.id, {
|
||||||
reason:
|
reason:
|
||||||
reason +
|
reason +
|
||||||
` (by ${await fetchUsername(message.author_id)} ${
|
` (by ${await fetchUsername(message.authorId!)} ${
|
||||||
message.author_id
|
message.authorId
|
||||||
})`,
|
})`,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -293,7 +294,7 @@ export default {
|
||||||
"ban",
|
"ban",
|
||||||
message.serverContext,
|
message.serverContext,
|
||||||
message.member!,
|
message.member!,
|
||||||
user._id,
|
user.id,
|
||||||
reason,
|
reason,
|
||||||
infraction._id,
|
infraction._id,
|
||||||
`Ban duration: **Permanent**`
|
`Ban duration: **Permanent**`
|
||||||
|
@ -305,7 +306,7 @@ export default {
|
||||||
}`,
|
}`,
|
||||||
icon_url:
|
icon_url:
|
||||||
user instanceof User
|
user instanceof User
|
||||||
? user.generateAvatarURL()
|
? user.avatarURL
|
||||||
: undefined,
|
: undefined,
|
||||||
colour: EmbedColor.Success,
|
colour: EmbedColor.Success,
|
||||||
description:
|
description:
|
||||||
|
@ -314,8 +315,8 @@ export default {
|
||||||
? "**the first infraction**"
|
? "**the first infraction**"
|
||||||
: `infraction number **${userWarnCount}**`
|
: `infraction number **${userWarnCount}**`
|
||||||
}` +
|
}` +
|
||||||
` for ${await fetchUsername(user._id)}.\n` +
|
` for ${await fetchUsername(user.id)}.\n` +
|
||||||
`**User ID:** \`${user._id}\`\n` +
|
`**User ID:** \`${user.id}\`\n` +
|
||||||
`**Infraction ID:** \`${infraction._id}\`\n` +
|
`**Infraction ID:** \`${infraction._id}\`\n` +
|
||||||
`**Reason:** \`${infraction.reason}\``,
|
`**Reason:** \`${infraction.reason}\``,
|
||||||
});
|
});
|
||||||
|
@ -325,14 +326,14 @@ export default {
|
||||||
const infId = ulid();
|
const infId = ulid();
|
||||||
const infraction: Infraction = {
|
const infraction: Infraction = {
|
||||||
_id: infId,
|
_id: infId,
|
||||||
createdBy: message.author_id,
|
createdBy: message.authorId!,
|
||||||
date: Date.now(),
|
date: Date.now(),
|
||||||
reason:
|
reason:
|
||||||
(reason || "No reason provided") +
|
(reason || "No reason provided") +
|
||||||
` (${durationStr})`,
|
` (${durationStr})`,
|
||||||
server: message.serverContext._id,
|
server: message.serverContext.id,
|
||||||
type: InfractionType.Manual,
|
type: InfractionType.Manual,
|
||||||
user: user._id,
|
user: user.id,
|
||||||
actionType: "ban",
|
actionType: "ban",
|
||||||
expires: banUntil,
|
expires: banUntil,
|
||||||
};
|
};
|
||||||
|
@ -362,26 +363,26 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await message.serverContext.banUser(user._id, {
|
await message.serverContext.banUser(user.id, {
|
||||||
reason:
|
reason:
|
||||||
reason +
|
reason +
|
||||||
` (by ${await fetchUsername(message.author_id)} ${
|
` (by ${await fetchUsername(message.authorId!)} ${
|
||||||
message.author_id
|
message.authorId
|
||||||
}) (${durationStr})`,
|
}) (${durationStr})`,
|
||||||
});
|
});
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
storeTempBan({
|
storeTempBan({
|
||||||
id: infId,
|
id: infId,
|
||||||
bannedUser: user._id,
|
bannedUser: user.id,
|
||||||
server: message.serverContext._id,
|
server: message.serverContext.id,
|
||||||
until: banUntil,
|
until: banUntil,
|
||||||
}),
|
}),
|
||||||
logModAction(
|
logModAction(
|
||||||
"ban",
|
"ban",
|
||||||
message.serverContext,
|
message.serverContext,
|
||||||
message.member!,
|
message.member!,
|
||||||
user._id,
|
user.id,
|
||||||
reason,
|
reason,
|
||||||
infraction._id,
|
infraction._id,
|
||||||
`Ban duration: **${banDurationFancy}**`
|
`Ban duration: **${banDurationFancy}**`
|
||||||
|
@ -392,7 +393,7 @@ export default {
|
||||||
title: `User temporarily banned`,
|
title: `User temporarily banned`,
|
||||||
icon_url:
|
icon_url:
|
||||||
user instanceof User
|
user instanceof User
|
||||||
? user.generateAvatarURL()
|
? user.avatarURL
|
||||||
: undefined,
|
: undefined,
|
||||||
colour: EmbedColor.Success,
|
colour: EmbedColor.Success,
|
||||||
description:
|
description:
|
||||||
|
@ -401,9 +402,9 @@ export default {
|
||||||
? "**the first infraction**"
|
? "**the first infraction**"
|
||||||
: `infraction number **${userWarnCount}**`
|
: `infraction number **${userWarnCount}**`
|
||||||
}` +
|
}` +
|
||||||
` for ${await fetchUsername(user._id)}.\n` +
|
` for ${await fetchUsername(user.id)}.\n` +
|
||||||
`**Ban duration:** ${banDurationFancy}\n` +
|
`**Ban duration:** ${banDurationFancy}\n` +
|
||||||
`**User ID:** \`${user._id}\`\n` +
|
`**User ID:** \`${user.id}\`\n` +
|
||||||
`**Infraction ID:** \`${infraction._id}\`\n` +
|
`**Infraction ID:** \`${infraction._id}\`\n` +
|
||||||
`**Reason:** \`${infraction.reason}\``,
|
`**Reason:** \`${infraction.reason}\``,
|
||||||
});
|
});
|
||||||
|
@ -413,8 +414,8 @@ export default {
|
||||||
embeds.push(
|
embeds.push(
|
||||||
embed(
|
embed(
|
||||||
`Failed to ban target \`${await fetchUsername(
|
`Failed to ban target \`${await fetchUsername(
|
||||||
user._id,
|
user.id,
|
||||||
user._id
|
user.id
|
||||||
)}\`: ${e}`,
|
)}\`: ${e}`,
|
||||||
"Failed to ban: An error has occurred",
|
"Failed to ban: An error has occurred",
|
||||||
EmbedColor.Error
|
EmbedColor.Error
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { User } from "@janderedev/revolt.js";
|
import { User } from "revolt.js";
|
||||||
import { SendableEmbed } from "revolt-api";
|
import { SendableEmbed } from "revolt-api";
|
||||||
import { ulid } from "ulid";
|
import { ulid } from "ulid";
|
||||||
import { client } from "../../../";
|
import { client } from "../../../";
|
||||||
|
@ -39,10 +39,10 @@ export default {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const userInput = !message.reply_ids?.length
|
const userInput = !message.replyIds?.length
|
||||||
? args.shift() || ""
|
? args.shift() || ""
|
||||||
: undefined;
|
: undefined;
|
||||||
if (!userInput && !message.reply_ids?.length)
|
if (!userInput && !message.replyIds?.length)
|
||||||
return message.reply({
|
return message.reply({
|
||||||
embeds: [
|
embeds: [
|
||||||
embed(
|
embed(
|
||||||
|
@ -72,19 +72,19 @@ export default {
|
||||||
|
|
||||||
const embeds: SendableEmbed[] = [];
|
const embeds: SendableEmbed[] = [];
|
||||||
const handledUsers: string[] = [];
|
const handledUsers: string[] = [];
|
||||||
const targetUsers: User | { _id: string }[] = [];
|
const targetUsers: User | { id: string }[] = [];
|
||||||
|
|
||||||
const targetInput = dedupeArray(
|
const targetInput = dedupeArray(
|
||||||
message.reply_ids?.length
|
message.replyIds?.length
|
||||||
? (
|
? (
|
||||||
await Promise.allSettled(
|
await Promise.allSettled(
|
||||||
message.reply_ids.map((msg) =>
|
message.replyIds.map((msg) =>
|
||||||
message.channel?.fetchMessage(msg)
|
message.channel?.fetchMessage(msg)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.filter((m) => m.status == "fulfilled")
|
.filter((m) => m.status == "fulfilled")
|
||||||
.map((m) => (m as any).value.author_id)
|
.map((m) => (m as any).value.authorId)
|
||||||
: userInput!.split(",")
|
: userInput!.split(",")
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -105,10 +105,10 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Silently ignore duplicates
|
// Silently ignore duplicates
|
||||||
if (handledUsers.includes(user._id)) continue;
|
if (handledUsers.includes(user.id)) continue;
|
||||||
handledUsers.push(user._id);
|
handledUsers.push(user.id);
|
||||||
|
|
||||||
if (user._id == message.author_id) {
|
if (user.id == message.authorId) {
|
||||||
embeds.push(
|
embeds.push(
|
||||||
embed(
|
embed(
|
||||||
"You might want to avoid kicking yourself...",
|
"You might want to avoid kicking yourself...",
|
||||||
|
@ -119,7 +119,7 @@ export default {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user._id == client.user!._id) {
|
if (user.id == client.user!.id) {
|
||||||
embeds.push(
|
embeds.push(
|
||||||
embed(
|
embed(
|
||||||
"I won't allow you to get rid of me this easily :trol:",
|
"I won't allow you to get rid of me this easily :trol:",
|
||||||
|
@ -145,30 +145,30 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.reply_ids?.length && targetUsers.length) {
|
if (message.replyIds?.length && targetUsers.length) {
|
||||||
let res = await yesNoMessage(
|
let res = await yesNoMessage(
|
||||||
message.channel!,
|
message.channel!,
|
||||||
message.author_id,
|
message.authorId!,
|
||||||
`This will kick the author${targetUsers.length > 1 ? 's' : ''} `
|
`This will kick the author${targetUsers.length > 1 ? 's' : ''} `
|
||||||
+ `of the message${message.reply_ids.length > 1 ? 's' : ''} you replied to.\n`
|
+ `of the message${message.replyIds.length > 1 ? 's' : ''} you replied to.\n`
|
||||||
+ `The following user${targetUsers.length > 1 ? 's' : ''} will be affected: `
|
+ `The following user${targetUsers.length > 1 ? 's' : ''} will be affected: `
|
||||||
+ `${targetUsers.map(u => `<@${u._id}>`).join(', ')}.\n`
|
+ `${targetUsers.map(u => `<@${u.id}>`).join(', ')}.\n`
|
||||||
+ `Are you sure?`,
|
+ `Are you sure?`,
|
||||||
'Confirm action'
|
'Confirm action'
|
||||||
);
|
);
|
||||||
if (!res) return;
|
if (!res) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const members = getMembers(message.serverContext._id);
|
const members = getMembers(message.serverContext.id);
|
||||||
|
|
||||||
for (const user of targetUsers) {
|
for (const user of targetUsers) {
|
||||||
try {
|
try {
|
||||||
const member = members.find((m) => m._id.user == user._id);
|
const member = members.find((m) => m.id.user == user.id);
|
||||||
if (!member) {
|
if (!member) {
|
||||||
embeds.push(
|
embeds.push(
|
||||||
embed(
|
embed(
|
||||||
`\`${await fetchUsername(
|
`\`${await fetchUsername(
|
||||||
user._id
|
user.id
|
||||||
)}\` is not a member of this server.`
|
)}\` is not a member of this server.`
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -178,12 +178,12 @@ export default {
|
||||||
let infId = ulid();
|
let infId = ulid();
|
||||||
let infraction: Infraction = {
|
let infraction: Infraction = {
|
||||||
_id: infId,
|
_id: infId,
|
||||||
createdBy: message.author_id,
|
createdBy: message.authorId!,
|
||||||
date: Date.now(),
|
date: Date.now(),
|
||||||
reason: reason || "No reason provided",
|
reason: reason || "No reason provided",
|
||||||
server: message.serverContext._id,
|
server: message.serverContext.id,
|
||||||
type: InfractionType.Manual,
|
type: InfractionType.Manual,
|
||||||
user: user._id,
|
user: user.id,
|
||||||
actionType: "kick",
|
actionType: "kick",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -214,7 +214,7 @@ export default {
|
||||||
"kick",
|
"kick",
|
||||||
message.serverContext,
|
message.serverContext,
|
||||||
message.member!,
|
message.member!,
|
||||||
user._id,
|
user.id,
|
||||||
reason,
|
reason,
|
||||||
infraction._id
|
infraction._id
|
||||||
),
|
),
|
||||||
|
@ -225,7 +225,7 @@ export default {
|
||||||
title: `User kicked`,
|
title: `User kicked`,
|
||||||
icon_url:
|
icon_url:
|
||||||
user instanceof User
|
user instanceof User
|
||||||
? user.generateAvatarURL()
|
? user.avatarURL
|
||||||
: undefined,
|
: undefined,
|
||||||
colour: EmbedColor.Success,
|
colour: EmbedColor.Success,
|
||||||
description:
|
description:
|
||||||
|
@ -234,8 +234,8 @@ export default {
|
||||||
? "**the first infraction**"
|
? "**the first infraction**"
|
||||||
: `infraction number **${userWarnCount}**`
|
: `infraction number **${userWarnCount}**`
|
||||||
}` +
|
}` +
|
||||||
` for ${await fetchUsername(user._id)}.\n` +
|
` for ${await fetchUsername(user.id)}.\n` +
|
||||||
`**User ID:** \`${user._id}\`\n` +
|
`**User ID:** \`${user.id}\`\n` +
|
||||||
`**Infraction ID:** \`${infraction._id}\`\n` +
|
`**Infraction ID:** \`${infraction._id}\`\n` +
|
||||||
`**Reason:** \`${infraction.reason}\``,
|
`**Reason:** \`${infraction.reason}\``,
|
||||||
});
|
});
|
||||||
|
@ -243,7 +243,7 @@ export default {
|
||||||
embeds.push(
|
embeds.push(
|
||||||
embed(
|
embed(
|
||||||
`Failed to kick user ${await fetchUsername(
|
`Failed to kick user ${await fetchUsername(
|
||||||
user._id
|
user.id
|
||||||
)}: ${e}`,
|
)}: ${e}`,
|
||||||
"Failed to kick user",
|
"Failed to kick user",
|
||||||
EmbedColor.Error
|
EmbedColor.Error
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import { Member } from "@janderedev/revolt.js/dist/maps/Members";
|
import { ServerMember } from "revolt.js";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
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 { hasPerm, isModerator, NO_MANAGER_MSG, parseUser } from "../../util";
|
import { isModerator, NO_MANAGER_MSG, parseUser } from "../../util";
|
||||||
|
import { client } from "../../..";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'nick',
|
name: 'nick',
|
||||||
|
@ -13,7 +14,7 @@ export default {
|
||||||
run: async (message: MessageCommandContext, args: string[]) => {
|
run: async (message: MessageCommandContext, args: string[]) => {
|
||||||
try {
|
try {
|
||||||
if (!message.member) return;
|
if (!message.member) return;
|
||||||
if (!hasPerm(message.member, 'ManageNicknames')
|
if (!message.member.hasPermission(message.member.server!, 'ManageNicknames')
|
||||||
&& !await isModerator(message)) return message.reply(NO_MANAGER_MSG);
|
&& !await isModerator(message)) return message.reply(NO_MANAGER_MSG);
|
||||||
|
|
||||||
const targetStr = args.shift();
|
const targetStr = args.shift();
|
||||||
|
@ -42,9 +43,9 @@ export default {
|
||||||
}
|
}
|
||||||
} as SimpleCommand;
|
} as SimpleCommand;
|
||||||
|
|
||||||
async function setNick(member: Member, newName: string|null) {
|
async function setNick(member: ServerMember, newName: string|null) {
|
||||||
await axios.patch(
|
await axios.patch(
|
||||||
`${member.client.apiURL}/servers/${member.server!._id}/members/${member._id.user}`,
|
`${client.options.baseURL}/servers/${member.server!.id}/members/${member.id.user}`,
|
||||||
{
|
{
|
||||||
nickname: newName || undefined,
|
nickname: newName || undefined,
|
||||||
remove: !newName ? [ "Nickname" ] : undefined,
|
remove: !newName ? [ "Nickname" ] : undefined,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import SimpleCommand from "../../../struct/commands/SimpleCommand";
|
import SimpleCommand from "../../../struct/commands/SimpleCommand";
|
||||||
import { Message } from "@janderedev/revolt.js/dist/maps/Messages";
|
import { Message } from "revolt.js";
|
||||||
import { decodeTime } from 'ulid';
|
import { decodeTime } from 'ulid';
|
||||||
import { isModerator, parseUserOrId } from "../../util";
|
import { isModerator, parseUserOrId } from "../../util";
|
||||||
import MessageCommandContext from "../../../struct/MessageCommandContext";
|
import MessageCommandContext from "../../../struct/MessageCommandContext";
|
||||||
|
@ -31,7 +31,7 @@ export default {
|
||||||
|
|
||||||
messages = await message.channel!.fetchMessages({
|
messages = await message.channel!.fetchMessages({
|
||||||
limit: amount,
|
limit: amount,
|
||||||
before: message._id,
|
before: message.id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// delete messages between [id] and [id]
|
// delete messages between [id] and [id]
|
||||||
|
@ -49,7 +49,7 @@ export default {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Make sure the msg1 and msg2 are in the correct order
|
// Make sure the msg1 and msg2 are in the correct order
|
||||||
if (decodeTime(msg1._id) < decodeTime(msg2._id)) {
|
if (decodeTime(msg1.id) < decodeTime(msg2.id)) {
|
||||||
[msg1, msg2] = [msg2, msg1];
|
[msg1, msg2] = [msg2, msg1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,17 +60,17 @@ export default {
|
||||||
sort: "Latest",
|
sort: "Latest",
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!messages.find((m) => m._id == msg1._id))
|
if (!messages.find((m) => m.id == msg1.id))
|
||||||
messages = [msg1, ...messages];
|
messages = [msg1, ...messages];
|
||||||
if (!messages.find((m) => m._id == msg2._id))
|
if (!messages.find((m) => m.id == msg2.id))
|
||||||
messages = [...messages, msg2];
|
messages = [...messages, msg2];
|
||||||
|
|
||||||
// Discard messages that are not in the selected range,
|
// Discard messages that are not in the selected range,
|
||||||
// because Revolt returns more messages than expected for some reason
|
// because Revolt returns more messages than expected for some reason
|
||||||
messages = messages.filter(
|
messages = messages.filter(
|
||||||
(m) =>
|
(m) =>
|
||||||
decodeTime(m._id) <= decodeTime(id2) &&
|
decodeTime(m.id) <= decodeTime(id2) &&
|
||||||
decodeTime(m._id) >= decodeTime(id1)
|
decodeTime(m.id) >= decodeTime(id1)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// allow single messages too, because why not?
|
// allow single messages too, because why not?
|
||||||
|
@ -92,11 +92,11 @@ export default {
|
||||||
);
|
);
|
||||||
|
|
||||||
messages = messages.filter((m) =>
|
messages = messages.filter((m) =>
|
||||||
users.find((u) => u?._id == m.author_id)
|
users.find((u) => u?.id == m.authorId)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
await message.channel?.deleteMessages(messages.map((m) => m._id));
|
await message.channel?.deleteMessages(messages.map((m) => m.id));
|
||||||
|
|
||||||
const replyMsg = await message.channel
|
const replyMsg = await message.channel
|
||||||
?.sendMessage({
|
?.sendMessage({
|
||||||
|
@ -107,8 +107,8 @@ export default {
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
try {
|
try {
|
||||||
await message.channel?.deleteMessages([
|
await message.channel?.deleteMessages([
|
||||||
replyMsg!._id,
|
replyMsg!.id,
|
||||||
message._id,
|
message.id,
|
||||||
]);
|
]);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
|
|
@ -45,13 +45,13 @@ export default {
|
||||||
|
|
||||||
const duration = parseTimeInput(args[1] ?? '');
|
const duration = parseTimeInput(args[1] ?? '');
|
||||||
if (!duration) {
|
if (!duration) {
|
||||||
await client.api.patch(`/servers/${message.serverContext._id}/members/${target._id}` as '/servers/{server}/members/{target}', {
|
await client.api.patch(`/servers/${message.serverContext.id}/members/${target.id}` as '/servers/{server}/members/{target}', {
|
||||||
timeout: new Date(0).toISOString()
|
timeout: new Date(0).toISOString()
|
||||||
} as any);
|
} as any);
|
||||||
await message.reply(`Timeout cleared on @${target.username}`);
|
await message.reply(`Timeout cleared on @${target.username}`);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
await client.api.patch(`/servers/${message.serverContext._id}/members/${target._id}` as '/servers/{server}/members/{target}', {
|
await client.api.patch(`/servers/${message.serverContext.id}/members/${target.id}` as '/servers/{server}/members/{target}', {
|
||||||
timeout: new Date(Date.now() + duration).toISOString()
|
timeout: new Date(Date.now() + duration).toISOString()
|
||||||
} as any);
|
} as any);
|
||||||
await message.reply(`Successfully timed out @${target.username}`);
|
await message.reply(`Successfully timed out @${target.username}`);
|
||||||
|
|
|
@ -18,7 +18,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
let checkTempBans = async (id: string): Promise<number> => {
|
let checkTempBans = async (id: string): Promise<number> => {
|
||||||
let tempbans = await dbs.TEMPBANS.find({ bannedUser: id, server: message.serverContext._id });
|
let tempbans = await dbs.TEMPBANS.find({ bannedUser: id, server: message.serverContext.id });
|
||||||
if (tempbans.length > 0) {
|
if (tempbans.length > 0) {
|
||||||
for (const ban of tempbans) {
|
for (const ban of tempbans) {
|
||||||
await removeTempBan(ban.id);
|
await removeTempBan(ban.id);
|
||||||
|
@ -37,7 +37,7 @@ export default {
|
||||||
let id: string|undefined = undefined;
|
let id: string|undefined = undefined;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
id = (await parseUser(target))?._id;
|
id = (await parseUser(target))?.id;
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
if (USER_MENTION_REGEX.test(target)) {
|
if (USER_MENTION_REGEX.test(target)) {
|
||||||
id = target
|
id = target
|
||||||
|
@ -46,8 +46,8 @@ export default {
|
||||||
} else if (ULID_REGEX.test(target)) {
|
} else if (ULID_REGEX.test(target)) {
|
||||||
id = target;
|
id = target;
|
||||||
} else {
|
} else {
|
||||||
let user = bans.users.find(u => u.username.toLowerCase() == target.toLowerCase());
|
let ban = bans.find(b => b.user?.username.toLowerCase() == target.toLowerCase());
|
||||||
if (user) id = user._id;
|
if (ban) id = ban.id.user;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,9 +58,9 @@ export default {
|
||||||
} else return msg.edit({ content: 'The user could not be found.' });
|
} else return msg.edit({ content: 'The user could not be found.' });
|
||||||
}
|
}
|
||||||
|
|
||||||
let bannedUser = bans.users.find(u => u._id == id);
|
let ban = bans.find(b => b.id.user == id);
|
||||||
|
|
||||||
if (!bannedUser) {
|
if (!ban) {
|
||||||
let tempnum = await checkTempBans(id);
|
let tempnum = await checkTempBans(id);
|
||||||
if (tempnum > 0) {
|
if (tempnum > 0) {
|
||||||
return msg.edit({ content: 'This user is not banned, but leftover database entries have been cleaned up.' });
|
return msg.edit({ content: 'This user is not banned, but leftover database entries have been cleaned up.' });
|
||||||
|
@ -68,12 +68,12 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
msg.edit({ content: `User found: @${bannedUser.username}, unbanning...` }),
|
msg.edit({ content: `User found: @${ban.user?.username ?? ban.id.user}, unbanning...` }),
|
||||||
message.serverContext.unbanUser(id),
|
message.serverContext.unbanUser(id),
|
||||||
checkTempBans(id),
|
checkTempBans(id),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
await msg.edit({ content: `@${bannedUser.username} has been unbanned.` });
|
await msg.edit({ content: `@${ban.user?.username ?? ban.id.user} has been unbanned.` });
|
||||||
} catch(e) { console.error(e) }
|
} catch(e) { console.error(e) }
|
||||||
}
|
}
|
||||||
} as SimpleCommand;
|
} as SimpleCommand;
|
||||||
|
|
|
@ -24,7 +24,7 @@ export default {
|
||||||
category: CommandCategory.Moderation,
|
category: CommandCategory.Moderation,
|
||||||
run: async (message: MessageCommandContext, args: string[]) => {
|
run: async (message: MessageCommandContext, args: string[]) => {
|
||||||
try {
|
try {
|
||||||
const serverConfig = await dbs.SERVERS.findOne({ id: message.serverContext._id });
|
const serverConfig = await dbs.SERVERS.findOne({ id: message.serverContext.id });
|
||||||
if (!serverConfig?.votekick?.enabled) return message.reply('Vote kick is not enabled for this server.');
|
if (!serverConfig?.votekick?.enabled) return message.reply('Vote kick is not enabled for this server.');
|
||||||
if (!message.member!.roles?.filter(r => serverConfig.votekick?.trustedRoles.includes(r)).length
|
if (!message.member!.roles?.filter(r => serverConfig.votekick?.trustedRoles.includes(r)).length
|
||||||
&& !(await isModerator(message))) {
|
&& !(await isModerator(message))) {
|
||||||
|
@ -47,23 +47,23 @@ export default {
|
||||||
|
|
||||||
const vote: VoteEntry = {
|
const vote: VoteEntry = {
|
||||||
id: ulid(),
|
id: ulid(),
|
||||||
target: target._id,
|
target: target.id,
|
||||||
user: message.author_id,
|
user: message.authorId!,
|
||||||
server: message.serverContext._id,
|
server: message.serverContext.id,
|
||||||
time: Date.now(),
|
time: Date.now(),
|
||||||
ignore: false,
|
ignore: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
const votes = await dbs.VOTEKICKS.find({
|
const votes = await dbs.VOTEKICKS.find({
|
||||||
server: message.serverContext._id,
|
server: message.serverContext.id,
|
||||||
target: target._id,
|
target: target.id,
|
||||||
time: {
|
time: {
|
||||||
$gt: Date.now() - 1000 * 60 * 30, // Last 30 minutes
|
$gt: Date.now() - 1000 * 60 * 30, // Last 30 minutes
|
||||||
},
|
},
|
||||||
ignore: false,
|
ignore: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (votes.find(v => v.user == message.author_id)) return message.reply('You can\'t vote twice for this user.');
|
if (votes.find(v => v.user == message.authorId)) return message.reply('You can\'t vote twice for this user.');
|
||||||
|
|
||||||
await dbs.VOTEKICKS.insert(vote);
|
await dbs.VOTEKICKS.insert(vote);
|
||||||
votes.push({ _id: '' as any, ...vote });
|
votes.push({ _id: '' as any, ...vote });
|
||||||
|
@ -72,7 +72,7 @@ export default {
|
||||||
"votekick",
|
"votekick",
|
||||||
message.serverContext,
|
message.serverContext,
|
||||||
message.member!,
|
message.member!,
|
||||||
target._id,
|
target.id,
|
||||||
`n/a`,
|
`n/a`,
|
||||||
vote.id,
|
vote.id,
|
||||||
`This is vote ${votes.length}/${serverConfig.votekick.votesRequired} for this user.`,
|
`This is vote ${votes.length}/${serverConfig.votekick.votesRequired} for this user.`,
|
||||||
|
@ -82,15 +82,15 @@ export default {
|
||||||
if (serverConfig.votekick.banDuration == -1) {
|
if (serverConfig.votekick.banDuration == -1) {
|
||||||
targetMember.kick();
|
targetMember.kick();
|
||||||
} else if (serverConfig.votekick.banDuration == 0) {
|
} else if (serverConfig.votekick.banDuration == 0) {
|
||||||
message.serverContext.banUser(target._id, { reason: 'Automatic permanent ban triggered by /votekick' });
|
message.serverContext.banUser(target.id, { reason: 'Automatic permanent ban triggered by /votekick' });
|
||||||
} else {
|
} else {
|
||||||
message.serverContext.banUser(target._id, { reason: `Automatic temporary ban triggered by /votekick `
|
message.serverContext.banUser(target.id, { reason: `Automatic temporary ban triggered by /votekick `
|
||||||
+ `(${serverConfig.votekick.banDuration} minutes)` });
|
+ `(${serverConfig.votekick.banDuration} minutes)` });
|
||||||
|
|
||||||
await storeTempBan({
|
await storeTempBan({
|
||||||
id: ulid(),
|
id: ulid(),
|
||||||
bannedUser: target._id,
|
bannedUser: target.id,
|
||||||
server: message.serverContext._id,
|
server: message.serverContext.id,
|
||||||
until: Date.now() + (1000 * 60 * serverConfig.votekick.banDuration),
|
until: Date.now() + (1000 * 60 * serverConfig.votekick.banDuration),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -99,8 +99,8 @@ export default {
|
||||||
+ `Banned @${target.username} for ${serverConfig.votekick.banDuration} minutes.`); // Todo: display ban duration properly (Permban, kick, etc)
|
+ `Banned @${target.username} for ${serverConfig.votekick.banDuration} minutes.`); // Todo: display ban duration properly (Permban, kick, etc)
|
||||||
|
|
||||||
await dbs.VOTEKICKS.update({
|
await dbs.VOTEKICKS.update({
|
||||||
server: message.serverContext._id,
|
server: message.serverContext.id,
|
||||||
target: target._id,
|
target: target.id,
|
||||||
time: { $gt: Date.now() - 1000 * 60 * 30 },
|
time: { $gt: Date.now() - 1000 * 60 * 30 },
|
||||||
ignore: false,
|
ignore: false,
|
||||||
}, { $set: { ignore: true } });
|
}, { $set: { ignore: true } });
|
||||||
|
|
|
@ -6,7 +6,7 @@ import InfractionType from "automod/dist/types/antispam/InfractionType";
|
||||||
import { fetchUsername, logModAction } from "../../modules/mod_logs";
|
import { fetchUsername, logModAction } from "../../modules/mod_logs";
|
||||||
import CommandCategory from "../../../struct/commands/CommandCategory";
|
import CommandCategory from "../../../struct/commands/CommandCategory";
|
||||||
import { SendableEmbed } from "revolt-api";
|
import { SendableEmbed } from "revolt-api";
|
||||||
import { User } from "@janderedev/revolt.js";
|
import { User } from "revolt.js";
|
||||||
import logger from "../../logger";
|
import logger from "../../logger";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -19,7 +19,7 @@ export default {
|
||||||
if (!await isModerator(message)) return message.reply(NO_MANAGER_MSG);
|
if (!await isModerator(message)) return message.reply(NO_MANAGER_MSG);
|
||||||
|
|
||||||
const userInput = args.shift() || '';
|
const userInput = args.shift() || '';
|
||||||
if (!userInput && !message.reply_ids?.length) return message.reply({ embeds: [
|
if (!userInput && !message.replyIds?.length) return message.reply({ embeds: [
|
||||||
embed(
|
embed(
|
||||||
`Please specify one or more users by replying to their message while running this command or ` +
|
`Please specify one or more users by replying to their message while running this command or ` +
|
||||||
`by specifying a comma-separated list of usernames.`,
|
`by specifying a comma-separated list of usernames.`,
|
||||||
|
@ -38,12 +38,12 @@ export default {
|
||||||
|
|
||||||
const embeds: SendableEmbed[] = [];
|
const embeds: SendableEmbed[] = [];
|
||||||
const handledUsers: string[] = [];
|
const handledUsers: string[] = [];
|
||||||
const targetUsers: User|{ _id: string }[] = [];
|
const targetUsers: User|{ id: string }[] = [];
|
||||||
|
|
||||||
const targetInput = dedupeArray(
|
const targetInput = dedupeArray(
|
||||||
// Replied messages
|
// Replied messages
|
||||||
(await Promise.allSettled(
|
(await Promise.allSettled(
|
||||||
(message.reply_ids ?? []).map(msg => message.channel?.fetchMessage(msg))
|
(message.replyIds ?? []).map(msg => message.channel?.fetchMessage(msg))
|
||||||
))
|
))
|
||||||
.filter(m => m.status == 'fulfilled').map(m => (m as any).value.author_id),
|
.filter(m => m.status == 'fulfilled').map(m => (m as any).value.author_id),
|
||||||
// Provided users
|
// Provided users
|
||||||
|
@ -54,7 +54,7 @@ export default {
|
||||||
try {
|
try {
|
||||||
let user = await parseUserOrId(userStr);
|
let user = await parseUserOrId(userStr);
|
||||||
if (!user) {
|
if (!user) {
|
||||||
if (message.reply_ids?.length && userStr == userInput) {
|
if (message.replyIds?.length && userStr == userInput) {
|
||||||
reason = reason ? `${userInput} ${reason}` : userInput;
|
reason = reason ? `${userInput} ${reason}` : userInput;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -64,8 +64,8 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Silently ignore duplicates
|
// Silently ignore duplicates
|
||||||
if (handledUsers.includes(user._id)) continue;
|
if (handledUsers.includes(user.id)) continue;
|
||||||
handledUsers.push(user._id);
|
handledUsers.push(user.id);
|
||||||
|
|
||||||
if ((user as any)?.bot != null) return await message.reply({ embeds: [
|
if ((user as any)?.bot != null) return await message.reply({ embeds: [
|
||||||
embed('You cannot warn bots.', null, EmbedColor.SoftError)
|
embed('You cannot warn bots.', null, EmbedColor.SoftError)
|
||||||
|
@ -85,10 +85,10 @@ export default {
|
||||||
for (const user of targetUsers) {
|
for (const user of targetUsers) {
|
||||||
let infraction = {
|
let infraction = {
|
||||||
_id: ulid(),
|
_id: ulid(),
|
||||||
createdBy: message.author_id,
|
createdBy: message.authorId,
|
||||||
user: user._id,
|
user: user.id,
|
||||||
reason: reason || 'No reason provided',
|
reason: reason || 'No reason provided',
|
||||||
server: message.serverContext._id,
|
server: message.serverContext.id,
|
||||||
type: InfractionType.Manual,
|
type: InfractionType.Manual,
|
||||||
date: Date.now(),
|
date: Date.now(),
|
||||||
} as Infraction;
|
} as Infraction;
|
||||||
|
@ -99,7 +99,7 @@ export default {
|
||||||
'warn',
|
'warn',
|
||||||
message.serverContext,
|
message.serverContext,
|
||||||
message.member!,
|
message.member!,
|
||||||
user._id,
|
user.id,
|
||||||
reason || 'No reason provided',
|
reason || 'No reason provided',
|
||||||
infraction._id,
|
infraction._id,
|
||||||
`This is warn number ${userWarnCount} for this user.`
|
`This is warn number ${userWarnCount} for this user.`
|
||||||
|
@ -123,10 +123,10 @@ export default {
|
||||||
|
|
||||||
embeds.push({
|
embeds.push({
|
||||||
title: `User warned`,
|
title: `User warned`,
|
||||||
icon_url: user instanceof User ? user.generateAvatarURL() : undefined,
|
icon_url: user instanceof User ? user.avatarURL : undefined,
|
||||||
colour: EmbedColor.Success,
|
colour: EmbedColor.Success,
|
||||||
description: `This is ${userWarnCount == 1 ? '**the first warn**' : `warn number **${userWarnCount}**`}` +
|
description: `This is ${userWarnCount == 1 ? '**the first warn**' : `warn number **${userWarnCount}**`}` +
|
||||||
` for ${await fetchUsername(user._id)}.\n` +
|
` for ${await fetchUsername(user.id)}.\n` +
|
||||||
`**Infraction ID:** \`${infraction._id}\`\n` +
|
`**Infraction ID:** \`${infraction._id}\`\n` +
|
||||||
`**Reason:** \`${infraction.reason}\``
|
`**Reason:** \`${infraction.reason}\``
|
||||||
});
|
});
|
||||||
|
|
|
@ -23,7 +23,7 @@ export default {
|
||||||
category: CommandCategory.Moderation,
|
category: CommandCategory.Moderation,
|
||||||
run: async (message: MessageCommandContext, args: string[]) => {
|
run: async (message: MessageCommandContext, args: string[]) => {
|
||||||
let infractions: Array<Infraction> = await dbs.INFRACTIONS.find({
|
let infractions: Array<Infraction> = await dbs.INFRACTIONS.find({
|
||||||
server: message.serverContext._id,
|
server: message.serverContext.id,
|
||||||
});
|
});
|
||||||
let userInfractions: Map<string, Infraction[]> = new Map();
|
let userInfractions: Map<string, Infraction[]> = new Map();
|
||||||
infractions.forEach(i => {
|
infractions.forEach(i => {
|
||||||
|
@ -56,7 +56,7 @@ export default {
|
||||||
if (!id) return message.reply('No infraction ID provided.');
|
if (!id) return message.reply('No infraction ID provided.');
|
||||||
let inf = await dbs.INFRACTIONS.findOneAndDelete({
|
let inf = await dbs.INFRACTIONS.findOneAndDelete({
|
||||||
_id: { $eq: id.toUpperCase() },
|
_id: { $eq: id.toUpperCase() },
|
||||||
server: message.serverContext._id
|
server: message.serverContext.id
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!inf) return message.reply('I can\'t find that ID.');
|
if (!inf) return message.reply('I can\'t find that ID.');
|
||||||
|
@ -69,18 +69,18 @@ export default {
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
let user = await parseUserOrId(args[0]);
|
let user = await parseUserOrId(args[0]);
|
||||||
if (!user?._id) return message.reply('I can\'t find this user.');
|
if (!user?.id) return message.reply('I can\'t find this user.');
|
||||||
|
|
||||||
|
|
||||||
if (user._id != message.author_id && !await isModerator(message)) return message.reply(NO_MANAGER_MSG);
|
if (user.id != message.authorId && !await isModerator(message)) return message.reply(NO_MANAGER_MSG);
|
||||||
|
|
||||||
const infs = userInfractions.get(user._id);
|
const infs = userInfractions.get(user.id);
|
||||||
const userConfig = await dbs.USERS.findOne({ id: user._id });
|
const userConfig = await dbs.USERS.findOne({ id: user.id });
|
||||||
|
|
||||||
if (!infs) return message.reply(`There are no infractions stored for \`${await fetchUsername(user._id)}\`.`
|
if (!infs) return message.reply(`There are no infractions stored for \`${await fetchUsername(user.id)}\`.`
|
||||||
+ (userConfig?.globalBlacklist ? '\n' + GLOBAL_BLACKLIST_TEXT(userConfig.blacklistReason) : ''), false);
|
+ (userConfig?.globalBlacklist ? '\n' + GLOBAL_BLACKLIST_TEXT(userConfig.blacklistReason) : ''), false);
|
||||||
else {
|
else {
|
||||||
let msg = `## ${infs.length} infractions stored for ${await fetchUsername(user._id)}\n`;
|
let msg = `## ${infs.length} infractions stored for ${await fetchUsername(user.id)}\n`;
|
||||||
|
|
||||||
if (userConfig?.globalBlacklist) {
|
if (userConfig?.globalBlacklist) {
|
||||||
msg += GLOBAL_BLACKLIST_TEXT(userConfig.blacklistReason);
|
msg += GLOBAL_BLACKLIST_TEXT(userConfig.blacklistReason);
|
||||||
|
@ -108,7 +108,7 @@ export default {
|
||||||
if (attachSpreadsheet) {
|
if (attachSpreadsheet) {
|
||||||
try {
|
try {
|
||||||
let csv_data = [
|
let csv_data = [
|
||||||
[`Warns for ${await fetchUsername(user._id)} (${user._id}) - ${Day().toString()}`],
|
[`Warns for ${await fetchUsername(user.id)} (${user.id}) - ${Day().toString()}`],
|
||||||
[],
|
[],
|
||||||
['Date', 'Reason', 'Created By', 'Type', 'Action Type', 'ID'],
|
['Date', 'Reason', 'Created By', 'Type', 'Action Type', 'ID'],
|
||||||
];
|
];
|
||||||
|
@ -127,7 +127,7 @@ export default {
|
||||||
let sheet = Xlsx.utils.aoa_to_sheet(csv_data);
|
let sheet = Xlsx.utils.aoa_to_sheet(csv_data);
|
||||||
let csv = Xlsx.utils.sheet_to_csv(sheet);
|
let csv = Xlsx.utils.sheet_to_csv(sheet);
|
||||||
|
|
||||||
message.reply({ content: msg, attachments: [ await uploadFile(csv, `${user._id}.csv`) ] }, false);
|
message.reply({ content: msg, attachments: [ await uploadFile(csv, `${user.id}.csv`) ] }, false);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
message.reply(msg, false);
|
message.reply(msg, false);
|
||||||
|
|
|
@ -29,7 +29,7 @@ async function adminBotLog(data: { message: string, type: 'INFO'|'WARN'|'ERROR'
|
||||||
await client?.send({
|
await client?.send({
|
||||||
embeds: [ embed ],
|
embeds: [ embed ],
|
||||||
username: bot.user?.username,
|
username: bot.user?.username,
|
||||||
avatarURL: bot.user?.generateAvatarURL({ size: 128 })
|
avatarURL: bot.user?.avatarURL,
|
||||||
});
|
});
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
logger.error(`Failed to log: ${e}`);
|
logger.error(`Failed to log: ${e}`);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Message } from "@janderedev/revolt.js/dist/maps/Messages";
|
import { Message } from "revolt.js";
|
||||||
import { ulid } from "ulid";
|
import { ulid } from "ulid";
|
||||||
import { client, dbs } from "../..";
|
import { client, dbs } from "../..";
|
||||||
import AntispamRule from "automod/dist/types/antispam/AntispamRule";
|
import AntispamRule from "automod/dist/types/antispam/AntispamRule";
|
||||||
|
@ -23,7 +23,7 @@ const SENT_FILTER_MESSAGE: string[] = [];
|
||||||
*/
|
*/
|
||||||
async function antispam(message: Message): Promise<boolean> {
|
async function antispam(message: Message): Promise<boolean> {
|
||||||
try {
|
try {
|
||||||
let serverRules = await dbs.SERVERS.findOne({ id: message.channel!.server_id! });
|
let serverRules = await dbs.SERVERS.findOne({ id: message.channel!.serverId! });
|
||||||
if (!serverRules?.automodSettings) return true;
|
if (!serverRules?.automodSettings) return true;
|
||||||
|
|
||||||
let ruleTriggered = false;
|
let ruleTriggered = false;
|
||||||
|
@ -34,14 +34,14 @@ async function antispam(message: Message): Promise<boolean> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.author?.bot != null) break;
|
if (message.author?.bot != null) break;
|
||||||
if (serverRules.whitelist?.users?.includes(message.author_id)) break;
|
if (serverRules.whitelist?.users?.includes(message.authorId!)) break;
|
||||||
if (message.member?.roles?.filter(r => serverRules!.whitelist?.roles?.includes(r)).length) break;
|
if (message.member?.roles?.filter(r => serverRules!.whitelist?.roles?.includes(r)).length) break;
|
||||||
if (serverRules.whitelist?.managers !== false && await isModerator(message, false)) break;
|
if (serverRules.whitelist?.managers !== false && await isModerator(message, false)) break;
|
||||||
if (rule.channels?.length && rule.channels.indexOf(message.channel_id) == -1) break;
|
if (rule.channels?.length && rule.channels.indexOf(message.channelId) == -1) break;
|
||||||
|
|
||||||
let store = msgCountStore.get(rule.id)!;
|
let store = msgCountStore.get(rule.id)!;
|
||||||
if (!store.users[message.channel_id]) store.users[message.channel_id] = {}
|
if (!store.users[message.channelId]) store.users[message.channelId] = {}
|
||||||
let userStore = store.users[message.channel_id];
|
let userStore = store.users[message.channelId];
|
||||||
|
|
||||||
if (!userStore.count) userStore.count = 1;
|
if (!userStore.count) userStore.count = 1;
|
||||||
else userStore.count++;
|
else userStore.count++;
|
||||||
|
@ -75,9 +75,9 @@ async function antispam(message: Message): Promise<boolean> {
|
||||||
createdBy: null,
|
createdBy: null,
|
||||||
date: Date.now(),
|
date: Date.now(),
|
||||||
reason: `Automatic moderation rule triggered: More than ${rule.max_msg} messages per ${rule.timeframe} seconds.`,
|
reason: `Automatic moderation rule triggered: More than ${rule.max_msg} messages per ${rule.timeframe} seconds.`,
|
||||||
server: message.channel?.server_id,
|
server: message.channel?.serverId,
|
||||||
type: InfractionType.Automatic,
|
type: InfractionType.Automatic,
|
||||||
user: message.author_id,
|
user: message.authorId,
|
||||||
} as Infraction;
|
} as Infraction;
|
||||||
|
|
||||||
message.channel?.sendMessage('## User has been warned.\n\u200b\n' + getWarnMsg(rule, message))
|
message.channel?.sendMessage('## User has been warned.\n\u200b\n' + getWarnMsg(rule, message))
|
||||||
|
@ -107,8 +107,8 @@ async function antispam(message: Message): Promise<boolean> {
|
||||||
function getWarnMsg(rule: AntispamRule, message: Message) {
|
function getWarnMsg(rule: AntispamRule, message: Message) {
|
||||||
if (rule.message != null) {
|
if (rule.message != null) {
|
||||||
return rule.message
|
return rule.message
|
||||||
.replace(new RegExp('{{userid}}', 'gi'), message.author_id);
|
.replace(new RegExp('{{userid}}', 'gi'), message.authorId!);
|
||||||
} else return `<@${message.author_id}>, please stop spamming.`;
|
} else return `<@${message.authorId}>, please stop spamming.`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -133,9 +133,9 @@ async function wordFilterCheck(message: Message, config: ServerConfig) {
|
||||||
createdBy: null,
|
createdBy: null,
|
||||||
date: Date.now(),
|
date: Date.now(),
|
||||||
reason: 'Word filter triggered',
|
reason: 'Word filter triggered',
|
||||||
server: message.channel!.server_id!,
|
server: message.channel!.serverId!,
|
||||||
type: InfractionType.Automatic,
|
type: InfractionType.Automatic,
|
||||||
user: message.author_id,
|
user: message.authorId!,
|
||||||
}
|
}
|
||||||
|
|
||||||
await storeInfraction(infraction);
|
await storeInfraction(infraction);
|
||||||
|
@ -155,14 +155,14 @@ async function wordFilterCheck(message: Message, config: ServerConfig) {
|
||||||
}
|
}
|
||||||
case 'DELETE': {
|
case 'DELETE': {
|
||||||
if (message.channel?.havePermission('ManageMessages')) {
|
if (message.channel?.havePermission('ManageMessages')) {
|
||||||
const key = `${message.author_id}:${message.channel_id}`;
|
const key = `${message.authorId}:${message.channelId}`;
|
||||||
await message.delete();
|
await message.delete();
|
||||||
|
|
||||||
if (!SENT_FILTER_MESSAGE.includes(key)) {
|
if (!SENT_FILTER_MESSAGE.includes(key)) {
|
||||||
SENT_FILTER_MESSAGE.push(key);
|
SENT_FILTER_MESSAGE.push(key);
|
||||||
setTimeout(() => SENT_FILTER_MESSAGE.splice(SENT_FILTER_MESSAGE.indexOf(key), 1), 30000);
|
setTimeout(() => SENT_FILTER_MESSAGE.splice(SENT_FILTER_MESSAGE.indexOf(key), 1), 30000);
|
||||||
await message.channel.sendMessage((config.wordlistAction.message || WORDLIST_DEFAULT_MESSAGE)
|
await message.channel.sendMessage((config.wordlistAction.message || WORDLIST_DEFAULT_MESSAGE)
|
||||||
.replaceAll('{{user_id}}', message.author_id));
|
.replaceAll('{{user_id}}', message.authorId!));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,7 +171,7 @@ async function wordFilterCheck(message: Message, config: ServerConfig) {
|
||||||
if (!config.logs?.modAction) break;
|
if (!config.logs?.modAction) break;
|
||||||
await sendLogMessage(config.logs.modAction, {
|
await sendLogMessage(config.logs.modAction, {
|
||||||
title: 'Message triggered word filter',
|
title: 'Message triggered word filter',
|
||||||
description: `**Author:** @${message.author?.username} (${message.author_id})\n` +
|
description: `**Author:** @${message.author?.username} (${message.authorId})\n` +
|
||||||
`**Action:** ${config.wordlistAction?.action || 'LOG'}\n` +
|
`**Action:** ${config.wordlistAction?.action || 'LOG'}\n` +
|
||||||
`#### Content\n` +
|
`#### Content\n` +
|
||||||
`>${sanitizeMessageContent(message.content.substring(0, 1000)).trim().replace(/\n/g, '\n>')}`,
|
`>${sanitizeMessageContent(message.content.substring(0, 1000)).trim().replace(/\n/g, '\n>')}`,
|
||||||
|
@ -259,7 +259,7 @@ const notifyPublicServers = async () => {
|
||||||
.filter(server => server.discoverable);
|
.filter(server => server.discoverable);
|
||||||
|
|
||||||
const res = await dbs.SERVERS.find({
|
const res = await dbs.SERVERS.find({
|
||||||
id: { $in: servers.map(s => s._id) },
|
id: { $in: servers.map(s => s.id) },
|
||||||
discoverAutospamNotify: { $in: [ undefined, false ] },
|
discoverAutospamNotify: { $in: [ undefined, false ] },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -273,7 +273,7 @@ const notifyPublicServers = async () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
const server = client.servers.get(serverConfig.id);
|
const server = client.servers.get(serverConfig.id);
|
||||||
const channel = await getDmChannel(server!.owner);
|
const channel = await getDmChannel(server!.ownerId);
|
||||||
await channel.sendMessage(`Hi there,
|
await channel.sendMessage(`Hi there,
|
||||||
|
|
||||||
It looks like your server, **${sanitizeMessageContent(server!.name).trim()}**, has been added to server discovery. Congratulations!
|
It looks like your server, **${sanitizeMessageContent(server!.name).trim()}**, has been added to server discovery. Congratulations!
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Member } from "@janderedev/revolt.js/dist/maps/Members";
|
import { ServerMember } from "revolt.js";
|
||||||
import { User } from "@janderedev/revolt.js/dist/maps/Users";
|
import { User } from "revolt.js";
|
||||||
import { client, dbs } from "../../..";
|
import { client, dbs } from "../../..";
|
||||||
import ServerConfig from "automod/dist/types/ServerConfig";
|
import ServerConfig from "automod/dist/types/ServerConfig";
|
||||||
import { getPermissionLevel } from "../../util";
|
import { getPermissionLevel } from "../../util";
|
||||||
|
@ -37,7 +37,7 @@ wsEvents.on('req:getUserServerDetails', async (data: ReqData, cb: (data: WSRespo
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let member: Member;
|
let member: ServerMember;
|
||||||
try {
|
try {
|
||||||
member = await server.fetchMember(user);
|
member = await server.fetchMember(user);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
|
@ -45,7 +45,7 @@ wsEvents.on('req:getUserServerDetails', async (data: ReqData, cb: (data: WSRespo
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const serverConfig = await dbs.SERVERS.findOne({ id: server._id });
|
const serverConfig = await dbs.SERVERS.findOne({ id: server.id });
|
||||||
|
|
||||||
// todo: remove unwanted keys from server config
|
// todo: remove unwanted keys from server config
|
||||||
|
|
||||||
|
@ -60,28 +60,28 @@ wsEvents.on('req:getUserServerDetails', async (data: ReqData, cb: (data: WSRespo
|
||||||
const users = await Promise.allSettled([
|
const users = await Promise.allSettled([
|
||||||
...(serverConfig?.botManagers?.map(u => fetchUser(u)) ?? []),
|
...(serverConfig?.botManagers?.map(u => fetchUser(u)) ?? []),
|
||||||
...(serverConfig?.moderators?.map(u => fetchUser(u)) ?? []),
|
...(serverConfig?.moderators?.map(u => fetchUser(u)) ?? []),
|
||||||
fetchUser(user._id),
|
fetchUser(user.id),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const response: ServerDetails = {
|
const response: ServerDetails = {
|
||||||
id: server._id,
|
id: server.id,
|
||||||
name: server.name,
|
name: server.name,
|
||||||
perms: await getPermissionLevel(member, server),
|
perms: await getPermissionLevel(member, server),
|
||||||
description: server.description ?? undefined,
|
description: server.description ?? undefined,
|
||||||
bannerURL: server.generateBannerURL(),
|
bannerURL: server.bannerURL,
|
||||||
iconURL: server.generateIconURL(),
|
iconURL: server.iconURL,
|
||||||
serverConfig: (serverConfig as ServerConfig|undefined),
|
serverConfig: (serverConfig as ServerConfig|undefined),
|
||||||
users: users.map(
|
users: users.map(
|
||||||
u => u.status == 'fulfilled'
|
u => u.status == 'fulfilled'
|
||||||
? { id: u.value._id, avatarURL: u.value.generateAvatarURL(), username: u.value.username }
|
? { id: u.value.id, avatarURL: u.value.avatarURL, username: u.value.username }
|
||||||
: { id: u.reason }
|
: { id: u.reason }
|
||||||
),
|
),
|
||||||
channels: server.channels.filter(c => c != undefined).map(c => ({
|
channels: server.channels.filter(c => c != undefined).map(c => ({
|
||||||
id: c!._id,
|
id: c!.id,
|
||||||
name: c!.name ?? '',
|
name: c!.name ?? '',
|
||||||
nsfw: c!.nsfw ?? false,
|
nsfw: false, // todo?
|
||||||
type: c!.channel_type == 'VoiceChannel' ? 'VOICE' : 'TEXT',
|
type: c!.type == 'VoiceChannel' ? 'VOICE' : 'TEXT',
|
||||||
icon: c!.generateIconURL(),
|
icon: c!.iconURL,
|
||||||
})),
|
})),
|
||||||
dmOnKick: serverConfig?.dmOnKick,
|
dmOnKick: serverConfig?.dmOnKick,
|
||||||
dmOnWarn: serverConfig?.dmOnWarn,
|
dmOnWarn: serverConfig?.dmOnWarn,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { User } from '@janderedev/revolt.js/dist/maps/Users';
|
import { User } from 'revolt.js';
|
||||||
import { client } from '../../..';
|
import { client } from '../../..';
|
||||||
import { getMutualServers, getPermissionLevel } from '../../util';
|
import { getMutualServers, getPermissionLevel } from '../../util';
|
||||||
import { wsEvents, WSResponse } from '../api_communication';
|
import { wsEvents, WSResponse } from '../api_communication';
|
||||||
|
@ -27,11 +27,11 @@ wsEvents.on('req:getUserServers', async (data: ReqData, cb: (data: WSResponse) =
|
||||||
if (!server) return reject('Server not found');
|
if (!server) return reject('Server not found');
|
||||||
const perms = await getPermissionLevel(user, server);
|
const perms = await getPermissionLevel(user, server);
|
||||||
resolve({
|
resolve({
|
||||||
id: server._id,
|
id: server.id,
|
||||||
perms,
|
perms,
|
||||||
name: server.name,
|
name: server.name,
|
||||||
bannerURL: server.generateBannerURL(),
|
bannerURL: server.bannerURL,
|
||||||
iconURL: server.generateIconURL({}),
|
iconURL: server.iconURL,
|
||||||
});
|
});
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { User } from "@janderedev/revolt.js/dist/maps/Users";
|
import { User } from "revolt.js";
|
||||||
import { client } from "../../..";
|
import { client } from "../../..";
|
||||||
import { getPermissionLevel, parseUser } from "../../util";
|
import { getPermissionLevel, parseUser } from "../../util";
|
||||||
import { wsEvents, WSResponse } from "../api_communication";
|
import { wsEvents, WSResponse } from "../api_communication";
|
||||||
|
@ -30,7 +30,7 @@ wsEvents.on('req:getUser', async (data: { user: string }, cb: (data: WSResponse)
|
||||||
if (!user)
|
if (!user)
|
||||||
cb({ success: false, statusCode: 404, error: 'User could not be found' });
|
cb({ success: false, statusCode: 404, error: 'User could not be found' });
|
||||||
else
|
else
|
||||||
cb({ success: true, user: { id: user._id, username: user.username, avatarURL: user.generateAvatarURL() } as APIUser });
|
cb({ success: true, user: { id: user.id, username: user.username, avatarURL: user.avatarURL } as APIUser });
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
cb({ success: false, error: `${e}` });
|
cb({ success: false, error: `${e}` });
|
||||||
|
|
|
@ -102,18 +102,18 @@ wsEvents.on('req:requestLogin', async (data: any, cb: (data: WSResponse) => void
|
||||||
let code: string|null = null;
|
let code: string|null = null;
|
||||||
while (!code) {
|
while (!code) {
|
||||||
const c = crypto.randomBytes(8).toString('hex');
|
const c = crypto.randomBytes(8).toString('hex');
|
||||||
const found = await dbs.PENDING_LOGINS.find({ code: c, user: user._id, confirmed: false });
|
const found = await dbs.PENDING_LOGINS.find({ code: c, user: user.id, confirmed: false });
|
||||||
if (found.length > 0) continue;
|
if (found.length > 0) continue;
|
||||||
code = c.substring(0, 8).toUpperCase();
|
code = c.substring(0, 8).toUpperCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info(`Attempted login for user ${user._id} with code ${code}`);
|
logger.info(`Attempted login for user ${user.id} with code ${code}`);
|
||||||
|
|
||||||
const nonce = ulid();
|
const nonce = ulid();
|
||||||
|
|
||||||
const [previousLogins, currentValidLogins] = await Promise.all([
|
const [previousLogins, currentValidLogins] = await Promise.all([
|
||||||
dbs.PENDING_LOGINS.find({ user: user._id, confirmed: true }),
|
dbs.PENDING_LOGINS.find({ user: user.id, confirmed: true }),
|
||||||
dbs.PENDING_LOGINS.find({ user: user._id, confirmed: false, expires: { $gt: Date.now() } }),
|
dbs.PENDING_LOGINS.find({ user: user.id, confirmed: false, expires: { $gt: Date.now() } }),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (currentValidLogins.length >= 5) return cb({ success: false, statusCode: 403, error: 'Too many pending logins. Try again later.' });
|
if (currentValidLogins.length >= 5) return cb({ success: false, statusCode: 403, error: 'Too many pending logins. Try again later.' });
|
||||||
|
@ -121,7 +121,7 @@ wsEvents.on('req:requestLogin', async (data: any, cb: (data: WSResponse) => void
|
||||||
await dbs.PENDING_LOGINS.insert({
|
await dbs.PENDING_LOGINS.insert({
|
||||||
code,
|
code,
|
||||||
expires: Date.now() + (1000 * 60 * 15), // Expires in 15 minutes
|
expires: Date.now() + (1000 * 60 * 15), // Expires in 15 minutes
|
||||||
user: user._id,
|
user: user.id,
|
||||||
nonce: nonce,
|
nonce: nonce,
|
||||||
confirmed: false,
|
confirmed: false,
|
||||||
requirePhishingConfirmation: previousLogins.length == 0,
|
requirePhishingConfirmation: previousLogins.length == 0,
|
||||||
|
@ -129,7 +129,7 @@ wsEvents.on('req:requestLogin', async (data: any, cb: (data: WSResponse) => void
|
||||||
invalid: false,
|
invalid: false,
|
||||||
} as PendingLogin);
|
} as PendingLogin);
|
||||||
|
|
||||||
cb({ success: true, uid: user._id, nonce, code });
|
cb({ success: true, uid: user.id, nonce, code });
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
cb({ success: false, error: `${e}` });
|
cb({ success: false, error: `${e}` });
|
||||||
|
@ -137,7 +137,7 @@ wsEvents.on('req:requestLogin', async (data: any, cb: (data: WSResponse) => void
|
||||||
});
|
});
|
||||||
|
|
||||||
wsEvents.on('req:stats', async (_data: any, cb: (data: { servers: number }) => void) => {
|
wsEvents.on('req:stats', async (_data: any, cb: (data: { servers: number }) => void) => {
|
||||||
const servers = bot.servers.size;
|
const servers = bot.servers.size();
|
||||||
cb({ servers });
|
cb({ servers });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -15,10 +15,10 @@ import logger from "../logger";
|
||||||
const update = async () => {
|
const update = async () => {
|
||||||
try {
|
try {
|
||||||
const statusText = statuses[i]
|
const statusText = statuses[i]
|
||||||
.replace('{{servers}}', `${client.servers.size}`)
|
.replace('{{servers}}', `${client.servers.size()}`)
|
||||||
.replace('{{users}}', `${client.users.size}`)
|
.replace('{{users}}', `${client.users.size()}`)
|
||||||
.replace('{{infractions_total}}', `${await dbs.INFRACTIONS.count({})}`)
|
.replace('{{infractions_total}}', `${await dbs.INFRACTIONS.count({})}`)
|
||||||
.replace('{{ping_ms}}', `${client.websocket.ping ?? -1}`);
|
.replace('{{ping_ms}}', `${client.events.ping() ?? -1}`);
|
||||||
|
|
||||||
await setStatus(statusText, 'Online');
|
await setStatus(statusText, 'Online');
|
||||||
logger.debug(`Bot status updated`);
|
logger.debug(`Bot status updated`);
|
||||||
|
@ -37,7 +37,7 @@ import logger from "../logger";
|
||||||
|
|
||||||
async function setStatus(text: string, presence: 'Online'|'Idle'|'Busy'|'Invisible') {
|
async function setStatus(text: string, presence: 'Online'|'Idle'|'Busy'|'Invisible') {
|
||||||
await axios.patch(
|
await axios.patch(
|
||||||
`${client.apiURL}/users/@me`,
|
`${client.options.baseURL}/users/@me`,
|
||||||
{
|
{
|
||||||
status: { text, presence }
|
status: { text, presence }
|
||||||
},
|
},
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { antispam, wordFilterCheck } from "./antispam";
|
||||||
import checkCustomRules from "./custom_rules/custom_rules";
|
import checkCustomRules from "./custom_rules/custom_rules";
|
||||||
import MessageCommandContext from "../../struct/MessageCommandContext";
|
import MessageCommandContext from "../../struct/MessageCommandContext";
|
||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
import { getOwnMemberInServer, hasPermForChannel } from "../util";
|
import { getOwnMemberInServer } from "../util";
|
||||||
import { isSudo, updateSudoTimeout } from "../commands/admin/botadm";
|
import { isSudo, updateSudoTimeout } from "../commands/admin/botadm";
|
||||||
import { metrics } from "./metrics";
|
import { metrics } from "./metrics";
|
||||||
|
|
||||||
|
@ -30,20 +30,20 @@ let commands: SimpleCommand[];
|
||||||
.map(async file => await import(file) as SimpleCommand)
|
.map(async file => await import(file) as SimpleCommand)
|
||||||
)).map(c => (c as any).default)
|
)).map(c => (c as any).default)
|
||||||
|
|
||||||
client.on('message/update', async msg => {
|
client.on('messageUpdate', async msg => {
|
||||||
checkCustomRules(msg, true);
|
checkCustomRules(msg, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
client.on('message', async msg => {
|
client.on('messageCreate', async msg => {
|
||||||
logger.debug(`Message -> ${msg.content}`);
|
logger.debug(`Message -> ${msg.content}`);
|
||||||
|
|
||||||
if (typeof msg.content != 'string' ||
|
if (typeof msg.content != 'string' ||
|
||||||
msg.author_id == client.user?._id ||
|
msg.authorId == client.user?.id ||
|
||||||
!msg.channel?.server) return;
|
!msg.channel?.server) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!msg.member) await msg.channel.server.fetchMember(msg.author_id);
|
if (!msg.member) await msg.channel.server.fetchMember(msg.authorId!);
|
||||||
if (!msg.author) await client.users.fetch(msg.author_id);
|
if (!msg.author) await client.users.fetch(msg.authorId!);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
return msg.reply('⚠ Failed to fetch message author');
|
return msg.reply('⚠ Failed to fetch message author');
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,8 @@ let commands: SimpleCommand[];
|
||||||
if (msg.author!.bot) return;
|
if (msg.author!.bot) return;
|
||||||
|
|
||||||
// If we can't reply to the message, return
|
// If we can't reply to the message, return
|
||||||
if (!hasPermForChannel(await getOwnMemberInServer(msg.channel.server), msg.channel, 'SendMessage')) {
|
const member = await getOwnMemberInServer(msg.channel.server);
|
||||||
|
if (!member.hasPermission(msg.channel, 'SendMessage')) {
|
||||||
logger.debug('Cannot reply to message; returning');
|
logger.debug('Cannot reply to message; returning');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -61,8 +62,8 @@ let commands: SimpleCommand[];
|
||||||
checkCustomRules(msg);
|
checkCustomRules(msg);
|
||||||
|
|
||||||
let [ config, userConfig ] = await Promise.all([
|
let [ config, userConfig ] = await Promise.all([
|
||||||
dbs.SERVERS.findOne({ id: msg.channel!.server_id! }),
|
dbs.SERVERS.findOne({ id: msg.channel!.serverId! }),
|
||||||
dbs.USERS.findOne({ id: msg.author_id }),
|
dbs.USERS.findOne({ id: msg.authorId }),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (config) {
|
if (config) {
|
||||||
|
@ -75,8 +76,8 @@ let commands: SimpleCommand[];
|
||||||
let cmdName = args.shift() ?? '';
|
let cmdName = args.shift() ?? '';
|
||||||
let guildPrefix = config?.prefix ?? DEFAULT_PREFIX;
|
let guildPrefix = config?.prefix ?? DEFAULT_PREFIX;
|
||||||
|
|
||||||
if (cmdName.startsWith(`<@${client.user?._id}>`)) {
|
if (cmdName.startsWith(`<@${client.user?.id}>`)) {
|
||||||
cmdName = cmdName.substring(`<@${client.user?._id}>`.length);
|
cmdName = cmdName.substring(`<@${client.user?.id}>`.length);
|
||||||
if (!cmdName) cmdName = args.shift() ?? ''; // Space between mention and command name
|
if (!cmdName) cmdName = args.shift() ?? ''; // Space between mention and command name
|
||||||
} else if (cmdName.startsWith(guildPrefix)) {
|
} else if (cmdName.startsWith(guildPrefix)) {
|
||||||
cmdName = cmdName.substring(guildPrefix.length);
|
cmdName = cmdName.substring(guildPrefix.length);
|
||||||
|
@ -108,7 +109,7 @@ let commands: SimpleCommand[];
|
||||||
|
|
||||||
if (isSudo(msg.author!)) updateSudoTimeout(msg.author!);
|
if (isSudo(msg.author!)) updateSudoTimeout(msg.author!);
|
||||||
|
|
||||||
if (cmd.restrict == 'BOTOWNER' && ownerIDs.indexOf(msg.author_id) == -1) {
|
if (cmd.restrict == 'BOTOWNER' && ownerIDs.indexOf(msg.authorId!) == -1) {
|
||||||
logger.warn(`User ${msg.author?.username} tried to run owner-only command: ${cmdName}`);
|
logger.warn(`User ${msg.author?.username} tried to run owner-only command: ${cmdName}`);
|
||||||
msg.reply('🔒 Access denied');
|
msg.reply('🔒 Access denied');
|
||||||
return;
|
return;
|
||||||
|
@ -130,10 +131,10 @@ let commands: SimpleCommand[];
|
||||||
let message: MessageCommandContext = msg as MessageCommandContext;
|
let message: MessageCommandContext = msg as MessageCommandContext;
|
||||||
message.serverContext = serverCtx;
|
message.serverContext = serverCtx;
|
||||||
|
|
||||||
logger.info(`Command: ${message.author?.username} (${message.author?._id}) in ${message.channel?.server?.name} (${message.channel?.server?._id}): ${message.content}`);
|
logger.info(`Command: ${message.author?.username} (${message.author?.id}) in ${message.channel?.server?.name} (${message.channel?.serverId}): ${message.content}`);
|
||||||
|
|
||||||
// Create document for server in DB, if not already present
|
// Create document for server in DB, if not already present
|
||||||
if (JSON.stringify(config) == '{}' || !config) await dbs.SERVERS.insert({ id: message.channel!.server_id! });
|
if (JSON.stringify(config) == '{}' || !config) await dbs.SERVERS.insert({ id: message.channel!.serverId! });
|
||||||
|
|
||||||
if (cmd.removeEmptyArgs !== false) {
|
if (cmd.removeEmptyArgs !== false) {
|
||||||
args = args.filter(a => a.length > 0);
|
args = args.filter(a => a.length > 0);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Message } from "@janderedev/revolt.js/dist/maps/Messages";
|
import { Message } from "revolt.js";
|
||||||
import CustomRuleAction from "automod/dist/types/antispam/CustomRuleAction";
|
import CustomRuleAction from "automod/dist/types/antispam/CustomRuleAction";
|
||||||
|
|
||||||
async function execute(message: Message, action: CustomRuleAction) {
|
async function execute(message: Message, action: CustomRuleAction) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Message } from "@janderedev/revolt.js/dist/maps/Messages";
|
import { Message } from "revolt.js";
|
||||||
import { client } from "../../../..";
|
import { client } from "../../../..";
|
||||||
import CustomRuleAction from "automod/dist/types/antispam/CustomRuleAction";
|
import CustomRuleAction from "automod/dist/types/antispam/CustomRuleAction";
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ async function execute(message: Message, action: CustomRuleAction) {
|
||||||
text = text.slice(0, 1996) + ' ...';
|
text = text.slice(0, 1996) + ' ...';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!message.channel) await client.channels.fetch(message.channel_id);
|
if (!message.channel) await client.channels.fetch(message.channelId);
|
||||||
let msg = await message.channel!.sendMessage(text);
|
let msg = await message.channel!.sendMessage(text);
|
||||||
|
|
||||||
if (action.duration) {
|
if (action.duration) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Message } from "@janderedev/revolt.js/dist/maps/Messages";
|
import { Message } from "revolt.js";
|
||||||
import CustomRuleAction from "automod/dist/types/antispam/CustomRuleAction";
|
import CustomRuleAction from "automod/dist/types/antispam/CustomRuleAction";
|
||||||
import { storeInfraction } from '../../../util';
|
import { storeInfraction } from '../../../util';
|
||||||
import Infraction from "automod/dist/types/antispam/Infraction";
|
import Infraction from "automod/dist/types/antispam/Infraction";
|
||||||
|
@ -7,17 +7,17 @@ import InfractionType from "automod/dist/types/antispam/InfractionType";
|
||||||
|
|
||||||
async function execute(message: Message, action: CustomRuleAction) {
|
async function execute(message: Message, action: CustomRuleAction) {
|
||||||
let warnMsg = action.text
|
let warnMsg = action.text
|
||||||
? `${action.text}\n(Triggered on ${message.channel_id} / ${message._id})`
|
? `${action.text}\n(Triggered on ${message.channelId} / ${message.id})`
|
||||||
: `Moderation rule triggered on ${message.channel_id} / ${message._id}`;
|
: `Moderation rule triggered on ${message.channelId} / ${message.id}`;
|
||||||
|
|
||||||
let infraction: Infraction = {
|
let infraction: Infraction = {
|
||||||
_id: ulid(),
|
_id: ulid(),
|
||||||
date: Date.now(),
|
date: Date.now(),
|
||||||
createdBy: null,
|
createdBy: null,
|
||||||
reason: warnMsg,
|
reason: warnMsg,
|
||||||
server: message.channel?.server_id!,
|
server: message.channel?.serverId!,
|
||||||
type: InfractionType.Automatic,
|
type: InfractionType.Automatic,
|
||||||
user: message.author_id
|
user: message.authorId!,
|
||||||
}
|
}
|
||||||
|
|
||||||
let { userWarnCount } = await storeInfraction(infraction);
|
let { userWarnCount } = await storeInfraction(infraction);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Message } from "@janderedev/revolt.js/dist/maps/Messages";
|
import { Message } from "revolt.js";
|
||||||
import { dbs } from "../../..";
|
import { dbs } from "../../..";
|
||||||
import logger from "../../logger";
|
import logger from "../../logger";
|
||||||
import messageContentTrigger from "./message_content_trigger";
|
import messageContentTrigger from "./message_content_trigger";
|
||||||
|
@ -6,11 +6,11 @@ import messageContentTrigger from "./message_content_trigger";
|
||||||
import custom_sendMessage from "./actions/sendMessage";
|
import custom_sendMessage from "./actions/sendMessage";
|
||||||
import custom_delete from "./actions/delete";
|
import custom_delete from "./actions/delete";
|
||||||
import custom_warn from "./actions/warn";
|
import custom_warn from "./actions/warn";
|
||||||
import { getOwnMemberInServer, hasPermForChannel } from "../../util";
|
import { getOwnMemberInServer } from "../../util";
|
||||||
|
|
||||||
async function checkCustomRules(message: Message, isEdit: boolean = false) {
|
async function checkCustomRules(message: Message, isEdit: boolean = false) {
|
||||||
try {
|
try {
|
||||||
let serverConfig = await dbs.SERVERS.findOne({ id: message.channel!.server_id! });
|
let serverConfig = await dbs.SERVERS.findOne({ id: message.channel!.serverId! });
|
||||||
let rules = serverConfig?.automodSettings?.custom;
|
let rules = serverConfig?.automodSettings?.custom;
|
||||||
if (!rules) return;
|
if (!rules) return;
|
||||||
|
|
||||||
|
@ -24,27 +24,28 @@ async function checkCustomRules(message: Message, isEdit: boolean = false) {
|
||||||
|
|
||||||
if (await messageContentTrigger(message, rule.trigger)) {
|
if (await messageContentTrigger(message, rule.trigger)) {
|
||||||
for (const action of rule.action) {
|
for (const action of rule.action) {
|
||||||
|
const member = await getOwnMemberInServer(message.channel!.server!);
|
||||||
switch(action.action) {
|
switch(action.action) {
|
||||||
case 'sendMessage':
|
case 'sendMessage':
|
||||||
if (hasPermForChannel(await getOwnMemberInServer(message.channel!.server!), message.channel!, 'SendMessage'))
|
if (member.hasPermission(message.channel!, 'SendMessage'))
|
||||||
await custom_sendMessage(message, action);
|
await custom_sendMessage(message, action);
|
||||||
else
|
else
|
||||||
logger.warn(`Custom rule ${rule._id}: 'sendMessage' action lacks permission`);
|
logger.warn(`Custom rule ${rule._id}: 'sendMessage' action lacks permission`);
|
||||||
break;
|
break;
|
||||||
case 'delete':
|
case 'delete':
|
||||||
if (hasPermForChannel(await getOwnMemberInServer(message.channel!.server!), message.channel!, 'ManageMessages'))
|
if (member.hasPermission(message.channel!, 'ManageMessages'))
|
||||||
await custom_delete(message, action);
|
await custom_delete(message, action);
|
||||||
else
|
else
|
||||||
logger.warn(`Custom rule ${rule._id}: 'delete' action lacks permission`);
|
logger.warn(`Custom rule ${rule._id}: 'delete' action lacks permission`);
|
||||||
break;
|
break;
|
||||||
case 'warn':
|
case 'warn':
|
||||||
if (hasPermForChannel(await getOwnMemberInServer(message.channel!.server!), message.channel!, 'SendMessage'))
|
if (member.hasPermission(message.channel!, 'SendMessage'))
|
||||||
await custom_warn(message, action);
|
await custom_warn(message, action);
|
||||||
else
|
else
|
||||||
logger.warn(`Custom rule ${rule._id}: 'warn' action lacks permission`);
|
logger.warn(`Custom rule ${rule._id}: 'warn' action lacks permission`);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
logger.warn(`Unknown action ${action.action} in custom rule ${rule._id} in server ${message.channel?.server_id}`);
|
logger.warn(`Unknown action ${action.action} in custom rule ${rule._id} in server ${message.channel?.serverId}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Message } from "@janderedev/revolt.js/dist/maps/Messages";
|
import { Message } from "revolt.js";
|
||||||
import { client } from "../../..";
|
import { client } from "../../..";
|
||||||
import CustomRuleTrigger from "automod/dist/types/antispam/CustomRuleTrigger";
|
import CustomRuleTrigger from "automod/dist/types/antispam/CustomRuleTrigger";
|
||||||
import VM from 'vm';
|
import VM from 'vm';
|
||||||
|
@ -12,8 +12,8 @@ async function messageContentTrigger(message: Message, trigger: CustomRuleTrigge
|
||||||
let matched = false;
|
let matched = false;
|
||||||
if (trigger.matcher) {
|
if (trigger.matcher) {
|
||||||
if (trigger.channelFilter) {
|
if (trigger.channelFilter) {
|
||||||
if (trigger.channelFilter.mode == 'WHITELIST' && !trigger.channelFilter.channels.includes(message.channel_id)) return false;
|
if (trigger.channelFilter.mode == 'WHITELIST' && !trigger.channelFilter.channels.includes(message.channelId)) return false;
|
||||||
if (trigger.channelFilter.mode == 'BLACKLIST' && trigger.channelFilter.channels.includes(message.channel_id)) return false;
|
if (trigger.channelFilter.mode == 'BLACKLIST' && trigger.channelFilter.channels.includes(message.channelId)) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trigger.matcher instanceof RegExp) {
|
if (trigger.matcher instanceof RegExp) {
|
||||||
|
@ -55,8 +55,8 @@ async function messageContentTrigger(message: Message, trigger: CustomRuleTrigge
|
||||||
|
|
||||||
let timeoutKeys = {
|
let timeoutKeys = {
|
||||||
global: trigger._id,
|
global: trigger._id,
|
||||||
channel: trigger._id + '/channel/' + message.channel_id,
|
channel: trigger._id + '/channel/' + message.channelId,
|
||||||
user: trigger._id + '/user/' + message.author_id,
|
user: trigger._id + '/user/' + message.authorId,
|
||||||
}
|
}
|
||||||
let timeoutPass = true;
|
let timeoutPass = true;
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ async function messageContentTrigger(message: Message, trigger: CustomRuleTrigge
|
||||||
/* User/bot filter comes last because we want to avoid fetching users if possible */
|
/* User/bot filter comes last because we want to avoid fetching users if possible */
|
||||||
|
|
||||||
if (trigger.userFilter && trigger.userFilter != 'any') {
|
if (trigger.userFilter && trigger.userFilter != 'any') {
|
||||||
let user = message.author || await client.users.fetch(message.author_id);
|
let user = message.author || await client.users.fetch(message.authorId!);
|
||||||
if (trigger.userFilter == 'bot' && !user.bot) return false;
|
if (trigger.userFilter == 'bot' && !user.bot) return false;
|
||||||
if (trigger.userFilter == 'user' && user.bot) return false;
|
if (trigger.userFilter == 'user' && user.bot) return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,71 +5,61 @@ import Infraction from "automod/dist/types/antispam/Infraction";
|
||||||
import InfractionType from "automod/dist/types/antispam/InfractionType";
|
import InfractionType from "automod/dist/types/antispam/InfractionType";
|
||||||
import { BLACKLIST_BAN_REASON, BLACKLIST_MESSAGE } from "../commands/admin/botadm";
|
import { BLACKLIST_BAN_REASON, BLACKLIST_MESSAGE } from "../commands/admin/botadm";
|
||||||
import logger from "../logger";
|
import logger from "../logger";
|
||||||
import { hasPermForChannel, storeInfraction } from "../util";
|
import { storeInfraction } from "../util";
|
||||||
import { DEFAULT_PREFIX } from "./command_handler";
|
import { DEFAULT_PREFIX } from "./command_handler";
|
||||||
|
import { SendableEmbed } from "revolt-api";
|
||||||
|
|
||||||
const DM_SESSION_LIFETIME = 1000 * 60 * 60 * 24 * 30;
|
const DM_SESSION_LIFETIME = 1000 * 60 * 60 * 24 * 30;
|
||||||
|
|
||||||
// Listen to system messages
|
// Listen to system messages
|
||||||
client.on('message', async message => {
|
client.on('messageCreate', async message => {
|
||||||
if (typeof message.content != 'object') {
|
|
||||||
// reply to 74
|
|
||||||
if (message.author_id == '01FCXF8V6RDKHSQ3AHJ410AASX' && message.content == 'we do a little') {
|
|
||||||
try {
|
|
||||||
message.reply('shut the fuck up');
|
|
||||||
} catch(e) { console.error(e) }
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
let sysMsg = message.systemMessage;
|
||||||
}
|
|
||||||
|
|
||||||
let sysMsg = message.asSystemMessage;
|
if (sysMsg) switch(sysMsg.type) {
|
||||||
|
|
||||||
switch(sysMsg.type) {
|
|
||||||
case 'user_kicked':
|
case 'user_kicked':
|
||||||
case 'user_banned':
|
case 'user_banned':
|
||||||
try {
|
try {
|
||||||
let recentEvents = await dbs.INFRACTIONS.findOne({
|
let recentEvents = await dbs.INFRACTIONS.findOne({
|
||||||
date: { $gt: Date.now() - 30000 },
|
date: { $gt: Date.now() - 30000 },
|
||||||
user: sysMsg.user?._id,
|
user: sysMsg.id,
|
||||||
server: message.channel!.server_id!,
|
server: message.channel!.serverId!,
|
||||||
actionType: sysMsg.type == 'user_kicked' ? 'kick' : 'ban',
|
actionType: sysMsg.type == 'user_kicked' ? 'kick' : 'ban',
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!message.channel ||
|
if (!message.channel ||
|
||||||
!sysMsg.user ||
|
!sysMsg.id ||
|
||||||
recentEvents) return;
|
recentEvents) return;
|
||||||
|
|
||||||
storeInfraction({
|
storeInfraction({
|
||||||
_id: ulid(),
|
_id: ulid(),
|
||||||
createdBy: sysMsg.by?._id,
|
createdBy: null,
|
||||||
reason: 'Unknown reason (caught system message)',
|
reason: 'Unknown reason (caught system message)',
|
||||||
date: message.createdAt,
|
date: message.createdAt.getTime(),
|
||||||
server: message.channel!.server_id,
|
server: message.channel!.serverId,
|
||||||
type: InfractionType.Manual,
|
type: InfractionType.Manual,
|
||||||
user: sysMsg.user!._id,
|
user: sysMsg.id,
|
||||||
actionType: sysMsg.type == 'user_kicked' ? 'kick' : 'ban',
|
actionType: sysMsg.type == 'user_kicked' ? 'kick' : 'ban',
|
||||||
} as Infraction).catch(console.warn);
|
} as Infraction).catch(console.warn);
|
||||||
} catch(e) { console.error(e) }
|
} catch(e) { console.error(e) }
|
||||||
break;
|
break;
|
||||||
case 'user_joined': {
|
case 'user_joined': {
|
||||||
if (!sysMsg.user) break;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const [ serverConfig, userConfig ] = await Promise.all([
|
const [ serverConfig, userConfig ] = await Promise.all([
|
||||||
dbs.SERVERS.findOne({ id: message.channel!.server_id! }),
|
dbs.SERVERS.findOne({ id: message.channel!.serverId }),
|
||||||
dbs.USERS.findOne({ id: sysMsg.user._id }),
|
dbs.USERS.findOne({ id: sysMsg.id }),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (userConfig?.globalBlacklist && !serverConfig?.allowBlacklistedUsers) {
|
if (userConfig?.globalBlacklist && !serverConfig?.allowBlacklistedUsers) {
|
||||||
const server = message.channel?.server;
|
const server = message.channel?.server;
|
||||||
if (server && server.havePermission('BanMembers')) {
|
if (server && server.havePermission('BanMembers')) {
|
||||||
await server.banUser(sysMsg.user._id, { reason: BLACKLIST_BAN_REASON });
|
await server.banUser(sysMsg.id, { reason: BLACKLIST_BAN_REASON });
|
||||||
|
|
||||||
if (server.system_messages?.user_banned) {
|
if (server.systemMessages?.user_banned) {
|
||||||
const channel = server.channels.find(c => c?._id == server.system_messages?.user_banned);
|
const channel = server.channels.find(c => c?.id == server.systemMessages?.user_banned);
|
||||||
if (channel && channel.havePermission('SendMessage')) {
|
if (channel && channel.havePermission('SendMessage')) {
|
||||||
await channel.sendMessage(BLACKLIST_MESSAGE(sysMsg.user.username));
|
const user = client.users.get(sysMsg.id);
|
||||||
|
await channel.sendMessage(BLACKLIST_MESSAGE(user?.username ?? sysMsg.id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,10 +75,10 @@ client.on('message', async message => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// DM message based API session token retrieval
|
// DM message based API session token retrieval
|
||||||
client.on('message', async message => {
|
client.on('messageCreate', async message => {
|
||||||
try {
|
try {
|
||||||
if (
|
if (
|
||||||
message.channel?.channel_type == "DirectMessage" &&
|
message.channel?.type == "DirectMessage" &&
|
||||||
message.nonce?.startsWith("REQUEST_SESSION_TOKEN-") &&
|
message.nonce?.startsWith("REQUEST_SESSION_TOKEN-") &&
|
||||||
message.content?.toLowerCase().startsWith("requesting session token.")
|
message.content?.toLowerCase().startsWith("requesting session token.")
|
||||||
) {
|
) {
|
||||||
|
@ -97,17 +87,16 @@ client.on('message', async message => {
|
||||||
const token = crypto.randomBytes(48).toString('base64').replace(/=/g, '');
|
const token = crypto.randomBytes(48).toString('base64').replace(/=/g, '');
|
||||||
|
|
||||||
await client.db.get('sessions').insert({
|
await client.db.get('sessions').insert({
|
||||||
user: message.author_id,
|
user: message.authorId,
|
||||||
token: token,
|
token: token,
|
||||||
nonce: message.nonce,
|
nonce: message.nonce,
|
||||||
invalid: false,
|
invalid: false,
|
||||||
expires: Date.now() + DM_SESSION_LIFETIME,
|
expires: Date.now() + DM_SESSION_LIFETIME,
|
||||||
})
|
})
|
||||||
|
|
||||||
// Don't need to risk exposing the user to the token, so we'll send it in the nonce
|
|
||||||
await message.channel.sendMessage({
|
await message.channel.sendMessage({
|
||||||
content: `Token request granted. **Do not send the content of this message to anyone!**\n$%${token}%$`,
|
content: `Token request granted. **Do not send the content of this message to anyone!**\n$%${token}%$`,
|
||||||
replies: [ { id: message._id, mention: false } ],
|
replies: [ { id: message.id, mention: false } ],
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -117,26 +106,24 @@ client.on('message', async message => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Send a message when added to a server
|
// Send a message when added to a server
|
||||||
client.on('member/join', (member) => {
|
client.on('serverMemberJoin', (member) => {
|
||||||
if (member._id.user != client.user?._id) return;
|
if (member.id.user != client.user?.id) return;
|
||||||
|
|
||||||
let url = `https://rvembed.janderedev.xyz/embed`
|
|
||||||
+ `?title=${encodeURIComponent('Hi there, thanks for adding me!')}`
|
|
||||||
+ `&description=${encodeURIComponent(`My prefix is "${DEFAULT_PREFIX}", `
|
|
||||||
+ `but you can also @mention me instead.\nCheck out ${DEFAULT_PREFIX}help to get started!`)}`
|
|
||||||
+ `&link=${encodeURIComponent(`/bot/${client.user._id}`)}`
|
|
||||||
+ `&redir=${encodeURIComponent(`https://github.com/janderedev/revolt-automod`)}`
|
|
||||||
+ `&color=${encodeURIComponent("#ff6e6d")}`
|
|
||||||
+ `&image=${encodeURIComponent(client.user.generateAvatarURL({ size: 128 }))}`
|
|
||||||
+ `&image_large=false`;
|
|
||||||
|
|
||||||
if (!member.server) return;
|
if (!member.server) return;
|
||||||
|
|
||||||
|
const embed: SendableEmbed = {
|
||||||
|
title: 'Hi there, thanks for adding me!',
|
||||||
|
description: `My prefix is "${DEFAULT_PREFIX}", but you can also @mention me instead.\nCheck out ${DEFAULT_PREFIX}help to get started!`,
|
||||||
|
icon_url: client.user.avatarURL,
|
||||||
|
colour: '#ff6e6d',
|
||||||
|
url: `/bot/${client.user.id}`,
|
||||||
|
}
|
||||||
|
|
||||||
let channels = member.server.channels.filter(
|
let channels = member.server.channels.filter(
|
||||||
c => c
|
c => c
|
||||||
&& c.channel_type == 'TextChannel'
|
&& c.type == 'TextChannel'
|
||||||
&& hasPermForChannel(member, c, 'SendMessage')
|
&& member.hasPermission(c, 'SendMessage')
|
||||||
&& hasPermForChannel(member, c, 'SendEmbeds')
|
&& member.hasPermission(c, 'SendEmbeds')
|
||||||
);
|
);
|
||||||
|
|
||||||
// Attempt to find an appropriate channel, otherwise use the first one available
|
// Attempt to find an appropriate channel, otherwise use the first one available
|
||||||
|
@ -147,6 +134,8 @@ client.on('member/join', (member) => {
|
||||||
|| channels[0];
|
|| channels[0];
|
||||||
|
|
||||||
if (!channel) return logger.debug('Cannot send hello message: No suitable channel found');
|
if (!channel) return logger.debug('Cannot send hello message: No suitable channel found');
|
||||||
channel.sendMessage(`[:wave:](${url} "Hi there!")`)
|
channel.sendMessage({
|
||||||
.catch(e => logger.debug('Cannot send hello message: ' + e));
|
content: `:wave: "Hi there!")`,
|
||||||
|
embeds: [embed],
|
||||||
|
}).catch(e => logger.debug('Cannot send hello message: ' + e));
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,14 +6,14 @@ import logger from "../logger";
|
||||||
(async () => {
|
(async () => {
|
||||||
if (!client.user) await new Promise<void>(r => client.once('ready', () => r()));
|
if (!client.user) await new Promise<void>(r => client.once('ready', () => r()));
|
||||||
|
|
||||||
logger.info(`Starting to fetch users in ${client.servers.size} servers.`);
|
logger.info(`Starting to fetch users in ${client.servers.size()} servers.`);
|
||||||
|
|
||||||
const promises: Promise<any>[] = [];
|
const promises: Promise<any>[] = [];
|
||||||
for (const server of client.servers) {
|
for (const server of client.servers.entries()) {
|
||||||
promises.push(server[1].fetchMembers());
|
promises.push(server[1].fetchMembers());
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = await Promise.allSettled(promises);
|
const res = await Promise.allSettled(promises);
|
||||||
logger.done(`Downloaded all users from ${res.filter(r => r.status == 'fulfilled').length} servers `
|
logger.done(`Downloaded all users from ${res.filter(r => r.status == 'fulfilled').length} servers `
|
||||||
+ `with ${res.filter(r => r.status == 'rejected').length} errors. Cache size: ${client.users.size}`);
|
+ `with ${res.filter(r => r.status == 'rejected').length} errors. Cache size: ${client.users.size()}`);
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -30,14 +30,14 @@ if (!isNaN(PORT)) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const setServerCount = () => metrics.servers.set(client.servers.size);
|
const setServerCount = () => metrics.servers.set(client.servers.size());
|
||||||
|
|
||||||
client.once('ready', setServerCount);
|
client.once('ready', setServerCount);
|
||||||
client.on('server/update', setServerCount);
|
client.on('serverUpdate', setServerCount);
|
||||||
client.on('server/delete', setServerCount);
|
client.on('serverDelete', setServerCount);
|
||||||
|
|
||||||
const measureLatency = async () => {
|
const measureLatency = async () => {
|
||||||
const wsPing = client.websocket.ping;
|
const wsPing = -1; // currently not exported by revolt.js, todo?
|
||||||
if (wsPing != undefined) metrics.wsPing.set(wsPing);
|
if (wsPing != undefined) metrics.wsPing.set(wsPing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,49 +1,46 @@
|
||||||
import { Member } from "@janderedev/revolt.js/dist/maps/Members";
|
import { Server, ServerMember } from "revolt.js";
|
||||||
import { Server } from "@janderedev/revolt.js/dist/maps/Servers";
|
|
||||||
import { client, dbs } from "../..";
|
import { client, dbs } from "../..";
|
||||||
import LogMessage from "automod/dist/types/LogMessage";
|
import LogMessage from "automod/dist/types/LogMessage";
|
||||||
|
import Xlsx from 'xlsx';
|
||||||
import logger from "../logger";
|
import logger from "../logger";
|
||||||
import { getAutumnURL, sanitizeMessageContent, sendLogMessage } from "../util";
|
import { sanitizeMessageContent, sendLogMessage } from "../util";
|
||||||
|
|
||||||
// the `packet` event is emitted before the client's cache
|
// the `packet` event is emitted before the client's cache
|
||||||
// is updated, which allows us to get the old message content
|
// is updated, which allows us to get the old message content
|
||||||
// if it was cached before
|
// if it was cached before
|
||||||
client.on('packet', async (packet) => {
|
client.on('messageUpdate', async (message, oldMessage) => {
|
||||||
if (packet.type == 'MessageUpdate') {
|
|
||||||
try {
|
try {
|
||||||
if (!packet.data.content) return;
|
if (!message.content) return;
|
||||||
|
|
||||||
let m = client.messages.get(packet.id);
|
if (message.authorId == client.user?.id) return;
|
||||||
|
|
||||||
if (m?.author_id == client.user?._id) return;
|
let oldMsgRaw = String(oldMessage.content ?? '(Unknown)');
|
||||||
|
let newMsgRaw = String(message.content);
|
||||||
let oldMsgRaw = String(m?.content ?? '(Unknown)');
|
|
||||||
let newMsgRaw = String(packet.data.content);
|
|
||||||
let oldMsg = sanitizeMessageContent(oldMsgRaw) || '(Empty)';
|
let oldMsg = sanitizeMessageContent(oldMsgRaw) || '(Empty)';
|
||||||
let newMsg = sanitizeMessageContent(newMsgRaw) || '(Empty)';
|
let newMsg = sanitizeMessageContent(newMsgRaw) || '(Empty)';
|
||||||
|
|
||||||
let channel = client.channels.get(packet.channel);
|
let channel = message.channel;
|
||||||
let server = channel?.server;
|
let server = channel?.server;
|
||||||
if (!server || !channel) return logger.warn('Received message update in unknown channel or server');
|
if (!server || !channel) return logger.warn('Received message update in unknown channel or server');
|
||||||
|
|
||||||
let config = await dbs.SERVERS.findOne({ id: server._id });
|
let config = await dbs.SERVERS.findOne({ id: server.id });
|
||||||
if (config?.logs?.messageUpdate) {
|
if (config?.logs?.messageUpdate) {
|
||||||
const attachFullMessage = oldMsg.length > 800 || newMsg.length > 800;
|
const attachFullMessage = oldMsg.length > 800 || newMsg.length > 800;
|
||||||
let embed: LogMessage = {
|
let embed: LogMessage = {
|
||||||
title: `Message edited in ${server.name}`,
|
title: `Message edited in ${server.name}`,
|
||||||
description:
|
description:
|
||||||
`[#${channel.name}](/server/${server._id}/channel/${channel._id}) | ` +
|
`[#${channel.name}](/server/${server.id}/channel/${channel.id}) | ` +
|
||||||
`[@${sanitizeMessageContent(
|
`@${sanitizeMessageContent(
|
||||||
m?.author?.username ?? "Unknown User"
|
message.author?.username ?? "Unknown User"
|
||||||
)}](/@${m?.author_id}) | ` +
|
)} (${message.authorId}) | ` +
|
||||||
`[Jump to message](/server/${server._id}/channel/${channel._id}/${packet.id})`,
|
`[Jump to message](/server/${server.id}/channel/${channel.id}/${message.id})`,
|
||||||
fields: [],
|
fields: [],
|
||||||
color: "#829dff",
|
color: "#829dff",
|
||||||
overrides: {
|
overrides: {
|
||||||
discord: {
|
discord: {
|
||||||
description: `Author: @${
|
description: `Author: @${
|
||||||
m?.author?.username || m?.author_id || "Unknown"
|
message.author?.username || message.authorId || "Unknown"
|
||||||
} | Channel: ${channel?.name || channel?._id}`,
|
} | Channel: ${channel.name || channel.id}`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -63,30 +60,30 @@ client.on('packet', async (packet) => {
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
client.on('messageDelete', async (message) => {
|
||||||
if (packet.type == 'MessageDelete') {
|
|
||||||
try {
|
try {
|
||||||
let channel = client.channels.get(packet.channel);
|
let channel = client.channels.get(message.channelId);
|
||||||
|
let author = message.authorId ? client.users.get(message.authorId) : null;
|
||||||
if (!channel) return;
|
if (!channel) return;
|
||||||
let message = client.messages.get(packet.id);
|
|
||||||
if (!message) return;
|
|
||||||
|
|
||||||
let msgRaw = String(message.content ?? '(Unknown)');
|
let msgRaw = String(message.content ?? '(Unknown)');
|
||||||
let msg = sanitizeMessageContent(msgRaw);
|
let msg = sanitizeMessageContent(msgRaw);
|
||||||
|
|
||||||
let config = await dbs.SERVERS.findOne({ id: message.channel?.server?._id });
|
let config = await dbs.SERVERS.findOne({ id: channel?.server?.id });
|
||||||
if (config?.logs?.messageUpdate) {
|
if (config?.logs?.messageUpdate) {
|
||||||
let embed: LogMessage = {
|
let embed: LogMessage = {
|
||||||
title: `Message deleted in ${message.channel?.server?.name}`,
|
title: `Message deleted in ${channel?.server?.name}`,
|
||||||
description: `[\\[#${channel.name}\\]](/server/${channel.server_id}/channel/${channel._id}) | `
|
description: `[#${channel.name}](/server/${channel.serverId}/channel/${channel.id}) | `
|
||||||
+ `[\\[Author\\]](/@${message.author_id}) | `
|
+ `@${sanitizeMessageContent(
|
||||||
+ `[\\[Jump to context\\]](/server/${channel.server_id}/channel/${channel._id}/${packet.id})`,
|
author?.username ?? "Unknown User"
|
||||||
|
)} (${message.authorId}) | `
|
||||||
|
+ `[\\[Jump to context\\]](/server/${channel.serverId}/channel/${channel.id}/${message.id})`,
|
||||||
fields: [],
|
fields: [],
|
||||||
color: '#ff6b6b',
|
color: '#ff6b6b',
|
||||||
overrides: {
|
overrides: {
|
||||||
discord: {
|
discord: {
|
||||||
description: `Author: @${message.author?.username || message.author_id} | Channel: ${message.channel?.name || message.channel_id}`
|
description: `Author: @${author?.username || message.authorId} | Channel: ${channel?.name || message.channelId}`
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,9 +95,9 @@ client.on('packet', async (packet) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.attachments?.length) {
|
if (message.attachments?.length) {
|
||||||
let autumnURL = await getAutumnURL();
|
let autumnURL = client.configuration?.features.autumn.url;
|
||||||
embed.fields!.push({ title: 'Attachments', content: message.attachments.map(a =>
|
embed.fields!.push({ title: 'Attachments', content: message.attachments.map(a =>
|
||||||
`[\\[${a.filename}\\]](<${autumnURL}/${a.tag}/${a._id}/${a.filename}>)`).join(' | ') })
|
`[\\[${a.filename}\\]](<${autumnURL}/${a.tag}/${a.id}/${a.filename}>)`).join(' | ') })
|
||||||
}
|
}
|
||||||
|
|
||||||
await sendLogMessage(config.logs.messageUpdate, embed);
|
await sendLogMessage(config.logs.messageUpdate, embed);
|
||||||
|
@ -108,39 +105,57 @@ client.on('packet', async (packet) => {
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (packet.type == 'BulkMessageDelete') {
|
|
||||||
const channel = client.channels.get(packet.channel);
|
|
||||||
if (!channel) return;
|
|
||||||
|
|
||||||
try {
|
|
||||||
let config = await dbs.SERVERS.findOne({ id: channel.server?._id });
|
|
||||||
if (config?.logs?.messageUpdate) {
|
|
||||||
let embed: LogMessage = {
|
|
||||||
title: `Bulk delete in ${channel.server?.name}`,
|
|
||||||
description: `${packet.ids.length} messages deleted in ` +
|
|
||||||
`[#${channel.name}](/server/${channel.server_id}/channel/${channel._id})`,
|
|
||||||
fields: [],
|
|
||||||
color: '#ff392b',
|
|
||||||
overrides: {
|
|
||||||
discord: {
|
|
||||||
description: `${packet.ids.length} messages deleted in #${channel.name}`,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await sendLogMessage(config.logs.messageUpdate, embed);
|
|
||||||
}
|
|
||||||
} catch(e) {
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
async function logModAction(type: 'warn'|'kick'|'ban'|'votekick', server: Server, mod: Member, target: string, reason: string|null, infractionID: string, extraText?: string): Promise<void> {
|
client.on('messageDeleteBulk', async (messages) => {
|
||||||
|
const channel = client.channels.get(messages[0].channelId);
|
||||||
|
if (!channel) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let config = await dbs.SERVERS.findOne({ id: server._id });
|
let config = await dbs.SERVERS.findOne({ id: channel.serverId });
|
||||||
|
if (config?.logs?.messageUpdate) {
|
||||||
|
const data: String[][] = [
|
||||||
|
['Message ID', 'Author ID', 'Author Name', 'Content', 'Attachment URLs'],
|
||||||
|
[],
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const message of messages) {
|
||||||
|
data.push([
|
||||||
|
message.id,
|
||||||
|
message.authorId ?? '',
|
||||||
|
message.authorId ? client.users.get(message.authorId)?.username ?? '' : '',
|
||||||
|
message.content ?? '',
|
||||||
|
message.attachments?.map(a => a.id).join(', ') ?? '',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const sheet = Xlsx.utils.aoa_to_sheet(data);
|
||||||
|
const csv = Xlsx.utils.sheet_to_csv(data);
|
||||||
|
|
||||||
|
let embed: LogMessage = {
|
||||||
|
title: `Bulk delete in ${channel.server?.name}`,
|
||||||
|
description: `${messages.length} messages deleted in ` +
|
||||||
|
`[#${channel.name}](/server/${channel.serverId}/channel/${channel.id})`,
|
||||||
|
fields: [],
|
||||||
|
attachments: [{ name: 'messages.csv', content: Buffer.from(csv) }],
|
||||||
|
color: '#ff392b',
|
||||||
|
overrides: {
|
||||||
|
discord: {
|
||||||
|
description: `${messages.length} messages deleted in #${channel.name}`,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await sendLogMessage(config.logs.messageUpdate, embed);
|
||||||
|
}
|
||||||
|
} catch(e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
async function logModAction(type: 'warn'|'kick'|'ban'|'votekick', server: Server, mod: ServerMember, target: string, reason: string|null, infractionID: string, extraText?: string): Promise<void> {
|
||||||
|
try {
|
||||||
|
let config = await dbs.SERVERS.findOne({ id: server.id });
|
||||||
|
|
||||||
if (config?.logs?.modAction) {
|
if (config?.logs?.modAction) {
|
||||||
let aType = type == 'ban' ? 'banned' : type + 'ed';
|
let aType = type == 'ban' ? 'banned' : type + 'ed';
|
||||||
|
|
|
@ -29,11 +29,11 @@ async function processUnban(ban: TempBan) {
|
||||||
if (expired.includes(ban.id)) return;
|
if (expired.includes(ban.id)) return;
|
||||||
|
|
||||||
let server = client.servers.get(ban.server) || await client.servers.fetch(ban.server);
|
let server = client.servers.get(ban.server) || await client.servers.fetch(ban.server);
|
||||||
if (!server.havePermission('BanMembers')) return logger.debug(`No permission to process unbans in ${server._id}, skipping`);
|
if (!server.havePermission('BanMembers')) return logger.debug(`No permission to process unbans in ${server.id}, skipping`);
|
||||||
let serverBans = await server.fetchBans();
|
let serverBans = await server.fetchBans();
|
||||||
|
|
||||||
if (serverBans.bans.find(b => b._id.user == ban.bannedUser)) {
|
if (serverBans.find(b => b.id.user == ban.bannedUser)) {
|
||||||
logger.debug(`Unbanning user ${ban.bannedUser} from ${server._id}`);
|
logger.debug(`Unbanning user ${ban.bannedUser} from ${server.id}`);
|
||||||
|
|
||||||
let promises = [
|
let promises = [
|
||||||
server.unbanUser(ban.bannedUser),
|
server.unbanUser(ban.bannedUser),
|
||||||
|
|
|
@ -1,23 +1,20 @@
|
||||||
import { Member } from "@janderedev/revolt.js/dist/maps/Members";
|
import { ServerMember } from "revolt.js";
|
||||||
import { User } from "@janderedev/revolt.js/dist/maps/Users";
|
import { User } from "revolt.js";
|
||||||
import { client, dbs } from "..";
|
import { client, dbs } from "..";
|
||||||
import Infraction from "automod/dist/types/antispam/Infraction";
|
import Infraction from "automod/dist/types/antispam/Infraction";
|
||||||
import FormData from 'form-data';
|
import FormData from 'form-data';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { Server } from "@janderedev/revolt.js/dist/maps/Servers";
|
import { Server } from "revolt.js";
|
||||||
import LogConfig from "automod/dist/types/LogConfig";
|
import LogConfig from "automod/dist/types/LogConfig";
|
||||||
import LogMessage from "automod/dist/types/LogMessage";
|
import LogMessage from "automod/dist/types/LogMessage";
|
||||||
import { ColorResolvable, MessageEmbed } from "discord.js";
|
import { ColorResolvable, MessageEmbed } from "discord.js";
|
||||||
import logger from "./logger";
|
import logger from "./logger";
|
||||||
import { ulid } from "ulid";
|
import { ulid } from "ulid";
|
||||||
import { Channel } from "@janderedev/revolt.js/dist/maps/Channels";
|
import { Channel } from "revolt.js";
|
||||||
import { Permission } from "@janderedev/revolt.js/dist/permissions/definitions";
|
import { Message } from "revolt.js";
|
||||||
import { Message } from "@janderedev/revolt.js/dist/maps/Messages";
|
|
||||||
import { isSudo } from "./commands/admin/botadm";
|
import { isSudo } from "./commands/admin/botadm";
|
||||||
import { SendableEmbed } from "revolt-api";
|
import { SendableEmbed } from "revolt-api";
|
||||||
import MessageCommandContext from "../struct/MessageCommandContext";
|
|
||||||
import ServerConfig from "automod/dist/types/ServerConfig";
|
import ServerConfig from "automod/dist/types/ServerConfig";
|
||||||
import { ClientboundNotification } from "@janderedev/revolt.js";
|
|
||||||
|
|
||||||
const NO_MANAGER_MSG = "🔒 Missing permission";
|
const NO_MANAGER_MSG = "🔒 Missing permission";
|
||||||
const ULID_REGEX = /^[0-9A-HJ-KM-NP-TV-Z]{26}$/i;
|
const ULID_REGEX = /^[0-9A-HJ-KM-NP-TV-Z]{26}$/i;
|
||||||
|
@ -26,18 +23,6 @@ const CHANNEL_MENTION_REGEX = /^<#[0-9A-HJ-KM-NP-TV-Z]{26}>$/i;
|
||||||
const RE_HTTP_URI = /^http(s?):\/\//g;
|
const RE_HTTP_URI = /^http(s?):\/\//g;
|
||||||
const RE_MAILTO_URI = /^mailto:/g;
|
const RE_MAILTO_URI = /^mailto:/g;
|
||||||
|
|
||||||
let autumn_url: string | null = null;
|
|
||||||
let apiConfig: any = axios.get(client.apiURL).then((res) => {
|
|
||||||
autumn_url = (res.data as any).features.autumn.url;
|
|
||||||
});
|
|
||||||
|
|
||||||
async function getAutumnURL() {
|
|
||||||
return (
|
|
||||||
autumn_url ||
|
|
||||||
((await axios.get(client.apiURL)).data as any).features.autumn.url
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses user input and returns an user object.
|
* Parses user input and returns an user object.
|
||||||
* Supports: `userID`, `<@userID>` (mention), `username`, `@username` (if user is cached).
|
* Supports: `userID`, `<@userID>` (mention), `username`, `@username` (if user is cached).
|
||||||
|
@ -80,10 +65,10 @@ async function parseUser(text: string): Promise<User | null> {
|
||||||
*/
|
*/
|
||||||
async function parseUserOrId(
|
async function parseUserOrId(
|
||||||
text: string
|
text: string
|
||||||
): Promise<User | { _id: string } | null> {
|
): Promise<User | { id: string } | null> {
|
||||||
let parsed = await parseUser(text);
|
let parsed = await parseUser(text);
|
||||||
if (parsed) return parsed;
|
if (parsed) return parsed;
|
||||||
if (ULID_REGEX.test(text)) return { _id: text.toUpperCase() };
|
if (ULID_REGEX.test(text)) return { id: text.toUpperCase() };
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,17 +76,17 @@ async function isModerator(message: Message, announceSudo?: boolean) {
|
||||||
let member = message.member!,
|
let member = message.member!,
|
||||||
server = message.channel!.server!;
|
server = message.channel!.server!;
|
||||||
|
|
||||||
if (hasPerm(member, "KickMembers")) return true;
|
if (member.hasPermission(member.server!, "KickMembers")) return true;
|
||||||
|
|
||||||
const [isManager, mods, isSudo] = await Promise.all([
|
const [isManager, mods, isSudo] = await Promise.all([
|
||||||
isBotManager(message),
|
isBotManager(message),
|
||||||
dbs.SERVERS.findOne({ id: server._id }),
|
dbs.SERVERS.findOne({ id: server.id }),
|
||||||
checkSudoPermission(message, announceSudo),
|
checkSudoPermission(message, announceSudo),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
isManager ||
|
isManager ||
|
||||||
(mods?.moderators?.indexOf(member.user?._id!) ?? -1) > -1 ||
|
(mods?.moderators?.indexOf(member.user?.id!) ?? -1) > -1 ||
|
||||||
isSudo
|
isSudo
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -109,15 +94,15 @@ async function isBotManager(message: Message, announceSudo?: boolean) {
|
||||||
let member = message.member!,
|
let member = message.member!,
|
||||||
server = message.channel!.server!;
|
server = message.channel!.server!;
|
||||||
|
|
||||||
if (hasPerm(member, "ManageServer")) return true;
|
if (member.hasPermission(member.server!, "ManageServer")) return true;
|
||||||
|
|
||||||
const [managers, isSudo] = await Promise.all([
|
const [managers, isSudo] = await Promise.all([
|
||||||
dbs.SERVERS.findOne({ id: server._id }),
|
dbs.SERVERS.findOne({ id: server.id }),
|
||||||
checkSudoPermission(message, announceSudo),
|
checkSudoPermission(message, announceSudo),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
(managers?.botManagers?.indexOf(member.user?._id!) ?? -1) > -1 || isSudo
|
(managers?.botManagers?.indexOf(member.user?.id!) ?? -1) > -1 || isSudo
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
async function checkSudoPermission(
|
async function checkSudoPermission(
|
||||||
|
@ -137,68 +122,38 @@ async function checkSudoPermission(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async function getPermissionLevel(
|
async function getPermissionLevel(
|
||||||
user: User | Member,
|
member: ServerMember | User,
|
||||||
server: Server
|
server: Server
|
||||||
): Promise<0 | 1 | 2 | 3> {
|
): Promise<0 | 1 | 2 | 3> {
|
||||||
|
|
||||||
|
if (member instanceof User) {
|
||||||
|
member = client.serverMembers.getByKey({ server: server.id, user: member.id }) || await server.fetchMember(member.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isSudo(member.user!)) return 3;
|
||||||
|
|
||||||
|
if (member.hasPermission(member.server!, "ManageServer")) return 3;
|
||||||
|
|
||||||
|
const config = await dbs.SERVERS.findOne({ id: server.id });
|
||||||
|
|
||||||
|
if (config?.botManagers?.includes(member.id.user)) return 2;
|
||||||
if (
|
if (
|
||||||
isSudo(
|
config?.moderators?.includes(member.id.user) ||
|
||||||
user instanceof User
|
member.hasPermission(member.server!, "KickMembers")
|
||||||
? user
|
|
||||||
: user.user || (await client.users.fetch(user._id.user))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return 3;
|
|
||||||
|
|
||||||
const member = user instanceof User ? await server.fetchMember(user) : user;
|
|
||||||
if (user instanceof Member) user = user.user!;
|
|
||||||
|
|
||||||
if (hasPerm(member, "ManageServer")) return 3;
|
|
||||||
|
|
||||||
const config = await dbs.SERVERS.findOne({ id: server._id });
|
|
||||||
|
|
||||||
if (config?.botManagers?.includes(user._id)) return 2;
|
|
||||||
if (
|
|
||||||
config?.moderators?.includes(user._id) ||
|
|
||||||
hasPerm(member, "KickMembers")
|
|
||||||
)
|
)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPermissionBasedOnRole(member: Member): 0 | 1 | 2 | 3 {
|
function getPermissionBasedOnRole(member: ServerMember): 0 | 1 | 2 | 3 {
|
||||||
if (hasPerm(member, "ManageServer")) return 3;
|
if (member.hasPermission(member.server!, "ManageServer")) return 3;
|
||||||
if (hasPerm(member, "KickMembers")) return 1;
|
if (member.hasPermission(member.server!, "KickMembers")) return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
async function getOwnMemberInServer(server: Server): Promise<ServerMember> {
|
||||||
* @deprecated Unnecessary
|
return server.member || await server.fetchMember(client.user!.id);
|
||||||
*/
|
|
||||||
function hasPerm(member: Member, perm: keyof typeof Permission): boolean {
|
|
||||||
let p = Permission[perm];
|
|
||||||
if (member.server?.owner == member.user?._id) return true;
|
|
||||||
|
|
||||||
return member.hasPermission(member.server!, perm);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated Unnecessary
|
|
||||||
*/
|
|
||||||
function hasPermForChannel(
|
|
||||||
member: Member,
|
|
||||||
channel: Channel,
|
|
||||||
perm: keyof typeof Permission
|
|
||||||
): boolean {
|
|
||||||
if (!member.server) throw "hasPermForChannel(): Server is undefined";
|
|
||||||
return member.hasPermission(channel, perm);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getOwnMemberInServer(server: Server): Promise<Member> {
|
|
||||||
return (
|
|
||||||
client.members.getKey({ server: server._id, user: client.user!._id }) ||
|
|
||||||
(await server.fetchMember(client.user!._id))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function storeInfraction(
|
async function storeInfraction(
|
||||||
|
@ -220,7 +175,7 @@ async function uploadFile(file: any, filename: string): Promise<string> {
|
||||||
let data = new FormData();
|
let data = new FormData();
|
||||||
data.append("file", file, { filename: filename });
|
data.append("file", file, { filename: filename });
|
||||||
|
|
||||||
let req = await axios.post((await getAutumnURL()) + "/attachments", data, {
|
let req = await axios.post(client.configuration?.features.autumn.url + "/attachments", data, {
|
||||||
headers: data.getHeaders(),
|
headers: data.getHeaders(),
|
||||||
});
|
});
|
||||||
return (req.data as any)["id"] as string;
|
return (req.data as any)["id"] as string;
|
||||||
|
@ -432,8 +387,8 @@ function dedupeArray<T>(...arrays: T[][]): T[] {
|
||||||
|
|
||||||
function getMutualServers(user: User) {
|
function getMutualServers(user: User) {
|
||||||
const servers: Server[] = [];
|
const servers: Server[] = [];
|
||||||
for (const member of client.members) {
|
for (const member of client.serverMembers.entries()) {
|
||||||
if (member[1]._id.user == user._id && member[1].server)
|
if (member[1].id.user == user.id && member[1].server)
|
||||||
servers.push(member[1].server);
|
servers.push(member[1].server);
|
||||||
}
|
}
|
||||||
return servers;
|
return servers;
|
||||||
|
@ -445,19 +400,21 @@ const awaitClient = () =>
|
||||||
else resolve();
|
else resolve();
|
||||||
});
|
});
|
||||||
|
|
||||||
const getDmChannel = async (user: string | { _id: string } | User) => {
|
const getDmChannel = async (user: string | { id: string } | User) => {
|
||||||
if (typeof user == "string")
|
if (typeof user == "string") {
|
||||||
user = client.users.get(user) || (await client.users.fetch(user));
|
user = client.users.get(user) || (await client.users.fetch(user));
|
||||||
if (!(user instanceof User))
|
}
|
||||||
user =
|
|
||||||
client.users.get(user._id) || (await client.users.fetch(user._id));
|
if (!(user instanceof User)) {
|
||||||
|
user = client.users.get(user.id) || (await client.users.fetch(user.id));
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
Array.from(client.channels).find(
|
Array.from(client.channels.values()).find(
|
||||||
(c) =>
|
(c: Channel) =>
|
||||||
c[1].channel_type == "DirectMessage" &&
|
c.type == "DirectMessage" &&
|
||||||
c[1].recipient?._id == (user as User)._id
|
c.recipient?.id == (user as User).id
|
||||||
)?.[1] || (await (user as User).openDM())
|
) || (await (user as User).openDM())
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -469,7 +426,7 @@ const generateInfractionDMEmbed = (
|
||||||
) => {
|
) => {
|
||||||
const embed: SendableEmbed = {
|
const embed: SendableEmbed = {
|
||||||
title: server.name,
|
title: server.name,
|
||||||
icon_url: server.generateIconURL({ max_side: 128 }),
|
icon_url: server.icon?.createFileURL({ max_side: 128 }),
|
||||||
colour: "#ff9e2f",
|
colour: "#ff9e2f",
|
||||||
url: message.url,
|
url: message.url,
|
||||||
description:
|
description:
|
||||||
|
@ -485,7 +442,7 @@ const generateInfractionDMEmbed = (
|
||||||
`**Reason:** ${infraction.reason}\n` +
|
`**Reason:** ${infraction.reason}\n` +
|
||||||
`**Moderator:** [@${sanitizeMessageContent(
|
`**Moderator:** [@${sanitizeMessageContent(
|
||||||
message.author?.username || "Unknown"
|
message.author?.username || "Unknown"
|
||||||
)}](/@${message.author_id})\n` +
|
)}](/@${message.authorId})\n` +
|
||||||
`**Infraction ID:** \`${infraction._id}\`` +
|
`**Infraction ID:** \`${infraction._id}\`` +
|
||||||
(infraction.actionType == "ban" && infraction.expires
|
(infraction.actionType == "ban" && infraction.expires
|
||||||
? infraction.expires == Infinity
|
? infraction.expires == Infinity
|
||||||
|
@ -545,14 +502,13 @@ const yesNoMessage = (
|
||||||
});
|
});
|
||||||
|
|
||||||
let destroyed = false;
|
let destroyed = false;
|
||||||
const cb = async (packet: ClientboundNotification) => {
|
const cb = async (m: Message, userId: string, emoji: string) => {
|
||||||
if (packet.type != "MessageReact") return;
|
if (m.id != msg.id) return;
|
||||||
if (packet.id != msg._id) return;
|
if (userId != allowedUser) return;
|
||||||
if (packet.user_id != allowedUser) return;
|
|
||||||
|
|
||||||
switch (packet.emoji_id) {
|
switch (emoji) {
|
||||||
case EMOJI_YES:
|
case EMOJI_YES:
|
||||||
channel.client.removeListener("packet", cb);
|
client.removeListener("messageReactionAdd", cb);
|
||||||
destroyed = true;
|
destroyed = true;
|
||||||
resolve(true);
|
resolve(true);
|
||||||
msg.edit({
|
msg.edit({
|
||||||
|
@ -569,7 +525,7 @@ const yesNoMessage = (
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EMOJI_NO:
|
case EMOJI_NO:
|
||||||
channel.client.removeListener("packet", cb);
|
client.removeListener("messageReactionAdd", cb);
|
||||||
destroyed = true;
|
destroyed = true;
|
||||||
resolve(false);
|
resolve(false);
|
||||||
msg.edit({
|
msg.edit({
|
||||||
|
@ -587,16 +543,16 @@ const yesNoMessage = (
|
||||||
|
|
||||||
default:
|
default:
|
||||||
logger.warn(
|
logger.warn(
|
||||||
"Received unexpected reaction: " + packet.emoji_id
|
"Received unexpected reaction: " + emoji
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
channel.client.on("packet", cb);
|
client.on("messageReactionAdd", cb);
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (!destroyed) {
|
if (!destroyed) {
|
||||||
resolve(false);
|
resolve(false);
|
||||||
channel.client.removeListener("packet", cb);
|
client.removeListener("messageReactionAdd", cb);
|
||||||
msg.edit({
|
msg.edit({
|
||||||
embeds: [
|
embeds: [
|
||||||
{
|
{
|
||||||
|
@ -615,14 +571,19 @@ const yesNoMessage = (
|
||||||
|
|
||||||
// Get all cached members of a server. Whoever put STRINGIFIED JSON as map keys is now on my hit list.
|
// Get all cached members of a server. Whoever put STRINGIFIED JSON as map keys is now on my hit list.
|
||||||
const getMembers = (id: string) =>
|
const getMembers = (id: string) =>
|
||||||
Array.from(client.members.entries())
|
Array.from(client.serverMembers.entries())
|
||||||
.filter((item) => item[0].includes(`"${id}"`))
|
.filter((item) => item[0].includes(`"${id}"`))
|
||||||
.map((entry) => entry[1]);
|
.map((entry) => entry[1]);
|
||||||
|
|
||||||
|
const memberRanking = (member: ServerMember) => {
|
||||||
|
const inferior = (member.server?.member?.ranking ?? Infinity) < member.ranking;
|
||||||
|
const kickable = member.server?.havePermission('KickMembers') && inferior;
|
||||||
|
const bannable = member.server?.havePermission('BanMembers') && inferior;
|
||||||
|
|
||||||
|
return { inferior, kickable, bannable }
|
||||||
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
getAutumnURL,
|
|
||||||
hasPerm,
|
|
||||||
hasPermForChannel,
|
|
||||||
getOwnMemberInServer,
|
getOwnMemberInServer,
|
||||||
isModerator,
|
isModerator,
|
||||||
isBotManager,
|
isBotManager,
|
||||||
|
@ -642,6 +603,7 @@ export {
|
||||||
generateInfractionDMEmbed,
|
generateInfractionDMEmbed,
|
||||||
yesNoMessage,
|
yesNoMessage,
|
||||||
getMembers,
|
getMembers,
|
||||||
|
memberRanking,
|
||||||
EmbedColor,
|
EmbedColor,
|
||||||
NO_MANAGER_MSG,
|
NO_MANAGER_MSG,
|
||||||
ULID_REGEX,
|
ULID_REGEX,
|
||||||
|
|
|
@ -18,12 +18,6 @@ logger.info('Initializing client');
|
||||||
|
|
||||||
let db = MongoDB();
|
let db = MongoDB();
|
||||||
let client = new AutomodClient({
|
let client = new AutomodClient({
|
||||||
// pongTimeout: 10,
|
|
||||||
// onPongTimeout: 'RECONNECT',
|
|
||||||
fixReplyCrash: true,
|
|
||||||
messageTimeoutFix: true,
|
|
||||||
apiURL: process.env.API_URL,
|
|
||||||
messageRateLimiter: true,
|
|
||||||
autoReconnect: true,
|
autoReconnect: true,
|
||||||
}, db);
|
}, db);
|
||||||
login(client);
|
login(client);
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
import * as Revolt from "@janderedev/revolt.js";
|
import * as Revolt from "revolt.js";
|
||||||
import { IMonkManager } from 'monk';
|
import { IMonkManager } from 'monk';
|
||||||
import logger from '../bot/logger';
|
import logger from '../bot/logger';
|
||||||
import { adminBotLog } from "../bot/logging";
|
import { adminBotLog } from "../bot/logging";
|
||||||
|
import { ClientOptions } from "revolt.js/src/Client";
|
||||||
|
|
||||||
class AutomodClient extends Revolt.Client {
|
class AutomodClient extends Revolt.Client {
|
||||||
db: IMonkManager;
|
db: IMonkManager;
|
||||||
|
|
||||||
constructor(options: Partial<Revolt.ClientOptions> | undefined, monk: IMonkManager) {
|
constructor(options: Partial<ClientOptions> | undefined, monk: IMonkManager) {
|
||||||
super(options);
|
super(options);
|
||||||
|
|
||||||
this.db = monk;
|
this.db = monk;
|
||||||
|
@ -29,13 +30,6 @@ let login = (client: Revolt.Client): Promise<void> => new Promise((resolve, reje
|
||||||
adminBotLog({ message: 'Bot logged in', type: 'INFO' });
|
adminBotLog({ message: 'Bot logged in', type: 'INFO' });
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
|
|
||||||
client.on('packet', packet => {
|
|
||||||
if (packet.type == 'InvalidSession' as any) {
|
|
||||||
logger.error('Authentication failed: ' + JSON.stringify(packet));
|
|
||||||
process.exit(99);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default AutomodClient;
|
export default AutomodClient;
|
||||||
|
|
|
@ -1,14 +1,9 @@
|
||||||
import { Message } from "@janderedev/revolt.js/dist/maps/Messages";
|
import { Message } from "revolt.js";
|
||||||
import { Server } from "@janderedev/revolt.js/dist/maps/Servers";
|
import { Server } from "revolt.js";
|
||||||
import logger from "../bot/logger";
|
|
||||||
|
|
||||||
class MessageCommandContext extends Message {
|
class MessageCommandContext extends Message {
|
||||||
// The server to which the command should be applied.
|
// The server to which the command should be applied.
|
||||||
serverContext: Server;
|
serverContext: Server;
|
||||||
|
|
||||||
/* Override types */
|
|
||||||
|
|
||||||
declare content: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default MessageCommandContext;
|
export default MessageCommandContext;
|
||||||
|
|
183
bot/yarn.lock
183
bot/yarn.lock
|
@ -25,22 +25,6 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@insertish/exponential-backoff@npm:3.1.0-patch.2":
|
|
||||||
version: 3.1.0-patch.2
|
|
||||||
resolution: "@insertish/exponential-backoff@npm:3.1.0-patch.2"
|
|
||||||
checksum: 510a531965965c8cc633a91653ca09ffa8408925eb403d07c072bed065ec8ce429b4fd42fb0639a3dbee73d300d4422c306ebaaab3292b06778a224a2b5b0bf1
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"@insertish/isomorphic-ws@npm:^4.0.1":
|
|
||||||
version: 4.0.1
|
|
||||||
resolution: "@insertish/isomorphic-ws@npm:4.0.1"
|
|
||||||
peerDependencies:
|
|
||||||
ws: "*"
|
|
||||||
checksum: 64e6464b379784d0c8df31868eb8301b3e3827f91131755c38f66a007fcd791314c6ef49f3ead37bb5d62cc7fd52f2171b2e0ce04564a744905f72d3cd86f1ba
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"@insertish/oapi@npm:0.1.18":
|
"@insertish/oapi@npm:0.1.18":
|
||||||
version: 0.1.18
|
version: 0.1.18
|
||||||
resolution: "@insertish/oapi@npm:0.1.18"
|
resolution: "@insertish/oapi@npm:0.1.18"
|
||||||
|
@ -59,26 +43,6 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@janderedev/revolt.js@npm:latest":
|
|
||||||
version: 6.0.20-patch.9
|
|
||||||
resolution: "@janderedev/revolt.js@npm:6.0.20-patch.9"
|
|
||||||
dependencies:
|
|
||||||
"@insertish/exponential-backoff": 3.1.0-patch.2
|
|
||||||
"@insertish/isomorphic-ws": ^4.0.1
|
|
||||||
axios: ^0.21.4
|
|
||||||
eventemitter3: ^4.0.7
|
|
||||||
lodash.defaultsdeep: ^4.6.1
|
|
||||||
lodash.flatten: ^4.4.0
|
|
||||||
lodash.isequal: ^4.5.0
|
|
||||||
long: ^5.2.0
|
|
||||||
mobx: ^6.3.2
|
|
||||||
revolt-api: 0.5.16
|
|
||||||
ulid: ^2.3.0
|
|
||||||
ws: ^8.2.2
|
|
||||||
checksum: 942f8cb7339f6378738d97ff788680dc63c287624e749b95b867a82c877bc6416a4a7b85264bf8797e034132d5a84843d75b820b6a1c37a760a88f13114772a0
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"@sapphire/async-queue@npm:^1.5.0":
|
"@sapphire/async-queue@npm:^1.5.0":
|
||||||
version: 1.5.0
|
version: 1.5.0
|
||||||
resolution: "@sapphire/async-queue@npm:1.5.0"
|
resolution: "@sapphire/async-queue@npm:1.5.0"
|
||||||
|
@ -96,6 +60,48 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@solid-primitives/map@npm:^0.4.3":
|
||||||
|
version: 0.4.3
|
||||||
|
resolution: "@solid-primitives/map@npm:0.4.3"
|
||||||
|
dependencies:
|
||||||
|
"@solid-primitives/trigger": ^1.0.3
|
||||||
|
peerDependencies:
|
||||||
|
solid-js: ^1.6.12
|
||||||
|
checksum: e2408d7309c2bc0b93126771ad796cc3cbc2b150a03b4f3d4963dbc6df2ad26e671277fc14aafe1c117f1228c35557686e709accd6237ac511d2e05a6682006d
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@solid-primitives/set@npm:^0.4.3":
|
||||||
|
version: 0.4.3
|
||||||
|
resolution: "@solid-primitives/set@npm:0.4.3"
|
||||||
|
dependencies:
|
||||||
|
"@solid-primitives/trigger": ^1.0.3
|
||||||
|
peerDependencies:
|
||||||
|
solid-js: ^1.6.12
|
||||||
|
checksum: fcab5679185633b887d6d9ef4c12ded12d1773969a66079ce98dc18bbb2869f9fe743a1f3cd1f5721b52dcd274ae096470daa8ab1284643b4b26eeb28b7a5698
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@solid-primitives/trigger@npm:^1.0.3":
|
||||||
|
version: 1.0.5
|
||||||
|
resolution: "@solid-primitives/trigger@npm:1.0.5"
|
||||||
|
dependencies:
|
||||||
|
"@solid-primitives/utils": ^6.0.0
|
||||||
|
peerDependencies:
|
||||||
|
solid-js: ^1.6.12
|
||||||
|
checksum: 5f137ec425b317c09de6b994928992201206c16be7a01f7add46e0ee987d76a947a7f4f9396a945eeb671c43307b6f5d55bd57d90738880cebdaa0907aca65dd
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@solid-primitives/utils@npm:^6.0.0":
|
||||||
|
version: 6.0.0
|
||||||
|
resolution: "@solid-primitives/utils@npm:6.0.0"
|
||||||
|
peerDependencies:
|
||||||
|
solid-js: ^1.6.12
|
||||||
|
checksum: c581b995e2d16c9ed0546baef52a9e60f54dda457a3733bac467a19f2a63227179eb0ec6faa16397af4cacc13fa281288cf967a206b0a75255412fafadc55411
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@types/bson@npm:*":
|
"@types/bson@npm:*":
|
||||||
version: 4.0.5
|
version: 4.0.5
|
||||||
resolution: "@types/bson@npm:4.0.5"
|
resolution: "@types/bson@npm:4.0.5"
|
||||||
|
@ -196,15 +202,6 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
"axios@npm:^0.21.4":
|
|
||||||
version: 0.21.4
|
|
||||||
resolution: "axios@npm:0.21.4"
|
|
||||||
dependencies:
|
|
||||||
follow-redirects: ^1.14.0
|
|
||||||
checksum: 44245f24ac971e7458f3120c92f9d66d1fc695e8b97019139de5b0cc65d9b8104647db01e5f46917728edfc0cfd88eb30fc4c55e6053eef4ace76768ce95ff3c
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"axios@npm:^0.22.0":
|
"axios@npm:^0.22.0":
|
||||||
version: 0.22.0
|
version: 0.22.0
|
||||||
resolution: "axios@npm:0.22.0"
|
resolution: "axios@npm:0.22.0"
|
||||||
|
@ -298,6 +295,13 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"csstype@npm:^3.1.0":
|
||||||
|
version: 3.1.2
|
||||||
|
resolution: "csstype@npm:3.1.2"
|
||||||
|
checksum: e1a52e6c25c1314d6beef5168da704ab29c5186b877c07d822bd0806717d9a265e8493a2e35ca7e68d0f5d472d43fac1cdce70fd79fd0853dff81f3028d857b5
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"dayjs@npm:^1.10.7":
|
"dayjs@npm:^1.10.7":
|
||||||
version: 1.11.7
|
version: 1.11.7
|
||||||
resolution: "dayjs@npm:1.11.7"
|
resolution: "dayjs@npm:1.11.7"
|
||||||
|
@ -369,10 +373,10 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"eventemitter3@npm:^4.0.7":
|
"eventemitter3@npm:^5.0.0":
|
||||||
version: 4.0.7
|
version: 5.0.0
|
||||||
resolution: "eventemitter3@npm:4.0.7"
|
resolution: "eventemitter3@npm:5.0.0"
|
||||||
checksum: 1875311c42fcfe9c707b2712c32664a245629b42bb0a5a84439762dd0fd637fc54d078155ea83c2af9e0323c9ac13687e03cfba79b03af9f40c89b4960099374
|
checksum: b974bafbab860e0a5bbb21add4c4e82f9d5691c583c03f2e4c5d44a2d6c4556d79223621bdcfc6c8e14366a4af9df6b5ea9d6caf65fbffc80b66f3e1dceacbc9
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
@ -390,7 +394,7 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"follow-redirects@npm:^1.14.0, follow-redirects@npm:^1.14.4, follow-redirects@npm:^1.14.8":
|
"follow-redirects@npm:^1.14.4, follow-redirects@npm:^1.14.8":
|
||||||
version: 1.15.2
|
version: 1.15.2
|
||||||
resolution: "follow-redirects@npm:1.15.2"
|
resolution: "follow-redirects@npm:1.15.2"
|
||||||
peerDependenciesMeta:
|
peerDependenciesMeta:
|
||||||
|
@ -457,6 +461,15 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"isomorphic-ws@npm:^5.0.0":
|
||||||
|
version: 5.0.0
|
||||||
|
resolution: "isomorphic-ws@npm:5.0.0"
|
||||||
|
peerDependencies:
|
||||||
|
ws: "*"
|
||||||
|
checksum: e20eb2aee09ba96247465fda40c6d22c1153394c0144fa34fe6609f341af4c8c564f60ea3ba762335a7a9c306809349f9b863c8beedf2beea09b299834ad5398
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"js-yaml@npm:^4.1.0":
|
"js-yaml@npm:^4.1.0":
|
||||||
version: 4.1.0
|
version: 4.1.0
|
||||||
resolution: "js-yaml@npm:4.1.0"
|
resolution: "js-yaml@npm:4.1.0"
|
||||||
|
@ -475,20 +488,6 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"lodash.flatten@npm:^4.4.0":
|
|
||||||
version: 4.4.0
|
|
||||||
resolution: "lodash.flatten@npm:4.4.0"
|
|
||||||
checksum: 0ac34a393d4b795d4b7421153d27c13ae67e08786c9cbb60ff5b732210d46f833598eee3fb3844bb10070e8488efe390ea53bb567377e0cb47e9e630bf0811cb
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"lodash.isequal@npm:^4.5.0":
|
|
||||||
version: 4.5.0
|
|
||||||
resolution: "lodash.isequal@npm:4.5.0"
|
|
||||||
checksum: da27515dc5230eb1140ba65ff8de3613649620e8656b19a6270afe4866b7bd461d9ba2ac8a48dcc57f7adac4ee80e1de9f965d89d4d81a0ad52bb3eec2609644
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"lodash@npm:^4.17.21":
|
"lodash@npm:^4.17.21":
|
||||||
version: 4.17.21
|
version: 4.17.21
|
||||||
resolution: "lodash@npm:4.17.21"
|
resolution: "lodash@npm:4.17.21"
|
||||||
|
@ -505,7 +504,7 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"long@npm:^5.2.0":
|
"long@npm:^5.2.1":
|
||||||
version: 5.2.1
|
version: 5.2.1
|
||||||
resolution: "long@npm:5.2.1"
|
resolution: "long@npm:5.2.1"
|
||||||
checksum: 9264da12d1b7df67e5aa6da4498144293caf1ad12e7f092efe4e9a2d32c53f0bbf7334f7cef997080a2a3af061142558ab366efa71698d98b1cdb883477445a7
|
checksum: 9264da12d1b7df67e5aa6da4498144293caf1ad12e7f092efe4e9a2d32c53f0bbf7334f7cef997080a2a3af061142558ab366efa71698d98b1cdb883477445a7
|
||||||
|
@ -544,13 +543,6 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"mobx@npm:^6.3.2":
|
|
||||||
version: 6.8.0
|
|
||||||
resolution: "mobx@npm:6.8.0"
|
|
||||||
checksum: f09bb079292ea59023a7e35a9c73ed577e3de9a0175ec3d5a2adc8192e2e3a352b29ec0981ee06d1d63f701f81bb7fc6cc19fd9089edf84a754a8a75ef00ef7f
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"mongodb@npm:^3.2.3":
|
"mongodb@npm:^3.2.3":
|
||||||
version: 3.7.3
|
version: 3.7.3
|
||||||
resolution: "mongodb@npm:3.7.3"
|
resolution: "mongodb@npm:3.7.3"
|
||||||
|
@ -750,14 +742,14 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"revolt-api@npm:0.5.16, revolt-api@npm:^0.5.16":
|
"revolt-api@npm:^0.5.17, revolt-api@npm:latest":
|
||||||
version: 0.5.16
|
version: 0.5.17
|
||||||
resolution: "revolt-api@npm:0.5.16"
|
resolution: "revolt-api@npm:0.5.17"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@insertish/oapi": 0.1.18
|
"@insertish/oapi": 0.1.18
|
||||||
axios: ^0.26.1
|
axios: ^0.26.1
|
||||||
lodash.defaultsdeep: ^4.6.1
|
lodash.defaultsdeep: ^4.6.1
|
||||||
checksum: ce39f61e371c1b7da0704191317bccf88b6630f1d8ffcef6bc9c699ebdc8cfbb3fcc5e054f96f9751c2f4a048398d4b349670cd067bcaad2e099d0c30efd9cfe
|
checksum: aa722f4739c09bea46f738a1b9aef61af126e06aa924a61fcf33caa53561c5de4e7e2ddde26b496cdd0546e113cf324821fead0035973e2ebdb2633df482091b
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
@ -765,7 +757,6 @@ __metadata:
|
||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "revolt-automod@workspace:."
|
resolution: "revolt-automod@workspace:."
|
||||||
dependencies:
|
dependencies:
|
||||||
"@janderedev/revolt.js": latest
|
|
||||||
"@types/monk": ^6.0.0
|
"@types/monk": ^6.0.0
|
||||||
automod: ^0.1.0
|
automod: ^0.1.0
|
||||||
axios: ^0.22.0
|
axios: ^0.22.0
|
||||||
|
@ -776,13 +767,30 @@ __metadata:
|
||||||
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.16
|
revolt-api: latest
|
||||||
|
revolt.js: ^7.0.0
|
||||||
typescript: ^4.4.3
|
typescript: ^4.4.3
|
||||||
ulid: ^2.3.0
|
ulid: ^2.3.0
|
||||||
xlsx: ^0.17.3
|
xlsx: ^0.17.3
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
|
"revolt.js@portal:../revolt.js::locator=revolt-automod%40workspace%3A.":
|
||||||
|
version: 0.0.0-use.local
|
||||||
|
resolution: "revolt.js@portal:../revolt.js::locator=revolt-automod%40workspace%3A."
|
||||||
|
dependencies:
|
||||||
|
"@solid-primitives/map": ^0.4.3
|
||||||
|
"@solid-primitives/set": ^0.4.3
|
||||||
|
eventemitter3: ^5.0.0
|
||||||
|
isomorphic-ws: ^5.0.0
|
||||||
|
long: ^5.2.1
|
||||||
|
revolt-api: ^0.5.17
|
||||||
|
solid-js: ^1.7.2
|
||||||
|
ulid: ^2.3.0
|
||||||
|
ws: ^8.13.0
|
||||||
|
languageName: node
|
||||||
|
linkType: soft
|
||||||
|
|
||||||
"safe-buffer@npm:^5.1.1, safe-buffer@npm:^5.1.2":
|
"safe-buffer@npm:^5.1.1, safe-buffer@npm:^5.1.2":
|
||||||
version: 5.2.1
|
version: 5.2.1
|
||||||
resolution: "safe-buffer@npm:5.2.1"
|
resolution: "safe-buffer@npm:5.2.1"
|
||||||
|
@ -806,6 +814,23 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"seroval@npm:^0.5.0":
|
||||||
|
version: 0.5.1
|
||||||
|
resolution: "seroval@npm:0.5.1"
|
||||||
|
checksum: a4c1e42d6a65ed12de3c1f1b6a5b6b996e575c5bc838e1998e92daed7bc05421f3f6c82096387082dba33c475d64a31d0d932ac9b693352549259216e38dc091
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"solid-js@npm:^1.7.2":
|
||||||
|
version: 1.7.3
|
||||||
|
resolution: "solid-js@npm:1.7.3"
|
||||||
|
dependencies:
|
||||||
|
csstype: ^3.1.0
|
||||||
|
seroval: ^0.5.0
|
||||||
|
checksum: 052a3148b6d0960312793781435005c16a7a80c2271e2bf2370ec22ec57ffd77e3e4a41335c1bd785ab36500adef86da79536445983efbed404db860e11593d4
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"sparse-bitfield@npm:^3.0.3":
|
"sparse-bitfield@npm:^3.0.3":
|
||||||
version: 3.0.3
|
version: 3.0.3
|
||||||
resolution: "sparse-bitfield@npm:3.0.3"
|
resolution: "sparse-bitfield@npm:3.0.3"
|
||||||
|
@ -956,7 +981,7 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"ws@npm:^8.2.2, ws@npm:^8.9.0":
|
"ws@npm:^8.13.0, ws@npm:^8.9.0":
|
||||||
version: 8.13.0
|
version: 8.13.0
|
||||||
resolution: "ws@npm:8.13.0"
|
resolution: "ws@npm:8.13.0"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@discordjs/rest": "^0.4.1",
|
"@discordjs/rest": "^0.4.1",
|
||||||
"@janderedev/revolt.js": "latest",
|
|
||||||
"automod": "^0.1.0",
|
"automod": "^0.1.0",
|
||||||
"axios": "^0.26.1",
|
"axios": "^0.26.1",
|
||||||
"discord-api-types": "^0.31.2",
|
"discord-api-types": "^0.31.2",
|
||||||
|
@ -25,7 +24,8 @@
|
||||||
"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.8",
|
"revolt-api": "latest",
|
||||||
|
"revolt.js": "^7.0.0",
|
||||||
"smart-replace": "^1.0.2",
|
"smart-replace": "^1.0.2",
|
||||||
"ulid": "^2.3.0"
|
"ulid": "^2.3.0"
|
||||||
},
|
},
|
||||||
|
@ -34,6 +34,7 @@
|
||||||
"typescript": "^4.7.4"
|
"typescript": "^4.7.4"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"automod": "portal:../lib"
|
"automod": "portal:../lib",
|
||||||
|
"revolt.js": "portal:../revolt.js"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -303,7 +303,7 @@ client.on("interactionCreate", async (interaction) => {
|
||||||
embed.addField(
|
embed.addField(
|
||||||
"Adding AutoMod to your server",
|
"Adding AutoMod to your server",
|
||||||
`You can add the Revolt bot to your server ` +
|
`You can add the Revolt bot to your server ` +
|
||||||
`[here](https://app.revolt.chat/bot/${revoltClient.user?._id} "Open Revolt"). To add the Discord counterpart, ` +
|
`[here](https://app.revolt.chat/bot/${revoltClient.user?.id} "Open Revolt"). To add the Discord counterpart, ` +
|
||||||
`click [here](${INVITE_URL} "Add Discord bot").`
|
`click [here](${INVITE_URL} "Add Discord bot").`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -480,11 +480,11 @@ client.on("interactionCreate", async (interaction) => {
|
||||||
|
|
||||||
if (revoltMsg) {
|
if (revoltMsg) {
|
||||||
const author = await revoltFetchUser(
|
const author = await revoltFetchUser(
|
||||||
revoltMsg.author_id
|
revoltMsg.authorId
|
||||||
);
|
);
|
||||||
embed.addField(
|
embed.addField(
|
||||||
"Message Author",
|
"Message Author",
|
||||||
`**@${author?.username}** (${revoltMsg.author_id})`
|
`**@${author?.username}** (${revoltMsg.authorId})`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { BRIDGED_MESSAGES, BRIDGE_CONFIG, BRIDGE_USER_CONFIG, logger } from "..";
|
import { BRIDGED_MESSAGES, BRIDGE_CONFIG, BRIDGE_USER_CONFIG, logger } from "..";
|
||||||
import { client } from "./client";
|
import { client } from "./client";
|
||||||
import { AUTUMN_URL, client as revoltClient } from "../revolt/client";
|
import { client as revoltClient } from "../revolt/client";
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { ulid } from "ulid";
|
import { ulid } from "ulid";
|
||||||
import GenericEmbed from "../types/GenericEmbed";
|
import GenericEmbed from "../types/GenericEmbed";
|
||||||
|
@ -196,7 +196,7 @@ client.on("messageCreate", async (message) => {
|
||||||
await BRIDGED_MESSAGES.update(
|
await BRIDGED_MESSAGES.update(
|
||||||
{ "discord.messageId": message.id },
|
{ "discord.messageId": message.id },
|
||||||
{
|
{
|
||||||
$set: { "revolt.messageId": msg._id },
|
$set: { "revolt.messageId": msg.id },
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -233,7 +233,7 @@ client.on("messageCreate", async (message) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const res = await axios.post(
|
const res = await axios.post(
|
||||||
`${AUTUMN_URL}/attachments`,
|
`${revoltClient.configuration?.features.autumn.url}/attachments`,
|
||||||
formData,
|
formData,
|
||||||
{ headers: formData.getHeaders() }
|
{ headers: formData.getHeaders() }
|
||||||
);
|
);
|
||||||
|
@ -280,7 +280,7 @@ client.on("messageCreate", async (message) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const res = await axios.post(
|
const res = await axios.post(
|
||||||
`${AUTUMN_URL}/attachments`,
|
`${revoltClient.configuration?.features.autumn.url}/attachments`,
|
||||||
formData,
|
formData,
|
||||||
{ headers: formData.getHeaders() }
|
{ headers: formData.getHeaders() }
|
||||||
);
|
);
|
||||||
|
@ -338,7 +338,7 @@ client.on("messageCreate", async (message) => {
|
||||||
|
|
||||||
await axios
|
await axios
|
||||||
.post(
|
.post(
|
||||||
`${revoltClient.apiURL}/channels/${channel._id}/messages`,
|
`${revoltClient.options.baseURL}/channels/${channel.id}/messages`,
|
||||||
payload,
|
payload,
|
||||||
{
|
{
|
||||||
headers: {
|
headers: {
|
||||||
|
@ -474,7 +474,7 @@ async function renderMessageBody(message: string): Promise<string> {
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
return revoltChannel
|
return revoltChannel
|
||||||
? `<#${revoltChannel._id}>`
|
? `<#${revoltChannel.id}>`
|
||||||
: `#${(channel as TextChannel)?.name || id}`;
|
: `#${(channel as TextChannel)?.name || id}`;
|
||||||
},
|
},
|
||||||
{ cacheMatchResults: true, maxMatches: 10 }
|
{ cacheMatchResults: true, maxMatches: 10 }
|
||||||
|
|
|
@ -1,21 +1,18 @@
|
||||||
import { Client } from '@janderedev/revolt.js';
|
import { Client } from 'revolt.js';
|
||||||
import axios from 'axios';
|
|
||||||
import { logger } from '..';
|
import { logger } from '..';
|
||||||
|
|
||||||
let AUTUMN_URL = `http://autumnUrl`;
|
let AUTUMN_URL: string = '';
|
||||||
|
|
||||||
const client = new Client({
|
const client = new Client({
|
||||||
apiURL: process.env.REVOLT_API_URL,
|
baseURL: process.env.REVOLT_API_URL || 'https://api.revolt.chat',
|
||||||
autoReconnect: true,
|
autoReconnect: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const login = () => new Promise((resolve: (value: Client) => void) => {
|
const login = () => new Promise((resolve: (value: Client) => void) => {
|
||||||
client.loginBot(process.env['REVOLT_TOKEN']!);
|
client.loginBot(process.env['REVOLT_TOKEN']!);
|
||||||
client.once('ready', async () => {
|
client.once('ready', async () => {
|
||||||
logger.info(`Revolt: ${client.user?.username} ready - ${client.servers.size} servers`);
|
logger.info(`Revolt: ${client.user?.username} ready - ${client.servers.size()} servers`);
|
||||||
|
AUTUMN_URL = client.configuration?.features.autumn.url ?? '';
|
||||||
const apiConfig = await axios.get(client.apiURL);
|
|
||||||
AUTUMN_URL = apiConfig.data?.features?.autumn?.url;
|
|
||||||
|
|
||||||
resolve(client);
|
resolve(client);
|
||||||
});
|
});
|
||||||
|
|
|
@ -26,7 +26,7 @@ fetchEmojiList()
|
||||||
)
|
)
|
||||||
.catch((e) => console.error(e));
|
.catch((e) => console.error(e));
|
||||||
|
|
||||||
client.on("message/delete", async (id) => {
|
client.on("messageDelete", async (id) => {
|
||||||
try {
|
try {
|
||||||
logger.debug(`[D] Revolt: ${id}`);
|
logger.debug(`[D] Revolt: ${id}`);
|
||||||
|
|
||||||
|
@ -83,15 +83,15 @@ client.on("message/delete", async (id) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
client.on("message/update", async (message) => {
|
client.on("messageUpdate", async (message) => {
|
||||||
if (!message.content || typeof message.content != "string") return;
|
if (!message.content || typeof message.content != "string") return;
|
||||||
if (message.author_id == client.user?._id) return;
|
if (message.authorId == client.user?.id) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
logger.debug(`[E] Revolt: ${message.content}`);
|
logger.debug(`[E] Revolt: ${message.content}`);
|
||||||
|
|
||||||
const [bridgeCfg, bridgedMsg] = await Promise.all([
|
const [bridgeCfg, bridgedMsg] = await Promise.all([
|
||||||
BRIDGE_CONFIG.findOne({ revolt: message.channel_id }),
|
BRIDGE_CONFIG.findOne({ revolt: message.channelId }),
|
||||||
BRIDGED_MESSAGES.findOne({ "revolt.nonce": message.nonce }),
|
BRIDGED_MESSAGES.findOne({ "revolt.nonce": message.nonce }),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -127,18 +127,18 @@ client.on("message/update", async (message) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
client.on("message", async (message) => {
|
client.on("messageCreate", async (message) => {
|
||||||
try {
|
try {
|
||||||
logger.debug(`[M] Revolt: ${message._id} ${message.content}`);
|
logger.debug(`[M] Revolt: ${message.id} ${message.content}`);
|
||||||
|
|
||||||
const [bridgeCfg, bridgedMsg, ...repliedMessages] = await Promise.all([
|
const [bridgeCfg, bridgedMsg, ...repliedMessages] = await Promise.all([
|
||||||
BRIDGE_CONFIG.findOne({ revolt: message.channel_id }),
|
BRIDGE_CONFIG.findOne({ revolt: message.channelId }),
|
||||||
BRIDGED_MESSAGES.findOne(
|
BRIDGED_MESSAGES.findOne(
|
||||||
message.nonce
|
message.nonce
|
||||||
? { "revolt.nonce": message.nonce }
|
? { "revolt.nonce": message.nonce }
|
||||||
: { "revolt.messageId": message._id }
|
: { "revolt.messageId": message.id }
|
||||||
),
|
),
|
||||||
...(message.reply_ids?.map((id) =>
|
...(message.replyIds?.map((id) =>
|
||||||
BRIDGED_MESSAGES.findOne({ "revolt.messageId": id })
|
BRIDGED_MESSAGES.findOne({ "revolt.messageId": id })
|
||||||
) ?? []),
|
) ?? []),
|
||||||
]);
|
]);
|
||||||
|
@ -147,7 +147,7 @@ client.on("message", async (message) => {
|
||||||
return logger.debug(
|
return logger.debug(
|
||||||
`Revolt: Message has already been bridged; ignoring`
|
`Revolt: Message has already been bridged; ignoring`
|
||||||
);
|
);
|
||||||
if (message.system && bridgeCfg?.config?.disable_system_messages)
|
if (message.systemMessage && bridgeCfg?.config?.disable_system_messages)
|
||||||
return logger.debug(
|
return logger.debug(
|
||||||
`Revolt: System message bridging disabled; ignoring`
|
`Revolt: System message bridging disabled; ignoring`
|
||||||
);
|
);
|
||||||
|
@ -182,7 +182,7 @@ client.on("message", async (message) => {
|
||||||
token: hook.token || "",
|
token: hook.token || "",
|
||||||
};
|
};
|
||||||
await BRIDGE_CONFIG.update(
|
await BRIDGE_CONFIG.update(
|
||||||
{ revolt: message.channel_id },
|
{ revolt: message.channelId },
|
||||||
{
|
{
|
||||||
$set: {
|
$set: {
|
||||||
discordWebhook: bridgeCfg.discordWebhook,
|
discordWebhook: bridgeCfg.discordWebhook,
|
||||||
|
@ -193,7 +193,7 @@ client.on("message", async (message) => {
|
||||||
logger.warn(
|
logger.warn(
|
||||||
`Unable to create new webhook for channel ${bridgeCfg.discord}; Deleting link\n${e}`
|
`Unable to create new webhook for channel ${bridgeCfg.discord}; Deleting link\n${e}`
|
||||||
);
|
);
|
||||||
await BRIDGE_CONFIG.remove({ revolt: message.channel_id });
|
await BRIDGE_CONFIG.remove({ revolt: message.channelId });
|
||||||
await message.channel
|
await message.channel
|
||||||
?.sendMessage(
|
?.sendMessage(
|
||||||
":warning: I was unable to create a webhook in the bridged Discord channel. " +
|
":warning: I was unable to create a webhook in the bridged Discord channel. " +
|
||||||
|
@ -206,15 +206,15 @@ client.on("message", async (message) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
await BRIDGED_MESSAGES.update(
|
await BRIDGED_MESSAGES.update(
|
||||||
{ "revolt.messageId": message._id },
|
{ "revolt.messageId": message.id },
|
||||||
{
|
{
|
||||||
$set: {
|
$set: {
|
||||||
revolt: {
|
revolt: {
|
||||||
messageId: message._id,
|
messageId: message.id,
|
||||||
nonce: message.nonce,
|
nonce: message.nonce,
|
||||||
},
|
},
|
||||||
channels: {
|
channels: {
|
||||||
revolt: message.channel_id,
|
revolt: message.channelId,
|
||||||
discord: bridgeCfg.discord,
|
discord: bridgeCfg.discord,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -238,23 +238,23 @@ client.on("message", async (message) => {
|
||||||
content:
|
content:
|
||||||
message.content
|
message.content
|
||||||
? await renderMessageBody(message.content)
|
? await renderMessageBody(message.content)
|
||||||
: message.system
|
: message.systemMessage
|
||||||
? await renderSystemMessage(message.system)
|
? await renderSystemMessage(message.systemMessage)
|
||||||
: undefined,
|
: undefined,
|
||||||
username: message.system
|
username: message.systemMessage
|
||||||
? "Revolt"
|
? "Revolt"
|
||||||
: (bridgeCfg.config?.bridge_nicknames
|
: (bridgeCfg.config?.bridge_nicknames
|
||||||
? message.masquerade?.name ??
|
? message.masquerade?.name ??
|
||||||
message.member?.nickname ??
|
message.member?.nickname ??
|
||||||
message.author?.username
|
message.author?.username
|
||||||
: message.author?.username) ?? "Unknown user",
|
: message.author?.username) ?? "Unknown user",
|
||||||
avatarURL: message.system
|
avatarURL: message.systemMessage
|
||||||
? "https://app.revolt.chat/assets/logo_round.png"
|
? "https://app.revolt.chat/assets/logo_round.png"
|
||||||
: bridgeCfg.config?.bridge_nicknames
|
: bridgeCfg.config?.bridge_nicknames
|
||||||
? message.masquerade?.avatar ??
|
? message.masquerade?.avatar ??
|
||||||
message.member?.generateAvatarURL({ max_side: 128 }) ??
|
message.member?.avatarURL ??
|
||||||
message.author?.generateAvatarURL({ max_side: 128 })
|
message.author?.avatarURL
|
||||||
: message.author?.generateAvatarURL({ max_side: 128 }),
|
: message.author?.avatarURL,
|
||||||
embeds: message.embeds?.length
|
embeds: message.embeds?.length
|
||||||
? message.embeds
|
? message.embeds
|
||||||
.filter((e) => e.type == "Text")
|
.filter((e) => e.type == "Text")
|
||||||
|
@ -293,15 +293,15 @@ client.on("message", async (message) => {
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
const msg = await revoltFetchMessage(
|
const msg = await revoltFetchMessage(
|
||||||
message.reply_ids?.[0],
|
message.replyIds?.[0],
|
||||||
message.channel
|
message.channel
|
||||||
);
|
);
|
||||||
const brMsg = repliedMessages.find(
|
const brMsg = repliedMessages.find(
|
||||||
(m) => m?.revolt.messageId == msg?._id
|
(m) => m?.revolt.messageId == msg?.id
|
||||||
);
|
);
|
||||||
embed.setAuthor({
|
embed.setAuthor({
|
||||||
name: `@${msg?.author?.username ?? "Unknown"}`,
|
name: `@${msg?.author?.username ?? "Unknown"}`,
|
||||||
iconURL: msg?.author?.generateAvatarURL({ size: 64 }),
|
iconURL: msg?.author?.avatarURL,
|
||||||
url: brMsg
|
url: brMsg
|
||||||
? `https://discord.com/channels/${
|
? `https://discord.com/channels/${
|
||||||
channel.guildId
|
channel.guildId
|
||||||
|
@ -338,7 +338,7 @@ client.on("message", async (message) => {
|
||||||
msgUrl = msg.url;
|
msgUrl = msg.url;
|
||||||
} else {
|
} else {
|
||||||
const brMsg = repliedMessages.find(
|
const brMsg = repliedMessages.find(
|
||||||
(m) => m?.revolt.messageId == msg?._id
|
(m) => m?.revolt.messageId == msg?.id
|
||||||
);
|
);
|
||||||
if (brMsg)
|
if (brMsg)
|
||||||
msgUrl = `https://discord.com/channels/${
|
msgUrl = `https://discord.com/channels/${
|
||||||
|
@ -367,7 +367,7 @@ client.on("message", async (message) => {
|
||||||
|
|
||||||
for (const attachment of message.attachments) {
|
for (const attachment of message.attachments) {
|
||||||
payload.files.push({
|
payload.files.push({
|
||||||
attachment: `${AUTUMN_URL}/attachments/${attachment._id}/${attachment.filename}`,
|
attachment: `${AUTUMN_URL}/attachments/${attachment.id}/${attachment.filename}`,
|
||||||
name: attachment.filename,
|
name: attachment.filename,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -378,7 +378,7 @@ client.on("message", async (message) => {
|
||||||
.then(async (res) => {
|
.then(async (res) => {
|
||||||
await BRIDGED_MESSAGES.update(
|
await BRIDGED_MESSAGES.update(
|
||||||
{
|
{
|
||||||
"revolt.messageId": message._id,
|
"revolt.messageId": message.id,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
$set: {
|
$set: {
|
||||||
|
@ -400,7 +400,7 @@ client.on("message", async (message) => {
|
||||||
"Revolt: Got Unknown Webhook error, deleting webhook config"
|
"Revolt: Got Unknown Webhook error, deleting webhook config"
|
||||||
);
|
);
|
||||||
await BRIDGE_CONFIG.update(
|
await BRIDGE_CONFIG.update(
|
||||||
{ revolt: message.channel_id },
|
{ revolt: message.channelId },
|
||||||
{ $set: { discordWebhook: undefined } }
|
{ $set: { discordWebhook: undefined } }
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -436,7 +436,7 @@ async function renderMessageBody(message: string): Promise<string> {
|
||||||
const channel = client.channels.get(id);
|
const channel = client.channels.get(id);
|
||||||
|
|
||||||
const bridgeCfg = channel
|
const bridgeCfg = channel
|
||||||
? await BRIDGE_CONFIG.findOne({ revolt: channel._id })
|
? await BRIDGE_CONFIG.findOne({ revolt: channel.id })
|
||||||
: undefined;
|
: undefined;
|
||||||
const discordChannel = bridgeCfg?.discord
|
const discordChannel = bridgeCfg?.discord
|
||||||
? discordClient.channels.cache.get(bridgeCfg.discord)
|
? discordClient.channels.cache.get(bridgeCfg.discord)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Channel } from "@janderedev/revolt.js/dist/maps/Channels";
|
import { Channel } from "revolt.js";
|
||||||
import { Message } from "@janderedev/revolt.js/dist/maps/Messages";
|
import { Message } from "revolt.js";
|
||||||
import { User } from "@janderedev/revolt.js/dist/maps/Users";
|
import { User } from "revolt.js";
|
||||||
import { Message as DiscordMessage, TextChannel, User as DiscordUser } from "discord.js";
|
import { Message as DiscordMessage, TextChannel, User as DiscordUser } from "discord.js";
|
||||||
import { client as discordClient } from "./discord/client";
|
import { client as discordClient } from "./discord/client";
|
||||||
import { client as revoltClient } from "./revolt/client"
|
import { client as revoltClient } from "./revolt/client"
|
||||||
|
|
183
bridge/yarn.lock
183
bridge/yarn.lock
|
@ -41,22 +41,6 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@insertish/exponential-backoff@npm:3.1.0-patch.2":
|
|
||||||
version: 3.1.0-patch.2
|
|
||||||
resolution: "@insertish/exponential-backoff@npm:3.1.0-patch.2"
|
|
||||||
checksum: 510a531965965c8cc633a91653ca09ffa8408925eb403d07c072bed065ec8ce429b4fd42fb0639a3dbee73d300d4422c306ebaaab3292b06778a224a2b5b0bf1
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"@insertish/isomorphic-ws@npm:^4.0.1":
|
|
||||||
version: 4.0.1
|
|
||||||
resolution: "@insertish/isomorphic-ws@npm:4.0.1"
|
|
||||||
peerDependencies:
|
|
||||||
ws: "*"
|
|
||||||
checksum: 64e6464b379784d0c8df31868eb8301b3e3827f91131755c38f66a007fcd791314c6ef49f3ead37bb5d62cc7fd52f2171b2e0ce04564a744905f72d3cd86f1ba
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"@insertish/oapi@npm:0.1.18":
|
"@insertish/oapi@npm:0.1.18":
|
||||||
version: 0.1.18
|
version: 0.1.18
|
||||||
resolution: "@insertish/oapi@npm:0.1.18"
|
resolution: "@insertish/oapi@npm:0.1.18"
|
||||||
|
@ -75,26 +59,6 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@janderedev/revolt.js@npm:latest":
|
|
||||||
version: 6.0.20-patch.9
|
|
||||||
resolution: "@janderedev/revolt.js@npm:6.0.20-patch.9"
|
|
||||||
dependencies:
|
|
||||||
"@insertish/exponential-backoff": 3.1.0-patch.2
|
|
||||||
"@insertish/isomorphic-ws": ^4.0.1
|
|
||||||
axios: ^0.21.4
|
|
||||||
eventemitter3: ^4.0.7
|
|
||||||
lodash.defaultsdeep: ^4.6.1
|
|
||||||
lodash.flatten: ^4.4.0
|
|
||||||
lodash.isequal: ^4.5.0
|
|
||||||
long: ^5.2.0
|
|
||||||
mobx: ^6.3.2
|
|
||||||
revolt-api: 0.5.16
|
|
||||||
ulid: ^2.3.0
|
|
||||||
ws: ^8.2.2
|
|
||||||
checksum: 942f8cb7339f6378738d97ff788680dc63c287624e749b95b867a82c877bc6416a4a7b85264bf8797e034132d5a84843d75b820b6a1c37a760a88f13114772a0
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"@sapphire/async-queue@npm:^1.3.1, @sapphire/async-queue@npm:^1.5.0":
|
"@sapphire/async-queue@npm:^1.3.1, @sapphire/async-queue@npm:^1.5.0":
|
||||||
version: 1.5.0
|
version: 1.5.0
|
||||||
resolution: "@sapphire/async-queue@npm:1.5.0"
|
resolution: "@sapphire/async-queue@npm:1.5.0"
|
||||||
|
@ -119,6 +83,48 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@solid-primitives/map@npm:^0.4.3":
|
||||||
|
version: 0.4.3
|
||||||
|
resolution: "@solid-primitives/map@npm:0.4.3"
|
||||||
|
dependencies:
|
||||||
|
"@solid-primitives/trigger": ^1.0.3
|
||||||
|
peerDependencies:
|
||||||
|
solid-js: ^1.6.12
|
||||||
|
checksum: e2408d7309c2bc0b93126771ad796cc3cbc2b150a03b4f3d4963dbc6df2ad26e671277fc14aafe1c117f1228c35557686e709accd6237ac511d2e05a6682006d
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@solid-primitives/set@npm:^0.4.3":
|
||||||
|
version: 0.4.3
|
||||||
|
resolution: "@solid-primitives/set@npm:0.4.3"
|
||||||
|
dependencies:
|
||||||
|
"@solid-primitives/trigger": ^1.0.3
|
||||||
|
peerDependencies:
|
||||||
|
solid-js: ^1.6.12
|
||||||
|
checksum: fcab5679185633b887d6d9ef4c12ded12d1773969a66079ce98dc18bbb2869f9fe743a1f3cd1f5721b52dcd274ae096470daa8ab1284643b4b26eeb28b7a5698
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@solid-primitives/trigger@npm:^1.0.3":
|
||||||
|
version: 1.0.5
|
||||||
|
resolution: "@solid-primitives/trigger@npm:1.0.5"
|
||||||
|
dependencies:
|
||||||
|
"@solid-primitives/utils": ^6.0.0
|
||||||
|
peerDependencies:
|
||||||
|
solid-js: ^1.6.12
|
||||||
|
checksum: 5f137ec425b317c09de6b994928992201206c16be7a01f7add46e0ee987d76a947a7f4f9396a945eeb671c43307b6f5d55bd57d90738880cebdaa0907aca65dd
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@solid-primitives/utils@npm:^6.0.0":
|
||||||
|
version: 6.0.0
|
||||||
|
resolution: "@solid-primitives/utils@npm:6.0.0"
|
||||||
|
peerDependencies:
|
||||||
|
solid-js: ^1.6.12
|
||||||
|
checksum: c581b995e2d16c9ed0546baef52a9e60f54dda457a3733bac467a19f2a63227179eb0ec6faa16397af4cacc13fa281288cf967a206b0a75255412fafadc55411
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@types/bson@npm:*":
|
"@types/bson@npm:*":
|
||||||
version: 4.0.5
|
version: 4.0.5
|
||||||
resolution: "@types/bson@npm:4.0.5"
|
resolution: "@types/bson@npm:4.0.5"
|
||||||
|
@ -191,15 +197,6 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
"axios@npm:^0.21.4":
|
|
||||||
version: 0.21.4
|
|
||||||
resolution: "axios@npm:0.21.4"
|
|
||||||
dependencies:
|
|
||||||
follow-redirects: ^1.14.0
|
|
||||||
checksum: 44245f24ac971e7458f3120c92f9d66d1fc695e8b97019139de5b0cc65d9b8104647db01e5f46917728edfc0cfd88eb30fc4c55e6053eef4ace76768ce95ff3c
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"axios@npm:^0.26.1":
|
"axios@npm:^0.26.1":
|
||||||
version: 0.26.1
|
version: 0.26.1
|
||||||
resolution: "axios@npm:0.26.1"
|
resolution: "axios@npm:0.26.1"
|
||||||
|
@ -231,7 +228,6 @@ __metadata:
|
||||||
resolution: "bridge@workspace:."
|
resolution: "bridge@workspace:."
|
||||||
dependencies:
|
dependencies:
|
||||||
"@discordjs/rest": ^0.4.1
|
"@discordjs/rest": ^0.4.1
|
||||||
"@janderedev/revolt.js": latest
|
|
||||||
automod: ^0.1.0
|
automod: ^0.1.0
|
||||||
axios: ^0.26.1
|
axios: ^0.26.1
|
||||||
discord-api-types: ^0.31.2
|
discord-api-types: ^0.31.2
|
||||||
|
@ -242,7 +238,8 @@ __metadata:
|
||||||
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.8
|
revolt-api: latest
|
||||||
|
revolt.js: ^7.0.0
|
||||||
smart-replace: ^1.0.2
|
smart-replace: ^1.0.2
|
||||||
typescript: ^4.7.4
|
typescript: ^4.7.4
|
||||||
ulid: ^2.3.0
|
ulid: ^2.3.0
|
||||||
|
@ -281,6 +278,13 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"csstype@npm:^3.1.0":
|
||||||
|
version: 3.1.2
|
||||||
|
resolution: "csstype@npm:3.1.2"
|
||||||
|
checksum: e1a52e6c25c1314d6beef5168da704ab29c5186b877c07d822bd0806717d9a265e8493a2e35ca7e68d0f5d472d43fac1cdce70fd79fd0853dff81f3028d857b5
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"debug@npm:*":
|
"debug@npm:*":
|
||||||
version: 4.3.4
|
version: 4.3.4
|
||||||
resolution: "debug@npm:4.3.4"
|
resolution: "debug@npm:4.3.4"
|
||||||
|
@ -359,10 +363,10 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"eventemitter3@npm:^4.0.7":
|
"eventemitter3@npm:^5.0.0":
|
||||||
version: 4.0.7
|
version: 5.0.0
|
||||||
resolution: "eventemitter3@npm:4.0.7"
|
resolution: "eventemitter3@npm:5.0.0"
|
||||||
checksum: 1875311c42fcfe9c707b2712c32664a245629b42bb0a5a84439762dd0fd637fc54d078155ea83c2af9e0323c9ac13687e03cfba79b03af9f40c89b4960099374
|
checksum: b974bafbab860e0a5bbb21add4c4e82f9d5691c583c03f2e4c5d44a2d6c4556d79223621bdcfc6c8e14366a4af9df6b5ea9d6caf65fbffc80b66f3e1dceacbc9
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
@ -373,7 +377,7 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"follow-redirects@npm:^1.14.0, follow-redirects@npm:^1.14.8":
|
"follow-redirects@npm:^1.14.8":
|
||||||
version: 1.15.2
|
version: 1.15.2
|
||||||
resolution: "follow-redirects@npm:1.15.2"
|
resolution: "follow-redirects@npm:1.15.2"
|
||||||
peerDependenciesMeta:
|
peerDependenciesMeta:
|
||||||
|
@ -433,6 +437,15 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"isomorphic-ws@npm:^5.0.0":
|
||||||
|
version: 5.0.0
|
||||||
|
resolution: "isomorphic-ws@npm:5.0.0"
|
||||||
|
peerDependencies:
|
||||||
|
ws: "*"
|
||||||
|
checksum: e20eb2aee09ba96247465fda40c6d22c1153394c0144fa34fe6609f341af4c8c564f60ea3ba762335a7a9c306809349f9b863c8beedf2beea09b299834ad5398
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"js-yaml@npm:^4.1.0":
|
"js-yaml@npm:^4.1.0":
|
||||||
version: 4.1.0
|
version: 4.1.0
|
||||||
resolution: "js-yaml@npm:4.1.0"
|
resolution: "js-yaml@npm:4.1.0"
|
||||||
|
@ -460,20 +473,6 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"lodash.flatten@npm:^4.4.0":
|
|
||||||
version: 4.4.0
|
|
||||||
resolution: "lodash.flatten@npm:4.4.0"
|
|
||||||
checksum: 0ac34a393d4b795d4b7421153d27c13ae67e08786c9cbb60ff5b732210d46f833598eee3fb3844bb10070e8488efe390ea53bb567377e0cb47e9e630bf0811cb
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"lodash.isequal@npm:^4.5.0":
|
|
||||||
version: 4.5.0
|
|
||||||
resolution: "lodash.isequal@npm:4.5.0"
|
|
||||||
checksum: da27515dc5230eb1140ba65ff8de3613649620e8656b19a6270afe4866b7bd461d9ba2ac8a48dcc57f7adac4ee80e1de9f965d89d4d81a0ad52bb3eec2609644
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"lodash@npm:^4.17.21":
|
"lodash@npm:^4.17.21":
|
||||||
version: 4.17.21
|
version: 4.17.21
|
||||||
resolution: "lodash@npm:4.17.21"
|
resolution: "lodash@npm:4.17.21"
|
||||||
|
@ -490,7 +489,7 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"long@npm:^5.2.0":
|
"long@npm:^5.2.1":
|
||||||
version: 5.2.1
|
version: 5.2.1
|
||||||
resolution: "long@npm:5.2.1"
|
resolution: "long@npm:5.2.1"
|
||||||
checksum: 9264da12d1b7df67e5aa6da4498144293caf1ad12e7f092efe4e9a2d32c53f0bbf7334f7cef997080a2a3af061142558ab366efa71698d98b1cdb883477445a7
|
checksum: 9264da12d1b7df67e5aa6da4498144293caf1ad12e7f092efe4e9a2d32c53f0bbf7334f7cef997080a2a3af061142558ab366efa71698d98b1cdb883477445a7
|
||||||
|
@ -529,13 +528,6 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"mobx@npm:^6.3.2":
|
|
||||||
version: 6.8.0
|
|
||||||
resolution: "mobx@npm:6.8.0"
|
|
||||||
checksum: f09bb079292ea59023a7e35a9c73ed577e3de9a0175ec3d5a2adc8192e2e3a352b29ec0981ee06d1d63f701f81bb7fc6cc19fd9089edf84a754a8a75ef00ef7f
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"mongodb@npm:^3.2.3":
|
"mongodb@npm:^3.2.3":
|
||||||
version: 3.7.3
|
version: 3.7.3
|
||||||
resolution: "mongodb@npm:3.7.3"
|
resolution: "mongodb@npm:3.7.3"
|
||||||
|
@ -726,17 +718,33 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"revolt-api@npm:0.5.16, revolt-api@npm:^0.5.3-rc.8":
|
"revolt-api@npm:^0.5.17, revolt-api@npm:latest":
|
||||||
version: 0.5.16
|
version: 0.5.17
|
||||||
resolution: "revolt-api@npm:0.5.16"
|
resolution: "revolt-api@npm:0.5.17"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@insertish/oapi": 0.1.18
|
"@insertish/oapi": 0.1.18
|
||||||
axios: ^0.26.1
|
axios: ^0.26.1
|
||||||
lodash.defaultsdeep: ^4.6.1
|
lodash.defaultsdeep: ^4.6.1
|
||||||
checksum: ce39f61e371c1b7da0704191317bccf88b6630f1d8ffcef6bc9c699ebdc8cfbb3fcc5e054f96f9751c2f4a048398d4b349670cd067bcaad2e099d0c30efd9cfe
|
checksum: aa722f4739c09bea46f738a1b9aef61af126e06aa924a61fcf33caa53561c5de4e7e2ddde26b496cdd0546e113cf324821fead0035973e2ebdb2633df482091b
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"revolt.js@portal:../revolt.js::locator=bridge%40workspace%3A.":
|
||||||
|
version: 0.0.0-use.local
|
||||||
|
resolution: "revolt.js@portal:../revolt.js::locator=bridge%40workspace%3A."
|
||||||
|
dependencies:
|
||||||
|
"@solid-primitives/map": ^0.4.3
|
||||||
|
"@solid-primitives/set": ^0.4.3
|
||||||
|
eventemitter3: ^5.0.0
|
||||||
|
isomorphic-ws: ^5.0.0
|
||||||
|
long: ^5.2.1
|
||||||
|
revolt-api: ^0.5.17
|
||||||
|
solid-js: ^1.7.2
|
||||||
|
ulid: ^2.3.0
|
||||||
|
ws: ^8.13.0
|
||||||
|
languageName: node
|
||||||
|
linkType: soft
|
||||||
|
|
||||||
"safe-buffer@npm:^5.1.1, safe-buffer@npm:^5.1.2":
|
"safe-buffer@npm:^5.1.1, safe-buffer@npm:^5.1.2":
|
||||||
version: 5.2.1
|
version: 5.2.1
|
||||||
resolution: "safe-buffer@npm:5.2.1"
|
resolution: "safe-buffer@npm:5.2.1"
|
||||||
|
@ -760,6 +768,13 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"seroval@npm:^0.5.0":
|
||||||
|
version: 0.5.1
|
||||||
|
resolution: "seroval@npm:0.5.1"
|
||||||
|
checksum: a4c1e42d6a65ed12de3c1f1b6a5b6b996e575c5bc838e1998e92daed7bc05421f3f6c82096387082dba33c475d64a31d0d932ac9b693352549259216e38dc091
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"smart-replace@npm:^1.0.2":
|
"smart-replace@npm:^1.0.2":
|
||||||
version: 1.0.2
|
version: 1.0.2
|
||||||
resolution: "smart-replace@npm:1.0.2"
|
resolution: "smart-replace@npm:1.0.2"
|
||||||
|
@ -767,6 +782,16 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"solid-js@npm:^1.7.2":
|
||||||
|
version: 1.7.3
|
||||||
|
resolution: "solid-js@npm:1.7.3"
|
||||||
|
dependencies:
|
||||||
|
csstype: ^3.1.0
|
||||||
|
seroval: ^0.5.0
|
||||||
|
checksum: 052a3148b6d0960312793781435005c16a7a80c2271e2bf2370ec22ec57ffd77e3e4a41335c1bd785ab36500adef86da79536445983efbed404db860e11593d4
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"sparse-bitfield@npm:^3.0.3":
|
"sparse-bitfield@npm:^3.0.3":
|
||||||
version: 3.0.3
|
version: 3.0.3
|
||||||
resolution: "sparse-bitfield@npm:3.0.3"
|
resolution: "sparse-bitfield@npm:3.0.3"
|
||||||
|
@ -894,7 +919,7 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"ws@npm:^8.2.2, ws@npm:^8.9.0":
|
"ws@npm:^8.13.0, ws@npm:^8.9.0":
|
||||||
version: 8.13.0
|
version: 8.13.0
|
||||||
resolution: "ws@npm:8.13.0"
|
resolution: "ws@npm:8.13.0"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
|
1
revolt.js
Submodule
1
revolt.js
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit d452295c85c0d700ea536ebed2061c5daf960612
|
Loading…
Reference in a new issue