Refactor Amayo client initialization and enhance editor functionality

- Updated the Amayo client to use environment variables for configuration defaults.
- Improved cache and sweeper settings for message and user management.
- Added detailed error handling and logging during database connection and Discord login.
- Introduced a new interactive editor for creating and managing display components with modals.
- Implemented various editor actions including adding content, editing titles/descriptions, and managing components.
- Enhanced user feedback with ephemeral messages for actions taken in the editor.
This commit is contained in:
Shni
2025-10-14 11:12:52 -05:00
parent 6482fbc8ea
commit 0eb5aa0691
3 changed files with 2403 additions and 974 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,64 +1,95 @@
import { Client, GatewayIntentBits, Options, Partials } from 'discord.js'; import {
import { prisma, ensurePrismaConnection } from './database/prisma'; Client,
import logger from './lib/logger'; GatewayIntentBits,
Options,
Partials,
ClientOptions,
} from "discord.js";
import { prisma, ensurePrismaConnection } from "./database/prisma";
import logger from "./lib/logger";
const DEFAULTS = {
CACHE_MESSAGES_LIMIT: 50,
CACHE_MEMBERS_LIMIT: 100,
SWEEP_MESSAGES_INTERVAL_SECONDS: 300,
SWEEP_MESSAGES_LIFETIME_SECONDS: 900,
USERS_SWEEP_INTERVAL_SECONDS: 60 * 30,
REST_RETRIES: 5,
} as const;
function intEnv(name: keyof typeof DEFAULTS, fallback?: number): number {
const raw = process.env[name];
const val = raw ? parseInt(raw, 10) : NaN;
return Number.isFinite(val) ? val : fallback ?? DEFAULTS[name];
}
class Amayo extends Client { class Amayo extends Client {
public key: string; public key: string;
public prisma = prisma; public prisma = prisma;
public mode: string; public mode: string;
constructor() { constructor() {
super({ // Build options here so `this` can be referenced in the users.sweep filter
intents: [ const options: ClientOptions = {
GatewayIntentBits.Guilds, intents: [
GatewayIntentBits.GuildMembers, GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages, GatewayIntentBits.GuildMembers,
GatewayIntentBits.MessageContent GatewayIntentBits.GuildMessages,
], GatewayIntentBits.MessageContent,
partials: [Partials.Channel, Partials.Message], ],
makeCache: Options.cacheWithLimits({ partials: [Partials.Channel, Partials.Message],
MessageManager: parseInt(process.env.CACHE_MESSAGES_LIMIT || '50', 10), makeCache: Options.cacheWithLimits({
GuildMemberManager: parseInt(process.env.CACHE_MEMBERS_LIMIT || '100', 10), MessageManager: intEnv("CACHE_MESSAGES_LIMIT"),
ThreadManager: 10, GuildMemberManager: intEnv("CACHE_MEMBERS_LIMIT"),
ReactionManager: 0, ThreadManager: 10,
GuildInviteManager: 0, ReactionManager: 0,
StageInstanceManager: 0, GuildInviteManager: 0,
PresenceManager: 0 StageInstanceManager: 0,
}), PresenceManager: 0,
sweepers: { }),
messages: { sweepers: {
interval: parseInt(process.env.SWEEP_MESSAGES_INTERVAL_SECONDS || '300', 10), messages: {
lifetime: parseInt(process.env.SWEEP_MESSAGES_LIFETIME_SECONDS || '900', 10) interval: intEnv("SWEEP_MESSAGES_INTERVAL_SECONDS"),
}, lifetime: intEnv("SWEEP_MESSAGES_LIFETIME_SECONDS"),
users: { },
interval: 60 * 30, users: {
filter: () => (user) => user.bot && user.id !== this.user?.id interval: DEFAULTS.USERS_SWEEP_INTERVAL_SECONDS,
} filter: () => (user) => user.bot && user.id !== this.user?.id,
}, },
rest: { },
retries: 5 rest: {
} retries: DEFAULTS.REST_RETRIES,
}); },
};
this.key = process.env.TOKEN ?? ''; super(options);
this.mode = process.env.MODE ?? 'Normal';
this.key = process.env.TOKEN ?? "";
this.mode = process.env.MODE ?? "Normal";
}
/**
* Inicia la conexión a la base de datos y al gateway de Discord.
* Lanza si falta la clave o si falla la conexión/login.
*/
public async play(): Promise<void> {
if (!this.key) {
logger.error("No key provided");
throw new Error("Missing DISCORD TOKEN");
} }
async play() { try {
if (!this.key) { await ensurePrismaConnection();
logger.error('No key provided'); logger.info("Successfully connected to the database (singleton).");
throw new Error('Missing DISCORD TOKEN'); await this.login(this.key);
} else { } catch (error) {
try { logger.error(
await ensurePrismaConnection(); { err: error },
logger.info('Successfully connected to the database (singleton).'); "Failed to connect to DB or login to Discord"
await this.login(this.key); );
} catch (error) { throw error;
logger.error({ err: error }, 'Failed to connect to DB or login to Discord');
throw error;
}
}
} }
}
} }
export default Amayo; export default Amayo;