- 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.
79 lines
2.5 KiB
TypeScript
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)
|
|
};
|
|
}
|