Kord/Docs/WorkDone/2026-03-27_Voice_Channels_I...

4.7 KiB

2026-03-27 작업 내역: 임시 음성 채널 기능 구현

체인지로그 (Changelog)

  • 2026-03-27: Kord 봇 음성 채널 제어 시스템 스펙 기획 및 전체 로직 구현 완료

본문 (Body)

1. 🎯 주요 목표 (Objective)

사용자가 봇 서버의 특정한 '생성용 채널(Generator)'에 입장하면, 유저 본인 소유의 '임시 전용 채널'을 만들어 주고, 빈 방이 되었을 때 삭제하여 채널 환경을 깔끔하게 유지하는 자동화 시스템 및 티어 기반 한도 제어 시스템을 구축.

2. 📝 진행 내역 (Work Done)

  • DB 스키마(Prisma) 설계 및 반영:
    • SubscriptionTier (FREE, STANDARD, PRO, PREMIUM) 추가.
    • UserSubscription, GuildOwnership 모델 생성하여 관리자 티어에 따른 리소스 상속 체계 마련.
    • VoiceGenerator, TempVoiceChannel, UserVoiceProfile 모델 반영.
  • 백엔드 리소스 개발:
    • src/commands/voiceSetup.ts: 특정 채널을 생성용(Generator)으로 지정하는 슬래시 커맨드.
    • src/events/voiceStateUpdate.ts, src/services/VoiceService.ts: 유저 접속 및 퇴장 이벤트를 감지하여 데이터베이스 검증을 거친 후 동적으로 채널을 생성/삭제하는 핵심 로직 구현.
  • 인터랙션/UI 개발:
    • src/events/interactionCreate.ts: 생성된 임시 채널 채팅창에 띄워진 조작 패널(단일 드롭다운 StringSelectMenu)에 대응하는 Modal 및 Select Menu 핸들러 추가. (이름 변경, 인원수 제한, Lock/Unlock, Kick, Ban)
    • 사용자 피드백 반영: 조작 패널을 기존 6개 버튼에서 단일 드롭다운(StringSelectMenu)으로 리팩토링하여 UI 깔끔함 확보.

3. 🤔 주요 의사결정 (Decisions Made)

  • 차단(Ban) 동작 정의: 특정 인터랙션에서 유저 밴 기능을 수행할 경우, 음성 채널 설정(Overwrite) API를 사용하여 해당 유저의 Connect, ViewChannel 권한을 모두 박탈함으로써 채널 텍스트 캐시 및 접속을 완전히 보이지 않게(투명화) 설계함.
  • 티어 권한 소유 구조: 서버 단위가 주체가 되는 것이 아니라, 봇을 초대한 '사용자 단위'가 주체가 되도록 GuildOwnershipUserSubscription을 연결. 추후 다양한 서비스에 재활용 가능하도록 기반 구축. (Docs/Decisions/subscription_tiers.md 참고)

4. 🛠️ 트러블슈팅 (Troubleshooting)

  • TypeScript 타입 캐스팅 관련 이슈:
    • 문제: interactionCreate에서 interaction.member.voice 에 접근 시 APIInteractionGuildMember 타입과의 충돌로 컴파일(yarn build) 에러 발생.
    • 해결: interaction.member as GuildMember 명시적 타입 캐스팅을 통해 voice.channel 객체 보장 및 에러 해결 완료.
  • 런타임 초기화 - 디스코드 권한(Intents) 충돌:
    • 문제: 로컬 구동 테스트 중 Error: Used disallowed intents 발생.
    • 원인: KordClient 부팅 시 GuildMembers, MessageContent, Presence 세 가지 Privileged Gateway Intent를 요구하나 디스코드 온라인 설정상 비활성화되어 있음.
    • 해결: 개발 과정에선 소스 오류가 아님을 확인 후, 사용자에게 디스코드 포털에서의 활성화 작업 요청 조치.
  • 채널 생성 권한 충돌 (50013: Missing Permissions):
    • 문제: 봇이 임시 채널을 생성할 때 방장에게 ManageRoles, ManageChannels 등의 오버라이드 권한을 주려 했으나, 봇 자신에게 해당 권한이 서버 수준에서 부족하여 생성 실패 에러 발생.
    • 해결: 권한 덮어쓰기 로직에 try-catch 래핑을 추가하여 실패 시 권한 오버라이드를 제외한 순정 채널로 생성하도록 우회 해결. 자세한 사항은 50013_Missing_Permissions.md 참고.
  • 퇴장 시 채널 미삭제 및 유령 방 버그:
    • 문제: 채널 내에 음악봇 등 봇만 남았을 때 삭제 조건이 작동하지 않고, 권한 문제로 삭제가 실패했을 때 DB 무결성이 깨지는 버그.
    • 해결: 휴먼 카운트(humanCount) 도입 및 삭제 롤백 검증 처리. 자세한 사항은 handleLeave_ghost_channel.md 참조.
  • 멀티 인스턴스 대응 및 봇 재부팅 복구 (Boot Recovery):
    • 사유: 봇 재시작, 크래시, 혹은 다중 노드(Multi-Instance) 환경에서 DB와 디스코드 실제 채널 상태가 어긋나게 될 경우를 방지.
    • 해결: ioredis 분산 락(Distributed Lock)과 결합된 VoiceService.syncChannels 메서드를 구현하여, 부팅 시 딱 하나의 인스턴스만 DB를 훑으며 삭제되어야 할 유령 방들을 크로스체크 및 안전하게 청소(Garbage Collection)하도록 반영.