Files
Nexumi/apps/bot/src/modules/welcome/service.ts
TheOnlyMace 4e135bcf43 Enhance component message handling and introduce new features
- Added `ComponentMessageBinding` model to manage message components in the database.
- Updated `WelcomeConfig`, `Tag`, and `ScheduledMessage` models to support new component fields.
- Integrated component handling in various modules, including Scheduler and Tags, to improve message customization.
- Enhanced user experience by implementing new commands for creating and managing component messages in the utility module.
- Updated localization files to reflect new component-related features and improve user guidance.
2026-07-22 22:55:37 +02:00

79 lines
2.5 KiB
TypeScript

import type { PrismaClient } from '@prisma/client';
import type { WelcomeEmbed, WelcomeMessageType } from '@nexumi/shared';
import { applyWelcomePlaceholders, parseMessageComponentsV2 } from '@nexumi/shared';
import type { Guild, GuildMember } from 'discord.js';
import { ensureGuild } from '../../guild.js';
export async function getWelcomeConfig(prisma: PrismaClient, guildId: string) {
await ensureGuild(prisma, guildId);
let config = await prisma.welcomeConfig.findUnique({ where: { guildId } });
if (!config) {
config = await prisma.welcomeConfig.create({ data: { guildId } });
}
return config;
}
export function buildPlaceholderVars(member: GuildMember, guild: Guild) {
return {
user: `<@${member.id}>`,
'user.name': member.displayName,
'user.tag': member.user.tag,
'user.id': member.id,
'user.avatar': member.user.displayAvatarURL({ size: 256 }),
server: guild.name,
memberCount: guild.memberCount,
'server.icon': guild.iconURL({ size: 128 }) ?? ''
};
}
export function renderWelcomeText(template: string, member: GuildMember, guild: Guild): string {
return applyWelcomePlaceholders(template, buildPlaceholderVars(member, guild));
}
export function parseWelcomeEmbed(raw: unknown): WelcomeEmbed | null {
if (!raw || typeof raw !== 'object') {
return null;
}
return raw as WelcomeEmbed;
}
export type WelcomePayload = {
type: WelcomeMessageType;
content?: string | null;
embed?: WelcomeEmbed | null;
components?: import('@nexumi/shared').MessageComponentsV2 | null;
imageTitle?: string | null;
imageSubtitle?: string | null;
};
export function resolveWelcomePayload(
config: Awaited<ReturnType<typeof getWelcomeConfig>>
): WelcomePayload {
return {
type: config.welcomeType as WelcomeMessageType,
content: config.welcomeContent,
embed: parseWelcomeEmbed(config.welcomeEmbed),
components: parseMessageComponentsV2(config.welcomeComponents),
imageTitle: config.imageTitle,
imageSubtitle: config.imageSubtitle
};
}
export type LeavePayload = {
type: import('@nexumi/shared').LeaveMessageType;
content?: string | null;
embed?: WelcomeEmbed | null;
components?: import('@nexumi/shared').MessageComponentsV2 | null;
};
export function resolveLeavePayload(
config: Awaited<ReturnType<typeof getWelcomeConfig>>
): LeavePayload {
return {
type: (config.leaveType as LeavePayload['type']) || 'TEXT',
content: config.leaveContent,
embed: parseWelcomeEmbed(config.leaveEmbed),
components: parseMessageComponentsV2(config.leaveComponents)
};
}