import { Guild, GuildMember, PermissionFlagsBits } from 'discord.js'; import { prisma } from '../database'; import { logger } from '../utils/logger'; import { auditLogService } from './AuditLogService'; export class AutoRoleService { /** * 서버의 자동 역할 설정을 조회합니다. */ async getConfig(guildId: string) { return prisma.autoRoleConfig.findUnique({ where: { guildId }, }); } /** * 서버의 자동 역할 설정을 업데이트합니다. */ async updateConfig(guildId: string, data: { userRoleIds?: string[]; botRoleIds?: string[]; isEnabled?: boolean; botEnabled?: boolean; }) { return prisma.autoRoleConfig.upsert({ where: { guildId }, create: { guildId, ...data, }, update: data, }); } /** * 자동 역할 부여 기능을 활성/비활성합니다. */ async setEnabled(guildId: string, enabled: boolean) { return this.updateConfig(guildId, { isEnabled: enabled }); } /** * 신규 멤버가 입장했을 때 자동으로 역할을 부여합니다. */ async handleMemberJoin(member: GuildMember) { const config = await this.getConfig(member.guild.id); if (!config) return; const isBot = member.user.bot; const isEnabled = isBot ? config.botEnabled : config.isEnabled; const roleIds = isBot ? config.botRoleIds : config.userRoleIds; if (!isEnabled || roleIds.length === 0) return; try { await member.roles.add(roleIds, 'Kord Auto-Role'); logger.info(`[AutoRole] Added roles to ${member.user.tag} in ${member.guild.name}`); } catch (error) { logger.error(`[AutoRole] Failed to add roles to ${member.user.tag} in ${member.guild.name}`, error); // 권한 문제인 경우 감사 로그에 기록 await auditLogService.log(member.guild, { category: 'PERMISSION', severity: 'WARN', title: 'Auto-Role Failure', description: `Failed to assign roles to ${member.user.toString()} automatically. Please check the bot's permission and role hierarchy.` }).catch(() => {}); } } } export const autoRoleService = new AutoRoleService();