feat(bot-discord): mute and unmute command

This commit is contained in:
GramingFoxTeam
2023-08-07 13:15:19 +03:00
parent d11ee5f01f
commit e5cf9f214e
13 changed files with 605 additions and 6 deletions

View File

@@ -0,0 +1,63 @@
import { SlashCommandBuilder } from 'discord.js';
import { checkForPerms } from '../utils/checkModPerms.js';
import reportToLogs from '../utils/reportToLogs.js';
import muteMember from '../utils/muteMember.js';
export default {
data: new SlashCommandBuilder()
.setName('mute')
.setDescription('Mute a member.')
.setDMPermission(false)
.addStringOption(option =>
option
.setName('user')
.setDescription('The member to mute')
.setRequired(true)
)
.addIntegerOption(option =>
option
.setName('duration')
.setDescription('The duration of mute')
.setRequired(true)
)
.addStringOption(option =>
option
.setName('reason')
.setDescription('The reason of the mute')
.setRequired(true)
),
async execute(_, config, interaction) {
if (!checkForPerms(config, interaction.member)) return interaction.reply({
epheremal: true,
content: 'You don\'t have the required permissions.'
});
await interaction.deferReply();
let member;
try {
member = await interaction.guild.members.fetch(interaction.getString('user'));
} catch (_) {
await interaction.editReply({
content: 'Could not find member.'
});
return;
}
const reason = interaction.getString('reason');
const parsedDuration = await muteMember(config, member, {
duration: interaction.getString('duration'),
reason,
supportMute: false
});
reportToLogs(config, interaction.client, 'muted', null, {
reason,
actionTo: await client.users.fetch(interaction.getString('user')),
actionBy: interaction.member,
channel: interaction.channel,
expire: parsedDuration
});
}
};

View File

@@ -0,0 +1,54 @@
import { SlashCommandBuilder } from 'discord.js';
import { checkForPerms } from '../utils/checkModPerms.js';
import reportToLogs from '../utils/reportToLogs.js';
import unmuteMember from '../utils/unmuteMember.js';
export default {
data: new SlashCommandBuilder()
.setName('unmute')
.setDescription('Unmute a member.')
.setDMPermission(false)
.addStringOption(option =>
option
.setName('user')
.setDescription('The member to unmute')
.setRequired(true)
),
async execute(_, config, interaction) {
if (!checkForPerms(config, interaction.member)) return interaction.reply({
epheremal: true,
content: 'You don\'t have the required permissions.'
});
await interaction.deferReply();
let member;
try {
member = await interaction.guild.members.fetch(interaction.getString('user'));
} catch (_) {
await interaction.editReply({
content: 'Could not find member.'
});
return;
}
const reason = interaction.getString('reason');
const isMuted = await unmuteMember(config, member);
if (!isMuted) {
await interaction.editReply({
content: 'Member was not muted.'
});
return;
}
reportToLogs(config, interaction.client, 'unmuted', null, {
reason,
actionTo: await client.users.fetch(interaction.getString('user')),
actionBy: interaction.member,
channel: interaction.channel,
});
}
};

View File

