7b56d2e055e5c5c33fb9bfac3d547ded757c0365
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.
tts_bot
Discord 음성채널에서 채팅을 읽어주는 TTS 봇. TypeScript + discord.js 기반.
주요 기능
- 지정한 텍스트 채널의 채팅을 음성채널에서 자동 낭독 (
/tts channel register로 채널 지정) - 치지직(Chzzk) 알림 TTS 엔진 사용 (
utils/tts/Chzzk.ts). 현재 코드는VoiceType.가람고정 (VoiceTypeenum에 다른 보이스도 정의돼 있어 코드 한 줄 수정으로 교체 가능) - 대체 엔진으로 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.jsv14,@discordjs/voice,@discordjs/opusbetter-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.jsoncompilerOptions에 추가하면 정상 빌드된다.
Docker
docker build -t tts_bot .
docker run --env-file .env -v $(pwd)/db:/app/db tts_bot
Dockerfile은 node:20-alpine 기반이며 ffmpeg을 설치한다. 단 위 "알려진 빌드 결함"이 해결돼야 이미지 빌드가 통과한다.
동작 흐름 요약
messageCreate→ 등록된 TTS 채널이면TTSClient.tts()호출- 텍스트 전처리(URL/멘션/이모지 치환) → 시그니처 키워드 분할
- 각 조각을 Chzzk TTS로 합성 또는 캐시된 시그니처 mp3 사용
- mp3 Buffer 결합 →
Transcode에서 PCM 변환 →VoiceSession.player.play() - 일정 시간 idle 시 세션 자동 종료, 사용자 채널 이동 시 따라감
참고
- 시그니처 서버 주소(
192.168.10.5:2967)는SignatureClient.ts에 하드코딩 — 환경에 맞게 수정 필요 commands/내 파일은 default export class 형태로 자동 로드되므로 새 명령어 추가 시 같은 패턴 유지- 현재
users테이블 스키마는 정의돼 있으나 코드에서 사용 흔적은 적음 (향후 확장 여지)
Description
Languages
TypeScript
99.5%
Dockerfile
0.5%