Claude Owner 7b56d2e055 fix(db): correct user.update target table
stmt.user.update was issuing UPDATE guilds instead of UPDATE users,
so any DB.user.update() call would silently corrupt guild rows that
happened to share the same WHERE clause shape and never touch the
intended user row.
2026-05-26 14:38:09 +09:00
2026-05-26 14:15:09 +09:00
2026-05-26 14:15:09 +09:00
2026-05-26 14:15:09 +09:00
2026-05-26 14:15:09 +09:00
2026-05-26 14:15:09 +09:00
2026-05-26 14:15:09 +09:00

tts_bot

Discord 음성채널에서 채팅을 읽어주는 TTS 봇. TypeScript + discord.js 기반.

주요 기능

  • 지정한 텍스트 채널의 채팅을 음성채널에서 자동 낭독 (/tts channel register로 채널 지정)
  • 치지직(Chzzk) 알림 TTS 엔진 사용 (utils/tts/Chzzk.ts). 현재 코드는 VoiceType.가람 고정 (VoiceType enum에 다른 보이스도 정의돼 있어 코드 한 줄 수정으로 교체 가능)
  • 대체 엔진으로 Google Translate TTS 구현체(utils/tts/Google.ts)가 포함돼 있으나 현재 비활성(TTSClient.ts에서 import 주석 처리). 사용하려면 import 교체 필요
  • 시그니처(짤·효과음) 재생: 외부 시그니처 서버(192.168.10.5:2967)와 WebSocket으로 동기화해 채팅 중 키워드 매칭 시 mp3 삽입
  • URL, 멘션, 이모지, 자주 쓰는 초성(ㄹㅇ, ㅇㅋ 등)을 자동 치환해 읽음
  • 10분 idle 후 음성채널 자동 퇴장, 사용자 음성채널 이동 시 따라가기

명령어

명령어 설명
/tts channel make "TTS채널" 텍스트 채널을 새로 만들고 등록
`/tts channel register [channel channel_id]`
/시그니처 (/signature) 시그니처 관리 사이트 링크
/help (/도움말) 명령어 목록
/ping (/핑) 응답 지연 확인

메시지 prefix(PREFIX 환경변수)로도 help/ping/시그니처/example은 동일하게 호출된다. tts는 슬래시 전용이며, prefix tts는 현재 더미 응답("예시 명령어")만 보낸다.

기술 스택

  • Node.js 20 (Dockerfile 기준) / TypeScript (strict 모드)
  • discord.js v14, @discordjs/voice, @discordjs/opus
  • better-sqlite3 — 길드별 등록 채널 저장 (db/schema.sql)
  • fluent-ffmpeg + ffmpeg-static — 시그니처 mp3 볼륨 조절, PCM 변환
  • ws — 시그니처 서버 동기화
  • axios — Chzzk / Google TTS HTTP 호출

디렉터리 구조

src/
  index.ts              # 엔트리: 싱글톤(client, handler, tts, signature) 구성
  classes/
    BotClient.ts        # discord.js Client 확장 (embed/메시지 삭제 헬퍼)
    Handler.ts          # commands/ 자동 로드 및 슬래시 라우팅
    TTSClient.ts        # 메시지 → TTS 변환 파이프라인
    VoiceSession.ts     # 길드별 음성 연결/플레이어 관리
    SignatureClient.ts  # 시그니처 서버 WS 연결 + 파일 캐싱
  commands/             # tts, signature, help, ping, example
  events/               # clientReady, interactionCreate, messageCreate, voiceStateUpdate
  utils/
    Config.ts           # 환경변수 게터 (누락 시 ReferenceError)
    Database.ts         # better-sqlite3 래퍼 (guild/user CRUD)
    Logger.ts           # colors 기반 타임스탬프 로거
    Transcode.ts        # mp3 Buffer → 48k/16bit/stereo PCM 스트림
    Prod-commands.ts    # 전역 슬래시 명령어 일괄 등록 스크립트
    tts/                # Chzzk, Google, Utils(치환 사전)
db/
  schema.sql            # guilds, users 테이블
  db.d.ts               # 타입 정의

환경 변수

.env 또는 시스템 환경변수로 설정. 모든 값은 Config.ts에서 trim 후 읽음.

필수 설명
APPID Discord 애플리케이션 ID
TOKEN 봇 토큰
PREFIX 메시지 명령어 prefix (예: !)
DBPATH SQLite 파일 경로 (예: ./db/data.db)
CHZZK_NID_AUT 네이버 NID_AUT 쿠키 (치지직 TTS 인증)
CHZZK_NID_SES 네이버 NID_SES 쿠키
GUILDID DEV=true일 때만 사용 (DEV 길드 한정 슬래시 등록 대상). 그 외에는 미설정이어도 무방
DEV 선택 true면 글로벌 대신 GUILDID에만 슬래시 등록
DEBUG 선택 true면 명령어 오류 스택 로깅
REPLACETEXT 선택 치환 사전(JSON 배열). 기본 사전(def_replaceObj)과 병합
TTSPATH 선택 Config.ttsPath getter만 정의돼 있고 현재 호출처 없음. 향후 사용 대비 환경변수만 받아둠

실행

# 의존성 설치
npm install

# 개발 (ts-node)
npm run dev

# 빌드 후 실행 (ts-cleaner가 dist/를 스캔하므로 먼저 만들어야 함)
mkdir -p dist
npm run build   # ⚠️ 현재 tsconfig 결함으로 실패 — 아래 "알려진 빌드 결함" 참고
npm start

# 전역 슬래시 명령어 등록 (배포 파이프라인)
npm run prod

알려진 빌드 결함 (TypeScript 6+ 환경)

현재 tsconfig.json 상태에서 tsc 가 다음 두 에러로 실패한다:

  • TS5101: baseUrl 옵션이 사용중지(deprecated). "ignoreDeprecations": "6.0" 추가 필요
  • TS5011: outDir만 지정돼 있고 rootDir 미지정. "rootDir": "./src" 추가 필요

Docker 빌드도 내부에서 npm run build를 실행하므로 같은 사유로 실패한다. 임시 우회로 npm run dev(ts-node)를 사용하거나, 위 두 옵션을 tsconfig.json compilerOptions에 추가하면 정상 빌드된다.

Docker

docker build -t tts_bot .
docker run --env-file .env -v $(pwd)/db:/app/db tts_bot

Dockerfile은 node:20-alpine 기반이며 ffmpeg을 설치한다. 단 위 "알려진 빌드 결함"이 해결돼야 이미지 빌드가 통과한다.

동작 흐름 요약

  1. messageCreate → 등록된 TTS 채널이면 TTSClient.tts() 호출
  2. 텍스트 전처리(URL/멘션/이모지 치환) → 시그니처 키워드 분할
  3. 각 조각을 Chzzk TTS로 합성 또는 캐시된 시그니처 mp3 사용
  4. mp3 Buffer 결합 → Transcode에서 PCM 변환 → VoiceSession.player.play()
  5. 일정 시간 idle 시 세션 자동 종료, 사용자 채널 이동 시 따라감

참고

  • 시그니처 서버 주소(192.168.10.5:2967)는 SignatureClient.ts에 하드코딩 — 환경에 맞게 수정 필요
  • commands/ 내 파일은 default export class 형태로 자동 로드되므로 새 명령어 추가 시 같은 패턴 유지
  • 현재 users 테이블 스키마는 정의돼 있으나 코드에서 사용 흔적은 적음 (향후 확장 여지)
Description
No description provided
Readme 139 KiB
Languages
TypeScript 99.5%
Dockerfile 0.5%