https://github.com/yichen11818/neteasetsbot
TSBot 是一个为 TeamSpeak 制作的网易云音乐机器人,提供网易云音乐播放及网页服务,一键式启动与安装,免除繁杂的依赖安装
https://github.com/yichen11818/neteasetsbot
neteasecloudmusicapi teamspeak teamspeak3-bot teamspeak6
Last synced: 2 months ago
JSON representation
TSBot 是一个为 TeamSpeak 制作的网易云音乐机器人,提供网易云音乐播放及网页服务,一键式启动与安装,免除繁杂的依赖安装
- Host: GitHub
- URL: https://github.com/yichen11818/neteasetsbot
- Owner: yichen11818
- License: mit
- Created: 2026-01-14T15:49:16.000Z (5 months ago)
- Default Branch: main
- Last Pushed: 2026-03-08T11:16:48.000Z (3 months ago)
- Last Synced: 2026-03-08T14:49:46.649Z (3 months ago)
- Topics: neteasecloudmusicapi, teamspeak, teamspeak3-bot, teamspeak6
- Language: Vue
- Homepage:
- Size: 2.28 MB
- Stars: 27
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.en.md
- License: LICENSE
Awesome Lists containing this project
README
# TSBot (NeteaseTSBot)
[](LICENSE)








[](README.md)
TSBot is a TeamSpeak based music bot; the `voice-service` primary client connection already supports TS6 (historical env var names remain `TSBOT_TS3_*`). It provides:
- **TeamSpeak voice playback** (connects to TeamSpeak servers and plays audio via `voice-service`; primary client connection supports TS3/TS6)
- **Queue and playback control** (pause/resume/next/previous, volume, shuffle/repeat, etc.)
- **Netease music search/playlists/likes/lyrics** (via external `NeteaseCloudMusicApi`)
- **QQ Music search/playlists/lyrics/play URLs** (built into backend; login-required features can be configured from the web console)
- **Web console** (Vue 3 frontend for search/queue/lyrics/settings)