@@ -14,7 +14,23 @@
"953965039105232906",
"953964264400515092",
"952987428786941952"
]
],
"mute": {
"takeRoles": [
"996121272897519687",
"965267139902705744",
"995126555867086938"
],
"giveRoles": [
"953984696491061289"
],
"supportTakeRoles" : [
],
"supportGiveRoles" : [
]
}
},
"logs": {
"channelId": "952987428786941952",

View File

@@ -14,7 +14,23 @@
"953965039105232906",
"953964264400515092",
"952987428786941952"
]
],
"mute": {
"takeRoles": [
"996121272897519687",
"965267139902705744",
"995126555867086938"
],
"giveRoles": [
"953984696491061289"
],
"supportTakeRoles" : [
],
"supportGiveRoles" : [
]
}
},
"logs": {
"channelId": "952987428786941952",

View File

@@ -0,0 +1,20 @@
import { Events } from 'discord.js';
export default {
name: Events.GuildMemberAdd,
once: false,
async execute(_, config, member) {
const mute = await client.db.collection('mute').findOne({
guild_id: member.guild.id,
user_id: member.id
});
if (mute) {
// Add the roles given.
member.roles.add(mute.support_mute ?
config.mute.supportGiveRoles :
config.mute.giveRoles
);
}
}
};

View File

@@ -0,0 +1,18 @@
import { Events } from 'discord.js';
import setMuteTimeout from '../utils/setMuteTimeout.js';
export default {
name: Events.ClientReady,
once: false,
async execute(_, config, client) {
console.log('Client is ready. Reloading mutes.');
const mutes = await client.db.collection('mute').find().toArray();
for (const mute of mutes) {
await setMuteTimeout(mute, client.mutes);
}
console.log(`Loaded ${mutes.length} mutes.`);
}
};

View File

@@ -7,10 +7,14 @@ const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
import HelperClient from '@revanced-helper/helper-client';
import config from './config.json' assert { type: 'json' };
import { MongoClient } from 'mongodb';
const helper = new HelperClient(config);
const mongoDBClient = new MongoClient(process.env.MONGODB_URI);
await mongoDBClient.connect();
helper.connect();
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
@@ -23,6 +27,8 @@ client.commands = new Collection();
client.trainingVotes = new Collection();
client.stickiedMessage = null;
client.stickiedMessageTimeout = null;
client.db = mongoDBClient.db('revanced_discord_bot');
client.mutes = new Collection();
const commandsPath = join(__dirname, 'commands');
const commandFiles = readdirSync(commandsPath).filter((file) =>

View File

@@ -10,10 +10,13 @@
"license": "GPL-3.0-or-later",
"dependencies": {
"@revanced-helper/helper-client": "file:../../../packages/client",
"discord.js": "^14.11.0"
"discord.js": "^14.11.0",
"mongodb": "^5.7.0",
"parse-duration": "^1.1.0"
}
},
"../../../packages/client": {
"name": "@revanced-helper/helper-client",
"version": "1.0.0",
"license": "GPL-3.0-or-later",
"dependencies": {
@@ -146,6 +149,20 @@
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.5.tgz",
"integrity": "sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ=="
},
"node_modules/@types/webidl-conversions": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
"integrity": "sha512-xTE1E+YF4aWPJJeUzaZI5DRntlkY3+BCVJi0axFptnjGmAoWxkyREIh/XMrfxVLejwQxMCfDXdICo0VLxThrog=="
},
"node_modules/@types/whatwg-url": {
"version": "8.2.2",
"resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.2.tgz",
"integrity": "sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==",
"dependencies": {
"@types/node": "*",
"@types/webidl-conversions": "*"
}
},
"node_modules/@types/ws": {
"version": "8.5.4",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.4.tgz",
@@ -163,6 +180,14 @@
"npm": ">=7.0.0"
}
},
"node_modules/bson": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/bson/-/bson-5.4.0.tgz",
"integrity": "sha512-WRZ5SQI5GfUuKnPTNmAYPiKIof3ORXAF4IRU5UcgmivNIon01rWQlw5RUH954dpu8yGL8T59YShVddIPaU/gFA==",
"engines": {
"node": ">=14.20.1"
}
},
"node_modules/busboy": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
@@ -248,6 +273,11 @@
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"node_modules/ip": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz",
"integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ=="
},
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
@@ -258,6 +288,66 @@
"resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz",
"integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw=="
},
"node_modules/memory-pager": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
"integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
"optional": true
},
"node_modules/mongodb": {
"version": "5.7.0",
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.7.0.tgz",
"integrity": "sha512-zm82Bq33QbqtxDf58fLWBwTjARK3NSvKYjyz997KSy6hpat0prjeX/kxjbPVyZY60XYPDNETaHkHJI2UCzSLuw==",
"dependencies": {
"bson": "^5.4.0",
"mongodb-connection-string-url": "^2.6.0",
"socks": "^2.7.1"
},
"engines": {
"node": ">=14.20.1"
},
"optionalDependencies": {
"saslprep": "^1.0.3"
},
"peerDependencies": {
"@aws-sdk/credential-providers": "^3.201.0",
"@mongodb-js/zstd": "^1.1.0",
"kerberos": "^2.0.1",
"mongodb-client-encryption": ">=2.3.0 <3",
"snappy": "^7.2.2"
},
"peerDependenciesMeta": {
"@aws-sdk/credential-providers": {
"optional": true
},
"@mongodb-js/zstd": {
"optional": true
},
"kerberos": {
"optional": true
},
"mongodb-client-encryption": {
"optional": true
},
"snappy": {
"optional": true
}
}
},
"node_modules/mongodb-connection-string-url": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz",
"integrity": "sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==",
"dependencies": {
"@types/whatwg-url": "^8.2.1",
"whatwg-url": "^11.0.0"
}
},
"node_modules/parse-duration": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/parse-duration/-/parse-duration-1.1.0.tgz",
"integrity": "sha512-z6t9dvSJYaPoQq7quMzdEagSFtpGu+utzHqqxmpVWNNZRIXnvqyCvn9XsTdh7c/w0Bqmdz3RB3YnRaKtpRtEXQ=="
},
"node_modules/peek-readable": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-5.0.0.tgz",
@@ -270,6 +360,14 @@
"url": "https://github.com/sponsors/Borewit"
}
},
"node_modules/punycode": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
"integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
"engines": {
"node": ">=6"
}
},
"node_modules/readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
@@ -317,6 +415,49 @@
}
]
},
"node_modules/saslprep": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz",
"integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==",
"optional": true,
"dependencies": {
"sparse-bitfield": "^3.0.3"
},
"engines": {
"node": ">=6"
}
},
"node_modules/smart-buffer": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
"integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
"engines": {
"node": ">= 6.0.0",
"npm": ">= 3.0.0"
}
},
"node_modules/socks": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz",
"integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==",
"dependencies": {
"ip": "^2.0.0",
"smart-buffer": "^4.2.0"
},
"engines": {
"node": ">= 10.13.0",
"npm": ">= 3.0.0"
}
},
"node_modules/sparse-bitfield": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
"integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==",
"optional": true,
"dependencies": {
"memory-pager": "^1.0.2"
}
},
"node_modules/streamsearch": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz",
@@ -365,6 +506,17 @@
"url": "https://github.com/sponsors/Borewit"
}
},
"node_modules/tr46": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz",
"integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==",
"dependencies": {
"punycode": "^2.1.1"
},
"engines": {
"node": ">=12"
}
},
"node_modules/ts-mixer": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.3.tgz",
@@ -391,6 +543,26 @@
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
},
"node_modules/webidl-conversions": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
"integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
"engines": {
"node": ">=12"
}
},
"node_modules/whatwg-url": {
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz",
"integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==",
"dependencies": {
"tr46": "^3.0.0",
"webidl-conversions": "^7.0.0"
},
"engines": {
"node": ">=12"
}
},
"node_modules/ws": {
"version": "8.13.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz",
@@ -511,6 +683,20 @@
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.5.tgz",
"integrity": "sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ=="
},
"@types/webidl-conversions": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
"integrity": "sha512-xTE1E+YF4aWPJJeUzaZI5DRntlkY3+BCVJi0axFptnjGmAoWxkyREIh/XMrfxVLejwQxMCfDXdICo0VLxThrog=="
},
"@types/whatwg-url": {
"version": "8.2.2",
"resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.2.tgz",
"integrity": "sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==",
"requires": {
"@types/node": "*",
"@types/webidl-conversions": "*"
}
},
"@types/ws": {
"version": "8.5.4",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.4.tgz",
@@ -524,6 +710,11 @@
"resolved": "https://registry.npmjs.org/@vladfrangu/async_event_emitter/-/async_event_emitter-2.2.2.tgz",
"integrity": "sha512-HIzRG7sy88UZjBJamssEczH5q7t5+axva19UbZLO6u0ySbYPrwzWiXBcC0WuHyhKKoeCyneH+FvYzKQq/zTtkQ=="
},
"bson": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/bson/-/bson-5.4.0.tgz",
"integrity": "sha512-WRZ5SQI5GfUuKnPTNmAYPiKIof3ORXAF4IRU5UcgmivNIon01rWQlw5RUH954dpu8yGL8T59YShVddIPaU/gFA=="
},
"busboy": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
@@ -583,6 +774,11 @@
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"ip": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz",
"integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ=="
},
"lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
@@ -593,11 +789,47 @@
"resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz",
"integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw=="
},
"memory-pager": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
"integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
"optional": true
},
"mongodb": {
"version": "5.7.0",
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.7.0.tgz",
"integrity": "sha512-zm82Bq33QbqtxDf58fLWBwTjARK3NSvKYjyz997KSy6hpat0prjeX/kxjbPVyZY60XYPDNETaHkHJI2UCzSLuw==",
"requires": {
"bson": "^5.4.0",
"mongodb-connection-string-url": "^2.6.0",
"saslprep": "^1.0.3",
"socks": "^2.7.1"
}
},
"mongodb-connection-string-url": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz",
"integrity": "sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==",
"requires": {
"@types/whatwg-url": "^8.2.1",
"whatwg-url": "^11.0.0"
}
},
"parse-duration": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/parse-duration/-/parse-duration-1.1.0.tgz",
"integrity": "sha512-z6t9dvSJYaPoQq7quMzdEagSFtpGu+utzHqqxmpVWNNZRIXnvqyCvn9XsTdh7c/w0Bqmdz3RB3YnRaKtpRtEXQ=="
},
"peek-readable": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-5.0.0.tgz",
"integrity": "sha512-YtCKvLUOvwtMGmrniQPdO7MwPjgkFBtFIrmfSbYmYuq3tKDV/mcfAhBth1+C3ru7uXIZasc/pHnb+YDYNkkj4A=="
},
"punycode": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
"integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA=="
},
"readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
@@ -621,6 +853,38 @@
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
},
"saslprep": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz",
"integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==",
"optional": true,
"requires": {
"sparse-bitfield": "^3.0.3"
}
},
"smart-buffer": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
"integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg=="
},
"socks": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz",
"integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==",
"requires": {
"ip": "^2.0.0",
"smart-buffer": "^4.2.0"
}
},
"sparse-bitfield": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
"integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==",
"optional": true,
"requires": {
"memory-pager": "^1.0.2"
}
},
"streamsearch": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz",
@@ -652,6 +916,14 @@
"ieee754": "^1.2.1"
}
},
"tr46": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz",
"integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==",
"requires": {
"punycode": "^2.1.1"
}
},
"ts-mixer": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.3.tgz",
@@ -675,6 +947,20 @@
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
},
"webidl-conversions": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
"integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="
},
"whatwg-url": {
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz",
"integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==",
"requires": {
"tr46": "^3.0.0",
"webidl-conversions": "^7.0.0"
}
},
"ws": {
"version": "8.13.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz",

View File

@@ -9,6 +9,8 @@
"license": "GPL-3.0-or-later",
"dependencies": {
"@revanced-helper/helper-client": "file:../../../packages/client",
"discord.js": "^14.11.0"
"discord.js": "^14.11.0",
"mongodb": "^5.7.0",
"parse-duration": "^1.1.0"
}
}

