(rewrite): Bot & Events. This most definitely doesn't work yet. I'm just running out of time to work on this atm.
This commit is contained in:
@@ -1 +1,2 @@
|
|||||||
|
registry=https://npm.hep.gg
|
||||||
@clynamic:registry=https://npm.clynamic.net
|
@clynamic:registry=https://npm.clynamic.net
|
||||||
|
|||||||
Generated
+88
-5
@@ -1,18 +1,19 @@
|
|||||||
{
|
{
|
||||||
"name": "discordbot-ng",
|
"name": "hexerade",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "discordbot-ng",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@clynamic/dmark": "0.0.11",
|
"@clynamic/dmark": "0.0.11",
|
||||||
"@redis/client": "5.1.0",
|
"@redis/client": "5.1.0",
|
||||||
|
"athena-prime": "4.2.0",
|
||||||
"body-parser": "2.2.2",
|
"body-parser": "2.2.2",
|
||||||
"discord.js": "14.26.4",
|
"discord.js": "14.26.4",
|
||||||
"dotenv": "16.5.0",
|
"dotenv": "16.5.0",
|
||||||
"express": "5.1.0",
|
"express": "5.1.0",
|
||||||
"express-session": "1.19.0",
|
"express-session": "1.19.0",
|
||||||
|
"ioredis": "6.0.0",
|
||||||
"markdown-it": "14.2.0",
|
"markdown-it": "14.2.0",
|
||||||
"memorystore": "1.6.7",
|
"memorystore": "1.6.7",
|
||||||
"sqlite": "5.1.1",
|
"sqlite": "5.1.1",
|
||||||
@@ -824,6 +825,12 @@
|
|||||||
"url": "https://github.com/sponsors/nzakas"
|
"url": "https://github.com/sponsors/nzakas"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@ioredis/commands": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://npm.hep.gg/@ioredis/commands/-/commands-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-vrx0AE/T0h7cRZwfo1M39Cr+ZhZrkf0V8mQN75wucKCxCLD9l/VX6no3gFvrLqD1IlG/1LtzWovqEw3t0Vr9zg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@isaacs/cliui": {
|
"node_modules/@isaacs/cliui": {
|
||||||
"version": "8.0.2",
|
"version": "8.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
|
||||||
@@ -1394,6 +1401,22 @@
|
|||||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
||||||
},
|
},
|
||||||
|
"node_modules/athena-prime": {
|
||||||
|
"version": "4.2.0",
|
||||||
|
"resolved": "https://npm.hep.gg/athena-prime/-/athena-prime-4.2.0.tgz",
|
||||||
|
"integrity": "sha512-CbIPwdupVGfGRR/ZRcc9BAC/nBnRQS9sRalzWtONYQ4eNhCDJVykPLQM2N7abndvcpLctWd1cD3awpA9NDy30Q==",
|
||||||
|
"license": "NOLICENSE",
|
||||||
|
"dependencies": {
|
||||||
|
"discord-api-types": "^0.38.48",
|
||||||
|
"eventemitter3": "^5.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=22.15.0"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"ws": "^8.21.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/balanced-match": {
|
"node_modules/balanced-match": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||||
@@ -1821,6 +1844,15 @@
|
|||||||
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
|
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/denque": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://npm.hep.gg/denque/-/denque-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/depd": {
|
"node_modules/depd": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
|
||||||
@@ -1838,9 +1870,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/discord-api-types": {
|
"node_modules/discord-api-types": {
|
||||||
"version": "0.38.42",
|
"version": "0.38.53",
|
||||||
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.38.42.tgz",
|
"resolved": "https://npm.hep.gg/discord-api-types/-/discord-api-types-0.38.53.tgz",
|
||||||
"integrity": "sha512-qs1kya7S84r5RR8m9kgttywGrmmoHaRifU1askAoi+wkoSefLpZP6aGXusjNw5b0jD3zOg3LTwUa3Tf2iHIceQ==",
|
"integrity": "sha512-HL1zz/UuZ+bbJjA/X8Kbxx9gk8v9rJAbTeWRNYKmIdjwJ7EovjlHgoJTxcLpATfNJ+AonOtMdy3Y5MVIJAAd/A==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"scripts/actions/documentation"
|
"scripts/actions/documentation"
|
||||||
@@ -2203,6 +2235,12 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/eventemitter3": {
|
||||||
|
"version": "5.0.4",
|
||||||
|
"resolved": "https://npm.hep.gg/eventemitter3/-/eventemitter3-5.0.4.tgz",
|
||||||
|
"integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/expand-template": {
|
"node_modules/expand-template": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
|
||||||
@@ -2761,6 +2799,36 @@
|
|||||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
|
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
|
||||||
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
|
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
|
||||||
},
|
},
|
||||||
|
"node_modules/ioredis": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://npm.hep.gg/ioredis/-/ioredis-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-f+Dtubxfpf6KYFq7WVXJoOLn0bk4TJrMrN9SzeE+jrWrCWj7XX3fA6vkryafhADX+GMymRxgDJDOI33COkJc0w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@ioredis/commands": "2.0.0",
|
||||||
|
"cluster-key-slot": "1.1.1",
|
||||||
|
"debug": "4.4.3",
|
||||||
|
"denque": "2.1.0",
|
||||||
|
"redis-errors": "1.2.0",
|
||||||
|
"standard-as-callback": "2.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/ioredis"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ioredis/node_modules/cluster-key-slot": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://npm.hep.gg/cluster-key-slot/-/cluster-key-slot-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-rwHwUfXL40Chm1r08yrhU3qpUvdVlgkKNeyeGPOxnW8/SyVDvgRaed/Uz54AqWNaTCAThlj6QAs3TZcKI0xDEw==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ipaddr.js": {
|
"node_modules/ipaddr.js": {
|
||||||
"version": "1.9.1",
|
"version": "1.9.1",
|
||||||
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
|
||||||
@@ -3679,6 +3747,15 @@
|
|||||||
"node": ">= 6"
|
"node": ">= 6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/redis-errors": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://npm.hep.gg/redis-errors/-/redis-errors-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/require-directory": {
|
"node_modules/require-directory": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||||
@@ -4124,6 +4201,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/standard-as-callback": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://npm.hep.gg/standard-as-callback/-/standard-as-callback-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/statuses": {
|
"node_modules/statuses": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
|
||||||
|
|||||||
@@ -11,9 +11,12 @@
|
|||||||
"typescript": "5.8.3",
|
"typescript": "5.8.3",
|
||||||
"typescript-eslint": "8.32.1"
|
"typescript-eslint": "8.32.1"
|
||||||
},
|
},
|
||||||
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@clynamic/dmark": "0.0.11",
|
"@clynamic/dmark": "0.0.11",
|
||||||
"@redis/client": "5.1.0",
|
"@redis/client": "5.1.0",
|
||||||
|
"ioredis": "6.0.0",
|
||||||
|
"athena-prime": "4.2.0",
|
||||||
"body-parser": "2.2.2",
|
"body-parser": "2.2.2",
|
||||||
"discord.js": "14.26.4",
|
"discord.js": "14.26.4",
|
||||||
"dotenv": "16.5.0",
|
"dotenv": "16.5.0",
|
||||||
@@ -24,6 +27,7 @@
|
|||||||
"sqlite": "5.1.1",
|
"sqlite": "5.1.1",
|
||||||
"sqlite3": "6.0.1"
|
"sqlite3": "6.0.1"
|
||||||
},
|
},
|
||||||
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "tsx watch --enable-source-maps src/index.ts",
|
"dev": "tsx watch --enable-source-maps src/index.ts",
|
||||||
"start": "node dist/index.js",
|
"start": "node dist/index.js",
|
||||||
|
|||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
// External Imports
|
||||||
|
import { CommandClient, Constants, LRUCollection, Member, User } from "athena-prime";
|
||||||
|
|
||||||
|
// Internal Imports
|
||||||
|
import config from "./config";
|
||||||
|
|
||||||
|
// ---------------
|
||||||
|
|
||||||
|
const client = new CommandClient({
|
||||||
|
token: `Bot ${config.DISCORD_TOKEN}`,
|
||||||
|
|
||||||
|
options: {
|
||||||
|
intents: [
|
||||||
|
Constants.GatewayIntentBits.Guilds,
|
||||||
|
Constants.GatewayIntentBits.GuildMembers,
|
||||||
|
Constants.GatewayIntentBits.GuildMessages,
|
||||||
|
Constants.GatewayIntentBits.GuildModeration,
|
||||||
|
Constants.GatewayIntentBits.GuildVoiceStates,
|
||||||
|
Constants.GatewayIntentBits.MessageContent,
|
||||||
|
],
|
||||||
|
|
||||||
|
largeBotOptimizations: true,
|
||||||
|
|
||||||
|
// TODO: Move caching to Redis.
|
||||||
|
cache: {
|
||||||
|
users: () => new LRUCollection(User, 1024),
|
||||||
|
members: (guild) => new LRUCollection(Member, 1024),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default client;
|
||||||
@@ -39,7 +39,7 @@ export default {
|
|||||||
.addComponents(button);
|
.addComponents(button);
|
||||||
|
|
||||||
await interaction.channel.send({ components: [row], content });
|
await interaction.channel.send({ components: [row], content });
|
||||||
await Database.updateGuildSettings(interaction.guildId, 'private_help_channel_id', interaction.channelId);
|
await Database.updateSettings(interaction.guildId, 'private_help_channel_id', interaction.channelId);
|
||||||
interaction.reply({ flags: [MessageFlags.Ephemeral], content: 'Sent.' });
|
interaction.reply({ flags: [MessageFlags.Ephemeral], content: 'Sent.' });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
+14
-14
@@ -139,75 +139,75 @@ export default {
|
|||||||
|
|
||||||
const generalChannel = interaction.options.getChannel('general-channel');
|
const generalChannel = interaction.options.getChannel('general-channel');
|
||||||
if (generalChannel) {
|
if (generalChannel) {
|
||||||
await Database.updateGuildSettings(interaction.guildId, 'general_chat_id', generalChannel.id);
|
await Database.updateSettings(interaction.guildId, 'general_chat_id', generalChannel.id);
|
||||||
response.push(`**general_chat_id** has been set to: ${generalChannel}.`);
|
response.push(`**general_chat_id** has been set to: ${generalChannel}.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ticketsChannel = interaction.options.getChannel('tickets-channel');
|
const ticketsChannel = interaction.options.getChannel('tickets-channel');
|
||||||
if (ticketsChannel) {
|
if (ticketsChannel) {
|
||||||
await Database.updateGuildSettings(interaction.guildId, 'tickets_channel_id', ticketsChannel.id);
|
await Database.updateSettings(interaction.guildId, 'tickets_channel_id', ticketsChannel.id);
|
||||||
response.push(`**tickets_channel_id** has been set to: ${ticketsChannel}.`);
|
response.push(`**tickets_channel_id** has been set to: ${ticketsChannel}.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const appealsChannel = interaction.options.getChannel('appeals-channel');
|
const appealsChannel = interaction.options.getChannel('appeals-channel');
|
||||||
|
|
||||||
if (appealsChannel) {
|
if (appealsChannel) {
|
||||||
await Database.updateGuildSettings(interaction.guildId, 'appeals_channel_id', appealsChannel.id);
|
await Database.updateSettings(interaction.guildId, 'appeals_channel_id', appealsChannel.id);
|
||||||
|
|
||||||
response.push(`**appeals_channel_id** has been set to ${appealsChannel}.`);
|
response.push(`**appeals_channel_id** has been set to ${appealsChannel}.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const eventLogsChannel = interaction.options.getChannel('event-logs-channel');
|
const eventLogsChannel = interaction.options.getChannel('event-logs-channel');
|
||||||
if (eventLogsChannel) {
|
if (eventLogsChannel) {
|
||||||
await Database.updateGuildSettings(interaction.guildId, 'event_logs_channel_id', eventLogsChannel.id);
|
await Database.updateSettings(interaction.guildId, 'event_logs_channel_id', eventLogsChannel.id);
|
||||||
response.push(`**event_logs_channel_id** has been set to: ${eventLogsChannel}.`);
|
response.push(`**event_logs_channel_id** has been set to: ${eventLogsChannel}.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const discordLogsChannel = interaction.options.getChannel('discord-logs-channel');
|
const discordLogsChannel = interaction.options.getChannel('discord-logs-channel');
|
||||||
if (discordLogsChannel) {
|
if (discordLogsChannel) {
|
||||||
await Database.updateGuildSettings(interaction.guildId, 'discord_logs_channel_id', discordLogsChannel.id);
|
await Database.updateSettings(interaction.guildId, 'discord_logs_channel_id', discordLogsChannel.id);
|
||||||
response.push(`**discord_logs_channel_id** has been set to: ${discordLogsChannel}.`);
|
response.push(`**discord_logs_channel_id** has been set to: ${discordLogsChannel}.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auditLogsChannel = interaction.options.getChannel('audit-logs-channel');
|
const auditLogsChannel = interaction.options.getChannel('audit-logs-channel');
|
||||||
if (auditLogsChannel) {
|
if (auditLogsChannel) {
|
||||||
await Database.updateGuildSettings(interaction.guildId, 'audit_logs_channel_id', auditLogsChannel.id);
|
await Database.updateSettings(interaction.guildId, 'audit_logs_channel_id', auditLogsChannel.id);
|
||||||
response.push(`**audit_logs_channel_id** has been set to: ${auditLogsChannel}.`);
|
response.push(`**audit_logs_channel_id** has been set to: ${auditLogsChannel}.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const voiceLogsChannel = interaction.options.getChannel('voice-logs-channel');
|
const voiceLogsChannel = interaction.options.getChannel('voice-logs-channel');
|
||||||
if (voiceLogsChannel) {
|
if (voiceLogsChannel) {
|
||||||
await Database.updateGuildSettings(interaction.guildId, 'voice_logs_channel_id', voiceLogsChannel.id);
|
await Database.updateSettings(interaction.guildId, 'voice_logs_channel_id', voiceLogsChannel.id);
|
||||||
response.push(`**voice_logs_channel_id** has been set to: ${voiceLogsChannel}.`);
|
response.push(`**voice_logs_channel_id** has been set to: ${voiceLogsChannel}.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const newMemberLogsChannel = interaction.options.getChannel('new-member-channel');
|
const newMemberLogsChannel = interaction.options.getChannel('new-member-channel');
|
||||||
if (newMemberLogsChannel) {
|
if (newMemberLogsChannel) {
|
||||||
await Database.updateGuildSettings(interaction.guildId, 'new_member_channel_id', newMemberLogsChannel.id);
|
await Database.updateSettings(interaction.guildId, 'new_member_channel_id', newMemberLogsChannel.id);
|
||||||
response.push(`**new_member_channel_id** has been set to: ${newMemberLogsChannel}.`);
|
response.push(`**new_member_channel_id** has been set to: ${newMemberLogsChannel}.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const moderatorChannel = interaction.options.getChannel('moderator-channel');
|
const moderatorChannel = interaction.options.getChannel('moderator-channel');
|
||||||
if (moderatorChannel) {
|
if (moderatorChannel) {
|
||||||
await Database.updateGuildSettings(interaction.guildId, 'moderator_channel_id', moderatorChannel.id);
|
await Database.updateSettings(interaction.guildId, 'moderator_channel_id', moderatorChannel.id);
|
||||||
response.push(`**moderator_channel_id** has been set to": ${moderatorChannel}.`);
|
response.push(`**moderator_channel_id** has been set to": ${moderatorChannel}.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const adminRole = interaction.options.getRole('admin-role');
|
const adminRole = interaction.options.getRole('admin-role');
|
||||||
if (adminRole) {
|
if (adminRole) {
|
||||||
await Database.updateGuildSettings(interaction.guildId, 'admin_role_id', adminRole.id);
|
await Database.updateSettings(interaction.guildId, 'admin_role_id', adminRole.id);
|
||||||
response.push(`**admin_role_id** has been set to: ${adminRole}.`);
|
response.push(`**admin_role_id** has been set to: ${adminRole}.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const privateHelperRole = interaction.options.getRole('private-helper-role');
|
const privateHelperRole = interaction.options.getRole('private-helper-role');
|
||||||
if (privateHelperRole) {
|
if (privateHelperRole) {
|
||||||
await Database.updateGuildSettings(interaction.guildId, 'private_help_role_id', privateHelperRole.id);
|
await Database.updateSettings(interaction.guildId, 'private_help_role_id', privateHelperRole.id);
|
||||||
response.push(`**private_help_role_id** has been set to: ${privateHelperRole}.`);
|
response.push(`**private_help_role_id** has been set to: ${privateHelperRole}.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const devWatchRole = interaction.options.getRole('devwatch-role');
|
const devWatchRole = interaction.options.getRole('devwatch-role');
|
||||||
if (devWatchRole) {
|
if (devWatchRole) {
|
||||||
await Database.updateGuildSettings(interaction.guildId, 'devwatch_role_id', devWatchRole.id);
|
await Database.updateSettings(interaction.guildId, 'devwatch_role_id', devWatchRole.id);
|
||||||
response.push(`**devwatch_role_id** has been set to ${devWatchRole}.`);
|
response.push(`**devwatch_role_id** has been set to ${devWatchRole}.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,13 +264,13 @@ export default {
|
|||||||
|
|
||||||
const githubReleaseChannel = interaction.options.getChannel('github-release-channel');
|
const githubReleaseChannel = interaction.options.getChannel('github-release-channel');
|
||||||
if (githubReleaseChannel) {
|
if (githubReleaseChannel) {
|
||||||
await Database.updateGuildSettings(interaction.guildId, 'github_release_channel', githubReleaseChannel.id);
|
await Database.updateSettings(interaction.guildId, 'github_release_channel', githubReleaseChannel.id);
|
||||||
response.push(`**github_release_channel** has been set to ${githubReleaseChannel}.`);
|
response.push(`**github_release_channel** has been set to ${githubReleaseChannel}.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const siteBreakerRole = interaction.options.getRole('site-breaker-role');
|
const siteBreakerRole = interaction.options.getRole('site-breaker-role');
|
||||||
if (siteBreakerRole) {
|
if (siteBreakerRole) {
|
||||||
await Database.updateGuildSettings(interaction.guildId, 'site_breaker_role_id', siteBreakerRole.id);
|
await Database.updateSettings(interaction.guildId, 'site_breaker_role_id', siteBreakerRole.id);
|
||||||
response.push(`**site_breaker_role_id** has been set to ${siteBreakerRole}.`);
|
response.push(`**site_breaker_role_id** has been set to ${siteBreakerRole}.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-9
@@ -1,10 +1,11 @@
|
|||||||
import dotenv from 'dotenv';
|
// External Imports
|
||||||
|
import 'dotenv/config';
|
||||||
|
|
||||||
dotenv.config();
|
// ---------------
|
||||||
|
|
||||||
const { DISCORD_TOKEN, DISCORD_CLIENT_ID, DISCORD_CLIENT_SECRET, DISCORD_GUILD_ID, RELEASE_SECRET, DATABASE_SECRET, LINK_SECRET, E621_BASE_URL, E926_BASE_URL, PRIVACY_POLICY_URL, GIT_REPO_BASE_URL, REDIS_URL, PORT, DEBUG } = process.env;
|
const { DISCORD_TOKEN, DISCORD_CLIENT_ID, DISCORD_CLIENT_SECRET, DISCORD_GUILD_ID, RELEASE_SECRET, DATABASE_SECRET, LINK_SECRET, E621_BASE_URL, E926_BASE_URL, PRIVACY_POLICY_URL, GIT_REPO_BASE_URL, REDIS_URL, PORT, DEBUG } = process.env;
|
||||||
|
|
||||||
export const config = {
|
export default {
|
||||||
DISCORD_TOKEN,
|
DISCORD_TOKEN,
|
||||||
DISCORD_CLIENT_ID,
|
DISCORD_CLIENT_ID,
|
||||||
DISCORD_CLIENT_SECRET,
|
DISCORD_CLIENT_SECRET,
|
||||||
@@ -21,9 +22,3 @@ export const config = {
|
|||||||
DEV_MODE: process.env.npm_lifecycle_event == 'dev',
|
DEV_MODE: process.env.npm_lifecycle_event == 'dev',
|
||||||
DEBUG: DEBUG == 'true'
|
DEBUG: DEBUG == 'true'
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const [key, val] of Object.entries(config)) {
|
|
||||||
if (val === undefined) {
|
|
||||||
throw new Error(`${key} is undefined in config`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
// External Imports
|
||||||
|
import { CommandClient, Event, Guild, User } from 'athena-prime';
|
||||||
|
|
||||||
|
// Internal Imports
|
||||||
|
import { Database } from '../shared/Database';
|
||||||
|
|
||||||
|
// ---------------
|
||||||
|
|
||||||
|
class GuildBanRemoveEvent extends Event<CommandClient> {
|
||||||
|
event: string = 'guildBanRemove' as const;
|
||||||
|
|
||||||
|
async handle(context: CommandClient<any, any>, guild: Guild, user: User) {
|
||||||
|
await Database.deleteBan(user.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new GuildBanRemoveEvent('guildBanRemove');
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// External Imports
|
||||||
|
import { CommandClient, Event, Guild } from 'athena-prime';
|
||||||
|
|
||||||
|
// Internal Imports
|
||||||
|
import { Database } from '../shared/Database';
|
||||||
|
|
||||||
|
class GuildCreateEvent extends Event<CommandClient> {
|
||||||
|
event: string = 'guildCreate' as const;
|
||||||
|
|
||||||
|
async handle(context: CommandClient<any, any>, guild: Guild) {
|
||||||
|
await Database.GetOrCreateSettings(guild.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new GuildCreateEvent('guildCreate');
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
// External Imports
|
||||||
|
import { CommandClient, Event, Guild, Member } from 'athena-prime';
|
||||||
|
|
||||||
|
// Internal Imports
|
||||||
|
import { Database } from '../shared/Database';
|
||||||
|
import { getE621Alts } from '../utils';
|
||||||
|
|
||||||
|
// ---------------
|
||||||
|
|
||||||
|
class GuildMemberAddEvent extends Event<CommandClient> {
|
||||||
|
event: string = 'guildMemberAdd' as const;
|
||||||
|
|
||||||
|
async handle(context: CommandClient<any, any>, guild: Guild, member: Member) {
|
||||||
|
const settings = await Database.GetOrCreateSettings(guild.id);
|
||||||
|
|
||||||
|
// TODO: Seperate this into its own function and create a handleWelcomeMessage() function.
|
||||||
|
const content = `${member.toString()}'s (${member.id}) e621 and discord account(s):\n${await getE621Alts(member.id, member.guild)}`;
|
||||||
|
|
||||||
|
if (!settings.moderator_channel_id || !content.includes('[BANNED]')) return;
|
||||||
|
context.createMessage(settings.moderator_channel_id, content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new GuildMemberAddEvent('guildMemberAdd');
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
import { GuildBan } from 'discord.js';
|
|
||||||
import { Database } from '../shared/Database';
|
|
||||||
|
|
||||||
export async function handleBanRemove(ban: GuildBan) {
|
|
||||||
await Database.removeBan(ban.user.id);
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
import { Guild } from 'discord.js';
|
|
||||||
import { Database } from '../shared/Database';
|
|
||||||
|
|
||||||
export async function handleGuildCreate(guild: Guild) {
|
|
||||||
try {
|
|
||||||
if (!await Database.getGuildSettings(guild.id)) await Database.putGuild(guild.id);
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
import { GuildMember, GuildTextBasedChannel } from 'discord.js';
|
|
||||||
import { Database } from '../shared/Database';
|
|
||||||
import { getE621Alts } from '../utils';
|
|
||||||
|
|
||||||
export async function handleMemberJoin(member: GuildMember) {
|
|
||||||
const guildSettings = await Database.getGuildSettings(member.guild.id);
|
|
||||||
|
|
||||||
if (guildSettings?.new_member_channel_id) {
|
|
||||||
const channel = await member.guild.channels.fetch(guildSettings.new_member_channel_id) as GuildTextBasedChannel;
|
|
||||||
|
|
||||||
if (channel) {
|
|
||||||
const content = `${member.toString()}'s (${member.id}) e621 and discord account(s):\n${await getE621Alts(member.id, member.guild)}`;
|
|
||||||
|
|
||||||
channel.send(content).catch(console.error);
|
|
||||||
|
|
||||||
if (guildSettings.moderator_channel_id && content.includes('[BANNED]')) {
|
|
||||||
const modChannel = await member.guild.channels.fetch(guildSettings.moderator_channel_id) as GuildTextBasedChannel;
|
|
||||||
|
|
||||||
if (modChannel) modChannel.send(`Member joined with banned alts:\n${content}`).catch(console.error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+5
-3
@@ -1,7 +1,9 @@
|
|||||||
export * from './handle-audit-log-create';
|
export * from './handle-audit-log-create';
|
||||||
export * from './handle-ban-remove';
|
import guildBanRemove from './guildBanRemove';
|
||||||
export * from './handle-guild-create';
|
import guildCreate from './guildCreate';
|
||||||
export * from './handle-member-join';
|
import guildMemberAdd from './guildMemberAdd';
|
||||||
export * from './handle-message';
|
export * from './handle-message';
|
||||||
export * from './handle-thread-create';
|
export * from './handle-thread-create';
|
||||||
export * from './handle-voice-state-update';
|
export * from './handle-voice-state-update';
|
||||||
|
|
||||||
|
export default [guildBanRemove, guildCreate, guildMemberAdd];
|
||||||
@@ -1,12 +1,15 @@
|
|||||||
import { Client } from 'discord.js';
|
// External Imports
|
||||||
|
import { CommandClient } from 'athena-prime';
|
||||||
|
|
||||||
|
// Internal Imports
|
||||||
import { Task } from '../types';
|
import { Task } from '../types';
|
||||||
import ScheduledTasks from './tasks';
|
import ScheduledTasks from './tasks';
|
||||||
|
|
||||||
class Scheduler {
|
class Scheduler {
|
||||||
private tasks = new Map<Task, NodeJS.Timeout>();
|
private tasks = new Map<Task, NodeJS.Timeout>();
|
||||||
private context: Client;
|
private context: CommandClient;
|
||||||
|
|
||||||
constructor(context: Client) {
|
constructor(context: CommandClient) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -18,6 +21,4 @@ class Scheduler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export { Scheduler, ScheduledTasks }
|
||||||
ScheduledTasks, Scheduler
|
|
||||||
};
|
|
||||||
@@ -1,12 +1,17 @@
|
|||||||
import { Client } from 'discord.js';
|
// External Imports
|
||||||
|
import { CommandClient } from 'athena-prime';
|
||||||
|
|
||||||
|
// Internal Imports
|
||||||
import { Task } from '../../types';
|
import { Task } from '../../types';
|
||||||
import { checkExpiredBans } from '../../utils';
|
import { checkExpiredBans } from '../../utils';
|
||||||
|
|
||||||
|
// ---------------
|
||||||
|
|
||||||
class CheckExpiredBansTask implements Task {
|
class CheckExpiredBansTask implements Task {
|
||||||
interval: number = 300000;
|
interval: number = 300000;
|
||||||
firstRun: boolean = true;
|
firstRun: boolean = true;
|
||||||
|
|
||||||
async handle(context: Client): Promise<void> {
|
async handle(context: CommandClient) {
|
||||||
await checkExpiredBans(context);
|
await checkExpiredBans(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,17 @@
|
|||||||
import { Client } from 'discord.js';
|
// External Imports
|
||||||
|
import { CommandClient } from 'athena-prime';
|
||||||
|
|
||||||
|
// Internal Imports
|
||||||
import { Task } from '../../types';
|
import { Task } from '../../types';
|
||||||
import { closeOldTickets } from '../../utils';
|
import { closeOldTickets } from '../../utils';
|
||||||
|
|
||||||
|
// ---------------
|
||||||
|
|
||||||
class CloseStaleTicketsTask implements Task {
|
class CloseStaleTicketsTask implements Task {
|
||||||
interval: number = 3.6e6;
|
interval: number = 3.6e6;
|
||||||
firstRun: boolean = true;
|
firstRun: boolean = true;
|
||||||
|
|
||||||
async handle(context: Client): Promise<void> {
|
async handle(context: CommandClient) {
|
||||||
await closeOldTickets(context);
|
await closeOldTickets(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
// External Imports
|
||||||
|
import { CommandClient } from 'athena-prime';
|
||||||
|
|
||||||
|
// Internal Imports
|
||||||
import { Task } from '../../types';
|
import { Task } from '../../types';
|
||||||
import { Database } from '../../shared/Database';
|
import { Database } from '../../shared/Database';
|
||||||
|
|
||||||
@@ -5,7 +9,7 @@ class PruneOldMessagesTask implements Task {
|
|||||||
interval: number = 3.6e6;
|
interval: number = 3.6e6;
|
||||||
firstRun: boolean = true;
|
firstRun: boolean = true;
|
||||||
|
|
||||||
async handle(): Promise<void> {
|
async handle(context: CommandClient) {
|
||||||
await Database.pruneOldMessages();
|
await Database.pruneOldMessages();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-12
@@ -2,7 +2,7 @@ import path from 'path';
|
|||||||
import { open, Database as SqliteDatabase } from 'sqlite';
|
import { open, Database as SqliteDatabase } from 'sqlite';
|
||||||
import sqlite3 from 'sqlite3';
|
import sqlite3 from 'sqlite3';
|
||||||
import { Message } from '../events';
|
import { Message } from '../events';
|
||||||
import { AppealMessage, Ban, GithubUserMapping, GuildArraySetting, GuildSetting, GuildSettings, KnowledgebaseItem, LoggedMessage, Note, PrivateHelpTicket, RoleButton, TicketMessage, TicketPhrase } from '../types';
|
import { AppealMessage, Ban, GithubUserMapping, GuildArraySetting, GuildSettings, KnowledgebaseItem, LoggedMessage, Note, PrivateHelpTicket, RoleButton, TicketMessage, TicketPhrase } from '../types';
|
||||||
import { deserializeMessage, serializeMessage, wait } from '../utils';
|
import { deserializeMessage, serializeMessage, wait } from '../utils';
|
||||||
import { readFileSync } from 'fs';
|
import { readFileSync } from 'fs';
|
||||||
import { Encrypter } from './Encrypter';
|
import { Encrypter } from './Encrypter';
|
||||||
@@ -13,7 +13,7 @@ export const enum PrivateHelpTicketStatus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class Database {
|
export class Database {
|
||||||
private static db: SqliteDatabase;
|
static db: SqliteDatabase;
|
||||||
|
|
||||||
static async open(file: string): Promise<void> {
|
static async open(file: string): Promise<void> {
|
||||||
if (Database.db) return;
|
if (Database.db) return;
|
||||||
@@ -28,7 +28,6 @@ export class Database {
|
|||||||
console.log('SQLite database opened');
|
console.log('SQLite database opened');
|
||||||
|
|
||||||
await Database.ensure();
|
await Database.ensure();
|
||||||
|
|
||||||
await Database.migrate();
|
await Database.migrate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,15 +74,19 @@ export class Database {
|
|||||||
|
|
||||||
//#region Guild Settings
|
//#region Guild Settings
|
||||||
|
|
||||||
static async getGuildSettings(guildId: string): Promise<GuildSettings> {
|
static async GetOrCreateSettings(guildId: string): Promise<GuildSettings> {
|
||||||
return await Database.db.get<GuildSettings>('SELECT * FROM settings WHERE guild_id = ?', guildId) as GuildSettings;
|
await Database.db.run(
|
||||||
}
|
'INSERT OR IGNORE INTO settings (guild_id) VALUES (?)',
|
||||||
|
guildId
|
||||||
|
);
|
||||||
|
|
||||||
static async putGuild(guildId: string) {
|
return await Database.db.get<GuildSettings>(
|
||||||
await Database.db.run('INSERT INTO settings(guild_id) VALUES (?)', guildId);
|
'SELECT * FROM settings WHERE guild_id = ?',
|
||||||
}
|
guildId
|
||||||
|
) as GuildSettings;
|
||||||
|
}
|
||||||
|
|
||||||
static async updateGuildSettings(guildId: string, key: GuildSetting, value: string) {
|
static async updateSettings(guildId: string, key: Exclude<keyof GuildSettings, 'guild_id'>, value: string) {
|
||||||
await Database.db.run(`UPDATE settings SET ${key} = ? WHERE guild_id = ?`, value, guildId);
|
await Database.db.run(`UPDATE settings SET ${key} = ? WHERE guild_id = ?`, value, guildId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -332,10 +335,10 @@ export class Database {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static async pruneExpiredBans(date: Date) {
|
static async pruneExpiredBans(date: Date) {
|
||||||
await Database.db.all<Ban[]>('DELETE from bans WHERE expires = 1 AND expires_at <= ?', date);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static async removeBan(userId: string) {
|
static async deleteBan(userId: string) {
|
||||||
await Database.db.run('DELETE from bans WHERE user_id_hash = ?', Encrypter.hash(userId));
|
await Database.db.run('DELETE from bans WHERE user_id_hash = ?', Encrypter.hash(userId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Vendored
-1
@@ -33,7 +33,6 @@ export type GuildSettings = {
|
|||||||
site_breaker_role_id?: string
|
site_breaker_role_id?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
type GuildSetting = Exclude<keyof GuildSettings, 'guild_id'>
|
|
||||||
export type GuildArraySetting = 'staff_categories' | 'safe_channels' | 'link_skip_channels';
|
export type GuildArraySetting = 'staff_categories' | 'safe_channels' | 'link_skip_channels';
|
||||||
|
|
||||||
export type TicketMessage = {
|
export type TicketMessage = {
|
||||||
|
|||||||
Vendored
+2
-2
@@ -1,8 +1,8 @@
|
|||||||
import { Client } from 'discord.js';
|
import { CommandClient } from 'athena-prime';
|
||||||
|
|
||||||
export interface Task {
|
export interface Task {
|
||||||
interval: number;
|
interval: number;
|
||||||
firstRun: boolean;
|
firstRun: boolean;
|
||||||
|
|
||||||
handle(context: Client): Promise<void>;
|
handle(context: CommandClient): Promise<void>;
|
||||||
};
|
};
|
||||||
|
|||||||
+10
-18
@@ -1,7 +1,10 @@
|
|||||||
import { Guild } from 'discord.js';
|
// External Imports
|
||||||
import { Database } from '../shared/Database';
|
import { Guild } from 'athena-prime';
|
||||||
|
|
||||||
|
// Internal Imports
|
||||||
import { userIsBanned } from './e621-utils';
|
import { userIsBanned } from './e621-utils';
|
||||||
import { config } from '../config';
|
import config from '../config';
|
||||||
|
import { Database } from '../shared/Database';
|
||||||
|
|
||||||
export type AltData = {
|
export type AltData = {
|
||||||
type: 'e621' | 'discord'
|
type: 'e621' | 'discord'
|
||||||
@@ -13,7 +16,6 @@ export type AltData = {
|
|||||||
|
|
||||||
export async function getE621Alts(discordId: string, guild: Guild, depth = 1, ignore: number[] = []): Promise<string> {
|
export async function getE621Alts(discordId: string, guild: Guild, depth = 1, ignore: number[] = []): Promise<string> {
|
||||||
const e621UserIds = await Database.getE621Ids(discordId);
|
const e621UserIds = await Database.getE621Ids(discordId);
|
||||||
|
|
||||||
const toIgnore = ignore.concat(e621UserIds);
|
const toIgnore = ignore.concat(e621UserIds);
|
||||||
|
|
||||||
let content = '';
|
let content = '';
|
||||||
@@ -22,7 +24,6 @@ export async function getE621Alts(discordId: string, guild: Guild, depth = 1, ig
|
|||||||
if (ignore.includes(e621Id)) continue;
|
if (ignore.includes(e621Id)) continue;
|
||||||
|
|
||||||
const alts = await getDiscordAlts(e621Id, guild, depth + 1, toIgnore);
|
const alts = await getDiscordAlts(e621Id, guild, depth + 1, toIgnore);
|
||||||
|
|
||||||
const banned = await userIsBanned(e621Id);
|
const banned = await userIsBanned(e621Id);
|
||||||
|
|
||||||
content += `${' '.repeat((depth - 1) * 2)}- ${config.E621_BASE_URL}/users/${e621Id}${banned ? ' [BANNED]' : ''}\n${alts}`;
|
content += `${' '.repeat((depth - 1) * 2)}- ${config.E621_BASE_URL}/users/${e621Id}${banned ? ' [BANNED]' : ''}\n${alts}`;
|
||||||
@@ -38,13 +39,10 @@ export async function getDiscordAlts(e621Id: number, guild: Guild, depth = 1, ig
|
|||||||
|
|
||||||
for (const discordId of discordIds) {
|
for (const discordId of discordIds) {
|
||||||
const alts = await getE621Alts(discordId, guild, depth + 1, ignore);
|
const alts = await getE621Alts(discordId, guild, depth + 1, ignore);
|
||||||
|
|
||||||
let banned = false;
|
let banned = false;
|
||||||
|
|
||||||
// It's either this or fetch all the bans and sift through them for every discord alt.
|
// It's either this or fetch all the bans and sift through them for every discord alt.
|
||||||
try {
|
banned = !!(await guild.getBan(discordId));
|
||||||
banned = !!(await guild.bans.fetch(discordId));
|
|
||||||
} catch (e) { }
|
|
||||||
|
|
||||||
content += `${' '.repeat((depth - 1) * 2)}- <@${discordId}> (${discordId})${banned ? ' [BANNED]' : ''}\n${alts}`;
|
content += `${' '.repeat((depth - 1) * 2)}- <@${discordId}> (${discordId})${banned ? ' [BANNED]' : ''}\n${alts}`;
|
||||||
}
|
}
|
||||||
@@ -69,14 +67,13 @@ async function getE621AltData(discordId: string, guild: Guild | null, depth = 1,
|
|||||||
|
|
||||||
// It's either this or fetch all the bans and sift through them for every discord alt.
|
// It's either this or fetch all the bans and sift through them for every discord alt.
|
||||||
try {
|
try {
|
||||||
banned = guild ? !!(await guild.bans.fetch(discordId)) : false;
|
banned = guild ? !!(await guild.getBan(discordId)) : false;
|
||||||
} catch (e) { }
|
} catch (e) { }
|
||||||
|
|
||||||
const data: AltData = { type: 'discord', thisId: discordId, banned, alts: [] };
|
const data: AltData = { type: 'discord', thisId: discordId, banned, alts: [] };
|
||||||
|
|
||||||
for (const e621Id of e621UserIds) {
|
for (const e621Id of e621UserIds) {
|
||||||
if (ignore.includes(e621Id)) continue;
|
if (ignore.includes(e621Id)) continue;
|
||||||
|
|
||||||
data.alts.push(await getDiscordAltData(e621Id, guild, depth + 1, toIgnore));
|
data.alts.push(await getDiscordAltData(e621Id, guild, depth + 1, toIgnore));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,12 +82,9 @@ async function getE621AltData(discordId: string, guild: Guild | null, depth = 1,
|
|||||||
|
|
||||||
async function getDiscordAltData(e621Id: number, guild: Guild | null, depth = 1, ignore: number[] = []): Promise<AltData> {
|
async function getDiscordAltData(e621Id: number, guild: Guild | null, depth = 1, ignore: number[] = []): Promise<AltData> {
|
||||||
const discordIds = await Database.getDiscordIds(e621Id);
|
const discordIds = await Database.getDiscordIds(e621Id);
|
||||||
|
|
||||||
const data: AltData = { type: 'e621', thisId: e621Id, banned: await userIsBanned(e621Id), alts: [] };
|
const data: AltData = { type: 'e621', thisId: e621Id, banned: await userIsBanned(e621Id), alts: [] };
|
||||||
|
|
||||||
for (const discordId of discordIds) {
|
for (const discordId of discordIds) data.alts.push(await getE621AltData(discordId, guild, depth + 1, ignore));
|
||||||
data.alts.push(await getE621AltData(discordId, guild, depth + 1, ignore));
|
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
@@ -98,9 +92,7 @@ async function getDiscordAltData(e621Id: number, guild: Guild | null, depth = 1,
|
|||||||
export function e621IdsFromAltData(altData: AltData, data: number[] = []) {
|
export function e621IdsFromAltData(altData: AltData, data: number[] = []) {
|
||||||
if (altData.type == 'e621' && !data.includes(altData.thisId as number)) data.push(altData.thisId as number);
|
if (altData.type == 'e621' && !data.includes(altData.thisId as number)) data.push(altData.thisId as number);
|
||||||
|
|
||||||
for (const alt of altData.alts) {
|
for (const alt of altData.alts) e621IdsFromAltData(alt, data);
|
||||||
e621IdsFromAltData(alt, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
+11
-11
@@ -1,22 +1,22 @@
|
|||||||
import { Client } from 'discord.js';
|
// External Imports
|
||||||
|
import { CommandClient } from 'athena-prime';
|
||||||
|
|
||||||
|
// Internal Imports
|
||||||
|
import config from '../config';
|
||||||
import { Database } from '../shared/Database';
|
import { Database } from '../shared/Database';
|
||||||
import { config } from '../config';
|
import { Ban } from '../types';
|
||||||
|
|
||||||
export async function checkExpiredBans(client: Client) {
|
// ---------------
|
||||||
const guild = await client.guilds.fetch(config.DISCORD_GUILD_ID!);
|
|
||||||
|
|
||||||
|
export async function checkExpiredBans(client: CommandClient) {
|
||||||
|
const guild = client.guilds.get(config.DISCORD_GUILD_ID!);
|
||||||
if (!guild) return;
|
if (!guild) return;
|
||||||
|
|
||||||
const date = new Date();
|
const date = new Date();
|
||||||
|
|
||||||
for (const ban of await Database.getExpiredBans(date)) {
|
for (const ban of await Database.getExpiredBans(date)) {
|
||||||
try {
|
await guild.unbanMember(ban.user_id, 'Ban Expired.');
|
||||||
await guild.bans.remove(ban.user_id);
|
|
||||||
} catch (e) {
|
|
||||||
console.error(`Error unbanning user: ${ban.user_id}`);
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await Database.pruneExpiredBans(date);
|
await Database.db.all<Ban[]>('DELETE from bans WHERE expires = 1 AND expires_at <= ?', date);
|
||||||
}
|
}
|
||||||
@@ -1,18 +1,15 @@
|
|||||||
import { APIEmbed, Client } from 'discord.js';
|
import { CommandClient, Constants } from 'athena-prime';
|
||||||
|
|
||||||
type EmbedSeverity =
|
type Severity = 'info' | 'warning' | 'error' | 'success';
|
||||||
| 'default'
|
|
||||||
| 'info'
|
|
||||||
| 'warning'
|
|
||||||
| 'error'
|
|
||||||
| 'success'
|
|
||||||
|
|
||||||
export function CreateDefaultEmbed(context: Client): APIEmbed {
|
export function CreateDefaultEmbed(context: CommandClient): Constants.APIEmbed {
|
||||||
if (!context.user) return {};
|
if (!context.user) return {};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
color: 0x014995,
|
||||||
|
|
||||||
footer: {
|
footer: {
|
||||||
icon_url: context.user.avatarURL()!,
|
icon_url: context.user.avatarURL,
|
||||||
text: context.user.username
|
text: context.user.username
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -20,9 +17,8 @@ export function CreateDefaultEmbed(context: Client): APIEmbed {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function SetSeverity(severity: EmbedSeverity): APIEmbed {
|
export function SetSeverity(severity: Severity): Constants.APIEmbed {
|
||||||
switch (severity) {
|
switch (severity) {
|
||||||
case 'default': return { color: 0x014995 };
|
|
||||||
case 'info': return { color: 0x5865F2 };
|
case 'info': return { color: 0x5865F2 };
|
||||||
case 'warning': return { color: 0xFEE75C };
|
case 'warning': return { color: 0xFEE75C };
|
||||||
case 'error': return { color: 0xED4245 };
|
case 'error': return { color: 0xED4245 };
|
||||||
|
|||||||
@@ -1,26 +1,25 @@
|
|||||||
import { ActionRowBuilder, ButtonBuilder, ButtonStyle, ChannelType, ChatInputCommandInteraction, Client, Guild, GuildMember, ModalBuilder, PrivateThreadChannel, TextChannel, TextInputStyle, ThreadAutoArchiveDuration, ThreadChannel, UserContextMenuCommandInteraction } from 'discord.js';
|
import { ActionRowBuilder, ButtonBuilder, ButtonStyle, ChannelType, ChatInputCommandInteraction, Client, Guild, GuildMember, ModalBuilder, PrivateThreadChannel, TextChannel, TextInputStyle, ThreadAutoArchiveDuration, UserContextMenuCommandInteraction } from 'discord.js';
|
||||||
import { Database } from '../shared/Database';
|
import { Database } from '../shared/Database';
|
||||||
import { createTextInput, createYesNoMenu } from './modal-utils';
|
import { createTextInput, createYesNoMenu } from './modal-utils';
|
||||||
|
|
||||||
export async function closeOldTickets(client: Client) {
|
import { CommandClient, ThreadChannel } from 'athena-prime';
|
||||||
|
|
||||||
|
// TODO: Handle Modmail Errors.
|
||||||
|
export async function closeOldTickets(client: CommandClient) {
|
||||||
for (const ticket of await Database.getAllOpenPrivateHelpTickets()) {
|
for (const ticket of await Database.getAllOpenPrivateHelpTickets()) {
|
||||||
try {
|
const thread = client.getChannel(ticket.thread_id) as ThreadChannel;
|
||||||
const thread = await client.channels.fetch(ticket.thread_id) as ThreadChannel;
|
const latestMessage = (await (thread.getMessages({ limit: 1 }))).at(0);
|
||||||
const latestMessage = (await thread.messages.fetch({ limit: 1 })).at(0);
|
|
||||||
if (latestMessage && latestMessage.createdTimestamp <= Date.now() - 432e6) {
|
if (latestMessage && latestMessage.timestamp <= Date.now() - 432e6) {
|
||||||
await Database.closePrivateHelpTicket(thread.id);
|
await Database.closePrivateHelpTicket(thread.id);
|
||||||
|
|
||||||
await thread.send('This ticket has been closed due to inactivity.');
|
await thread.createMessage('This ticket has been closed due to inactivity.');
|
||||||
|
|
||||||
thread.edit({
|
thread.edit({
|
||||||
archived: true,
|
archived: true,
|
||||||
locked: true
|
locked: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (e) {
|
|
||||||
console.error('Error closing ticket due to inactivity:');
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user