- Dockerfile base now node:22-bookworm-slim (glibc) so better-sqlite3 uses prebuilt binaries and node-gyp/python build deps are no longer required. Also satisfies @discordjs/voice node>=22.12 engine req. - Drop redundant `mkdir -p dist` (build script handles it). - Add .env.example covering TOKEN, APPID, PREFIX, DBPATH, GUILDID, CHZZK_NID_AUT/SES, SIGNATURE_HOST, TTSPATH, DEV, DEBUG, REPLACETEXT. - README: update base image note.
5.6 KiB
5.6 KiB
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)과 병합 |
SIGNATURE_HOST |
선택 | 시그니처 서버 host:port. 미설정 시 192.168.10.5:2967 기본값 |
TTSPATH |
선택 | Config.ttsPath getter만 정의돼 있고 현재 호출처 없음. 향후 사용 대비 환경변수만 받아둠 |
실행
# 의존성 설치
npm install
# 개발 (ts-node)
npm run dev
# 빌드 후 실행 (build 스크립트가 dist 디렉터리를 자동 생성)
npm run build
npm start
# 전역 슬래시 명령어 등록 (배포 파이프라인)
npm run prod
Docker
docker build -t tts_bot .
docker run --env-file .env -v $(pwd)/db:/app/db tts_bot
Dockerfile은 node:22-bookworm-slim 기반이며 ffmpeg을 설치한다. (이전 node:20-alpine 은 musl 환경이라 better-sqlite3 prebuilt 가 없어 node-gyp/python 빌드 의존성이 필요했고, @discordjs/voice 의 node>=22 요구도 충족하지 못해 변경했다.)
동작 흐름 요약
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테이블 스키마는 정의돼 있으나 코드에서 사용 흔적은 적음 (향후 확장 여지)