View File

@@ -0,0 +1,74 @@
import parse from 'parse-duration'
import setMuteTimeout from './setMuteTimeout.js';
parse['mo'] = parse['month']
export default async function muteMember(config, member, { duration, reason, supportMute }) {
const parsedDuration = parse(duration);
const expires = Date.now() + parsedDuration;
const takenRoles = [];
for (const takeRole of supportMute ?
config.discord.mute.supportTakeRoles :
config.discord.mute.takeRoles
) {
if (member.roles.cache.get(takeRole)) {
takenRoles.push(takeRoles);
}
}
const existingMute = await member.client.db.collection('mute').findOne({
guild_id: member.guild.id,
user_id: member.id
});
if (existingMute) {
// Update existing mute
await member.client.db.collection('mute').updateOne({
guild_id: member.guild.id,
user_id: member.id
}, {
$set: {
reason,
expires,
support_mute: supportMute
}
});
if (client.mutes.has(member.id)) {
clearTimeout(client.mutes.get(member.id))
client.mutes.delete(member.id);
}
} else {
await member.client.db.collection('mute').insert({
guild_id: member.guild.id,
user_id: member.id,
taken_roles: takenRoles,
expires,
reason,
support_mute: supportMute
});
}
// Remove the roles, give defined roles.
if (!existingMute) {
member.roles.remove(takenRoles);
member.roles.add(supportMute ?
config.discord.mute.giveRoles :
config.discord.mute.supportGiveRoles
);
}
// Start a timeout.
setMuteTimeout({
guild_id: member.guild.id,
user_id: member.id,
taken_roles: takenRoles,
expires,
support_mute: supportMute
}, member.client.mutes);
// Return parsed time for the mute command to resolve.
return expires;
}

