diff --git a/packages/shared/src/config/index.ts b/packages/shared/src/config/index.ts index 79f6a23..a6cfe4f 100644 --- a/packages/shared/src/config/index.ts +++ b/packages/shared/src/config/index.ts @@ -15,6 +15,10 @@ export const configSchema = z .string() .min(1, "DISCORD_TOKEN is required") .transform((value) => value.replace(/^("|')|(?:("|'))$/g, "")), + MONITOR_GUILD_IDS: z + .string() + .default("") + .transform((v) => v.split(",").filter(Boolean)), MONITOR_GUILD_ID: z.string().min(1).optional(), TEXT_GUILD_ID: z.string().min(1).optional(), TEXT_CHANNEL_ID: z.string().min(1).optional(), @@ -56,6 +60,15 @@ export const configSchema = z .transform((v) => v === "true") .default(false), ADMIN_PASSWORD: z.string().default("admin123"), + WEBHOOK_URLS: z + .string() + .default("") + .transform((v) => v.split(",").filter(Boolean)), + WEBHOOK_EVENTS: z + .string() + .default("message_flagged,auto_deleted,high_severity") + .transform((v) => v.split(",").filter(Boolean)), + METRICS_PORT: z.coerce.number().positive().default(9090), // ── Database (PostgreSQL) ──────────────────────────────────────────── DATABASE_URL: z.string().optional(), @@ -226,6 +239,7 @@ export const configSchema = z export type AppConfig = z.infer & { EFFECTIVE_TEXT_GUILD_ID?: string; EFFECTIVE_VOICE_GUILD_ID?: string; + EFFECTIVE_MONITOR_GUILD_IDS: string[]; }; export function loadConfig(env: NodeJS.ProcessEnv = process.env): AppConfig { @@ -235,6 +249,12 @@ export function loadConfig(env: NodeJS.ProcessEnv = process.env): AppConfig { ...parsed, EFFECTIVE_TEXT_GUILD_ID: parsed.TEXT_GUILD_ID ?? parsed.MONITOR_GUILD_ID, EFFECTIVE_VOICE_GUILD_ID: parsed.VOICE_GUILD_ID, + EFFECTIVE_MONITOR_GUILD_IDS: + parsed.MONITOR_GUILD_IDS.length > 0 + ? parsed.MONITOR_GUILD_IDS + : parsed.MONITOR_GUILD_ID + ? [parsed.MONITOR_GUILD_ID] + : [], }; } catch (error) { if (error instanceof z.ZodError) { diff --git a/packages/shared/src/redis-channels.ts b/packages/shared/src/redis-channels.ts index 78b26f3..6dd7ed1 100644 --- a/packages/shared/src/redis-channels.ts +++ b/packages/shared/src/redis-channels.ts @@ -21,6 +21,15 @@ export const DISCORD_VOICE_UPLOADED = "discord:voice:uploaded"; export const DISCORD_VOICE_ACTIVE_USER = "discord:voice:active_user"; export const DISCORD_VOICE_PCM = "discord:voice:pcm"; export const DISCORD_ANALYSIS_QUEUE_STATUS = "discord:analysis:queue_status"; +export const DISCORD_REACTION_ADDED = "discord:reaction:added"; +export const DISCORD_REACTION_REMOVED = "discord:reaction:removed"; +export const DISCORD_THREAD_CREATED = "discord:thread:created"; +export const DISCORD_THREAD_DELETED = "discord:thread:deleted"; +export const DISCORD_THREAD_UPDATED = "discord:thread:updated"; +export const DISCORD_CHANNEL_TOPIC_UPDATED = "discord:channel:topic_updated"; +export const DISCORD_PRESENCE_UPDATED = "discord:presence:updated"; +export const DISCORD_GUILD_MEMBER_ADDED = "discord:guild_member:added"; +export const DISCORD_GUILD_MEMBER_REMOVED = "discord:guild_member:removed"; // --------------------------------------------------------------------------- // Command channels (backend -> discord-gateway) @@ -43,6 +52,7 @@ export const MEDIA_STATUS_KEY = "media:status"; export const COMMAND_VOICE_CONNECT = "voice:connect"; export const COMMAND_VOICE_DISCONNECT = "voice:disconnect"; +export const COMMAND_VOICE_DISCONNECT_GUILD = "voice:disconnect:guild"; export const COMMAND_VOICE_CHANNELS = "voice:channels"; export const COMMAND_VOICE_TRANSMIT_START = "voice:transmit:start"; export const COMMAND_VOICE_TRANSMIT_STOP = "voice:transmit:stop"; @@ -53,6 +63,7 @@ export const COMMAND_MEDIA_SKIP = "media:skip"; export const COMMAND_MEDIA_STOP = "media:stop"; export const COMMAND_MEDIA_VOLUME = "media:volume"; export const COMMAND_MODERATION_ACTION = "moderation:action"; +export const DISCORD_VOICE_ANALYZED = "discord:voice:analyzed"; // --------------------------------------------------------------------------- // Event envelope — used by discord-gateway when publishing to Redis