## Why TSBot (Pain Points and Goals)
This project aims to solve the "dependency hell" and maintainability issues of older setups.
A common old stack looked like this:
- `TS3AudioBot`
- `NeteaseCloudMusicApi`
- `TS3AudioBot-NetEaseCloudmusic-plugin`
In practice, this stack often suffers from:
- **Heavy coupling**: the three pieces are tightly bound by versions, interfaces, and runtime assumptions, making deployment and troubleshooting expensive.
- **Hard API replacement/updates**: Netease-related APIs change frequently, and replacing/upgrading API logic can cascade into bot core or plugin code.
- **Critical plugin disappearance**: if `TS3AudioBot-NetEaseCloudmusic-plugin` becomes unavailable, the whole chain breaks and can no longer be maintained.
TSBot redraws those boundaries:
- **Voice and business logic are decoupled**: `voice-service` only handles "connect to TeamSpeak + play audio", exposing a stable gRPC control surface.
- **Netease is a replaceable dependency**: backend talks to external `NeteaseCloudMusicApi` through `TSBOT_NETEASE_API_BASE`; future replacements/upgrades are largely isolated in backend adapters.
- **Maintainable and evolvable architecture**: frontend/backend/voice-service can iterate independently, reducing single-point breakage.
The project has 3 components:
- **backend/**: Python/FastAPI backend (queue/search/Netease + QQ Music integration/voice control)
- **voice-service/**: Rust voice service (TeamSpeak connection + audio playback, exposes gRPC to backend)
- **web/**: Vue 3 + Vite frontend (web console/player UI)
More docs:
- `HOWTOSTART.md` (deployment/run guide)
- `LOGGING.md` (unified logging system)
- `web/README.md` (frontend details)
## System Requirements
- **Linux** (Ubuntu 20.04+ recommended)
- **Python**: 3.8+
- **Node.js**: 16+
- **Rust**: 1.70+ (for `voice-service`)
Music source dependency notes:
- **NeteaseCloudMusicApi** (required only for Netease features; self-hosted HTTP service)
- **QQ Music** (built into backend; user playlists and more stable song URLs usually require an admin QQ Music cookie)
## Architecture Overview
```text
[web (Vue3)] <--HTTP--> [backend (FastAPI)] <--gRPC--> [voice-service (Rust)] --> TeamSpeak (TS3/TS6)
|
| HTTP
v
[NeteaseCloudMusicApi]
```
## TeamSpeak / TS6 Support
- The `voice-service` primary client connection path already supports TeamSpeak login, channel join, text messaging, and audio playback against TS3/TS6 servers.
- For backward compatibility, env vars still use the `TSBOT_TS3_*` naming scheme, even when connecting to TS6.
- The code still contains an optional legacy `ServerQuery` fallback used only for old-style `client_description` updates; it is not the TS6 HTTP(S) Query interface.
## Netease Support (Optional, via `NeteaseCloudMusicApi`)
This project does **not** directly call Netease official APIs. Instead, it forwards through your own `NeteaseCloudMusicApi` deployment.
- **NPM**: https://www.npmjs.com/package/NeteaseCloudMusicApi
- **Docs**: https://neteasecloudmusicapi.js.org/#/
After deployment, set `TSBOT_NETEASE_API_BASE` to the service URL (for example, `http://127.0.0.1:3000/`).
Common deployment options (choose one, exact args follow upstream docs):
```bash
# Option A: start directly with npx
npx NeteaseCloudMusicApi@latest
# Option B: use Docker (common image: binaryify/neteasecloudmusicapi)
# docker run -d --name ncm-api -p 3000:3000 binaryify/neteasecloudmusicapi
```
It is recommended to deploy this service where **backend can reach it** (same host `127.0.0.1:3000` or an internal network address).
## QQ Music Support (Built-in)
QQ Music support is provided directly by the backend; you do not need to deploy a separate QQ Music API service.
- Search, song details, playlists, lyrics, album/artist/MV information are already exposed by backend endpoints.
- Play URLs, user playlists, and other login-required features usually need an admin QQ Music cookie.
- Admins can scan a QR code in the web console, or call `/admin/qqmusic/*` APIs to store/confirm the cookie.
## Quick Start (Recommended)
### 1) Configure Environment Variables
Copy the template and edit:
```bash
cp tsbot.env.example tsbot.env
```
At minimum, set:
- `TSBOT_TS3_HOST` / `TSBOT_TS3_PORT` / `TSBOT_TS3_CHANNEL_ID` (TeamSpeak connection settings; historical `TSBOT_TS3_*` naming is retained)
- `TSBOT_COOKIE_KEY` (used to encrypt stored admin cookies; use your own random string)
Depending on music source:
- For Netease: set `TSBOT_NETEASE_API_BASE` to your `NeteaseCloudMusicApi` URL, for example `http://127.0.0.1:3000/`
- For QQ Music login-required features: store the admin QQ Music cookie via the web console or `/admin/qqmusic/*` APIs
Optional:
- `TSBOT_TS3_SERVER_PASSWORD` / `TSBOT_TS3_CHANNEL_PASSWORD` / `TSBOT_TS3_CHANNEL_PATH`
- `TSBOT_TS3_IDENTITY` / `TSBOT_TS3_IDENTITY_FILE` / `TSBOT_TS3_AVATAR_DIR`
- `TSBOT_ADMIN_TOKEN`: enable backend admin endpoint protection (request header `x-admin-token`)
- `TSBOT_WEB_HOST` / `TSBOT_WEB_PORT`: frontend production preview bind host/port (used by `run-web.sh` / `nohup-start.sh`)
- `TSBOT_WEB_API_PROXY_TARGET`: proxy target for frontend dev / preview mode (defaults to `TSBOT_HOST` / `TSBOT_PORT`)
- `TSBOT_WEB_ALLOWED_HOSTS`: comma-separated host allowlist when you access Vite dev / preview through a domain
- `VITE_DEV_HOST` / `VITE_DEV_PORT`: frontend dev server bind host/port
- `VITE_API_BASE`: frontend backend base URL (recommended default `/api`, forwarded by dev / preview / Docker reverse proxy)
### 2) Install Dependencies
Backend (Python):
```bash
cd backend
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cd ..
```
Frontend (Node):
```bash
cd web
npm install
cd ..
```
Voice service (Rust):
```bash
# Install Rust if not installed
# https://rustup.rs/
# Build voice-service
make voice-build
```
You can also use the convenience targets added to the repository:
```bash
make backend-setup
make web-build
make all
```
### 3) Foreground Startup (production-style)
Run in 3 terminals:
```bash
./run-voicemake.sh
```
```bash
./run-backend.sh
```
```bash
./run-web.sh
```
These scripts automatically read root `tsbot.env`. `run-web.sh` now builds the frontend bundle first, then serves it with `vite preview` on `TSBOT_WEB_PORT` (default `8080`).
### 4) One-Command Startup (`nohup`, recommended for remote servers)
```bash
chmod +x ./nohup-start.sh ./nohup-stop.sh ./nohup-status.sh
# Start (launches voice/backend/web and writes logs to logs/)
./nohup-start.sh
# Check status (ports + log paths)
./nohup-status.sh
# Stop
./nohup-stop.sh
```
### 5) Local Development Startup (with reload / dev server)
Run in 3 terminals:
```bash
./run-voicemake.sh
```
```bash
backend/.venv/bin/uvicorn backend.main:app --reload --reload-exclude "backend/_generated/*" --host 127.0.0.1 --port 8009
```
```bash
npm --prefix web run dev
```
Local development uses `http://127.0.0.1:5173` by default and proxies `/api` to the backend.
## Docker Deployment
The repository now includes:
- `docker-compose.yml`
- `docker-compose.prebuilt.yml`
- `Dockerfile.backend`
- `Dockerfile.voice-service`
- `Dockerfile.web`
### 1) Prepare env file
```bash
cp tsbot.env.example tsbot.env
```
If your `NeteaseCloudMusicApi` runs on the host machine, set:
- `TSBOT_NETEASE_API_BASE=http://host.docker.internal:3000/`
### 2) Build and run
```bash
docker compose up -d --build
```
### 3) Inspect
```bash
docker compose ps
docker compose logs -f backend
docker compose logs -f web
```
### 4) Stop
```bash
docker compose down
```
Compose starts 3 services by default:
- `voice-service` (`50051`)
- `backend` (`8009`)
- `web` (`8080`, Nginx serves the production frontend bundle and reverse-proxies `/api/*` to backend)
### 5) Use published images directly (Docker Hub / GHCR)
If you do not want to build locally, you can consume the prebuilt images published by GitHub Actions. The repository also ships `docker-compose.prebuilt.yml`, which pulls the official Docker Hub images by default:
```bash
# Docker Hub (default latest)
docker compose -f docker-compose.prebuilt.yml up -d
# Pin a release tag, for example v0.4.0
TSBOT_IMAGE_TAG=v0.4.0 docker compose -f docker-compose.prebuilt.yml up -d
# Switch to GHCR
TSBOT_IMAGE_REGISTRY=ghcr.io \
TSBOT_IMAGE_NAMESPACE=yichen11818 \
docker compose -f docker-compose.prebuilt.yml up -d
```
Image naming format (the Docker Hub namespace is `yumi118`; the current GitHub Packages / GHCR owner is `yichen11818`; forks can override via env vars):
- `docker.io//neteasetsbot-backend:`
- `docker.io//neteasetsbot-web:`
- `docker.io//neteasetsbot-voice-service:`
- `ghcr.io//neteasetsbot-backend:`
- `ghcr.io//neteasetsbot-web:`
- `ghcr.io//neteasetsbot-voice-service:`
Notes:
- GitHub **Packages** only shows GHCR packages, so it stays empty if you only push to Docker Hub.
- Seeing **3 image repositories** is expected because the project publishes `backend`, `web`, and `voice-service` separately.
- GitHub **Releases** also includes `tsbot--linux-amd64.tar.gz` and `SHA256SUMS.txt`; those are downloadable bundles, not container images.
## Default Ports
- **voice-service gRPC**: `127.0.0.1:50051`
- **backend**: `127.0.0.1:8009` (`TSBOT_PORT`)
- **web (production / Docker / run-web.sh)**: `127.0.0.1:8080` (`TSBOT_WEB_PORT`)
- **web (local dev server)**: `127.0.0.1:5173` (`VITE_DEV_PORT`)
Backend OpenAPI docs:
- `http://127.0.0.1:8009/docs`
## Admin Login State (Netease / QQ Music)
### Netease Cookie
Backend encrypts and stores the "admin Netease cookie" in database (`tsbot.db`) for:
- getting more stable song URLs (avoid anonymous restrictions on some endpoints)
- accessing features requiring login state (playlists, likes, etc.)
Setup APIs (if admin token is enabled, include header `x-admin-token: `):
- `POST /admin/cookie`: store cookie
- `GET /admin/status`: check if cookie exists
- `GET /admin/account`: verify cookie validity
The frontend also provides a setup UI (see `web/README.md`).
### QQ Music Cookie
Backend also encrypts and stores the "admin QQ Music cookie" in database (`tsbot.db`) for:
- getting more stable QQ Music play URLs
- accessing login-required features such as user playlists and account info
Setup APIs (if admin token is enabled, include header `x-admin-token: `):
- `GET /admin/qqmusic/status`: check if cookie exists
- `POST /admin/qqmusic/cookie`: store cookie manually
- `POST /admin/qqmusic/qr/confirm`: confirm QR login from the web UI and persist the cookie
The web console includes a QQ Music QR login flow.
## Logging
Logs are written to `logs/` by default:
- `logs/backend.log`
- `logs/voice.log`
- `logs/web.log`
See `LOGGING.md` for details (`scripts/log-viewer.sh` / `scripts/unified-logger.sh`).
## Project Structure
```text
.
├── backend/ # FastAPI backend
├── web/ # Vue3 frontend
├── voice-service/ # Rust voice service (gRPC + TeamSpeak)
├── proto/ # gRPC proto definitions
├── data/ # runtime data/config (e.g. config.json)
├── logs/ # runtime logs (created by startup scripts)
├── HOWTOSTART.md
├── LOGGING.md
└── tsbot.env.example
```
## FAQ
- **Is the web port 5173 or 8080?**
- `5173` is the local Vite dev server (`npm --prefix web run dev` / `VITE_DEV_PORT`)
- `8080` is the production foreground and Docker default (`run-web.sh` / `nohup-start.sh` / `TSBOT_WEB_PORT`)
- **Frontend request errors / cannot reach backend?**
- Recommended default is `VITE_API_BASE=/api`, which is reverse-proxied by dev server / preview / Docker Nginx to backend
- If you do not use same-origin proxying, set `VITE_API_BASE` explicitly or point `TSBOT_WEB_API_PROXY_TARGET` at the backend
- **Seeing a Vite host security error when accessing via domain?**
- That is Vite host validation working as designed.
- Set `TSBOT_WEB_ALLOWED_HOSTS="dev.example.com,.example.com"` in `tsbot.env` and only whitelist the domains you really need.
- **Backend cannot reach voice-service?**
- Check `TSBOT_VOICE_GRPC_ADDR` is `127.0.0.1:50051`
- Ensure `make voice-run` or `run-voicemake.sh` is running
- **Is TS6 fully supported?**
- The primary client connection already supports TS6, while configuration still uses the historical `TSBOT_TS3_*` names.
- Legacy `TSBOT_TS3_SERVERQUERY_*` settings still map to the old ServerQuery fallback, not TS6 HTTP(S) Query.
## License
See `LICENSE`.