View File

@@ -3,9 +3,12 @@ import { EmbedBuilder, messageLink } from 'discord.js';
export default async function reportToLogs(config, client, action, message, { reason, expire, actionTo, actionBy }, msgChannel) {
const channel = await client.channels.fetch(config.logs.channelId);
const thread = await channel.threads.fetch(config.logs.threadId);
const actionUpper = action.charAt(0).toUpperCase() + action.slice(1);
const actionTitle = `${actionUpper} ${actionTo.tag}`;
const actionEmbed = new EmbedBuilder()
.setThumbnail(actionTo.user.avatarURL());
.setThumbnail(actionTo.user.avatarURL())
.setTitle(actionTitle);
const fields = [
{ name: 'Action', value: `${actionTo.toString()} was ${action} by ${actionBy.toString()}` }

View File

@@ -0,0 +1,19 @@
export default async function setMuteTimeout(mute, mutes) {
const duration = Date.now() - mute.expires;
mutes.set(mute.user_id, setTimeout(async() => {
const guild = await client.guilds.fetch(mute.guild_id);
let member;
try {
member = await guild.members.fetch(mute.user_id);
} catch (_) {
return;
}
member.roles.add(mute.taken_roles);
member.roles.remove(
mute.support_mute ?
config.discord.mute.supportGiveRoles :
config.discord.mute.giveRoles
);
}, duration));
}

View File

@@ -0,0 +1,22 @@
export default async function unmuteMember(config, member) {
const mute = await member.client.db.collection('mute').findOne({
guild_id: member.guild.id,
user_id: member.id
});
if (!mute) return false;
member.roles.remove(mute.support_mute ?
config.mute.supportGiveRoles :
config.mute.giveRoles
);
member.roles.add(mute.taken_roles);
await member.client.db.collection('mute').remove({
guild_id: member.guild.id,
user_id: member.id
});
return true;
}