Skip to content

Stubson/LINGROBOT

Repository files navigation

LINGROBOT

Modular TeamSpeak Server Query bot. Currently includes automatic private channel creation and inactive channel/client cleanup, with more modules planned.

Acknowledgments

Developed with assistance from Claude (Anthropic).

Features

  • Automatic private channel creation when a user joins a lobby channel
  • Persistent channel ownership across restarts (MariaDB)
  • Flexible channel placement (subchannel, root level, sorted after another channel)
  • Per-lobby configuration — multiple lobbies supported
  • Optional group restriction per lobby
  • Automatic cleanup of channels inactive for X days
  • Optional cleanup of inactive client database entries
  • Automatic reconnect with exponential backoff
  • Structured logging (console + file)
  • Graceful shutdown (SIGINT / SIGTERM)
  • Modular architecture — add new features without touching existing code

Requirements

  • Node.js >= 24
  • A running TeamSpeak 3 server with Server Query enabled
  • A MariaDB or MySQL server
  • A Server Query login

Installation

git clone <this-repo>
cd ts3-bot
npm install

Database setup

mysql -u root -p < schema.sql

Or manually:

CREATE DATABASE ts3bot CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'ts3bot'@'localhost' IDENTIFIED BY 'your_password';
GRANT ALL PRIVILEGES ON ts3bot.* TO 'ts3bot'@'localhost';
FLUSH PRIVILEGES;

Configuration

cp config.example.js config.js

Edit config.js with your TS3 and database credentials. All available options are documented inline.

mkdir logs
npm start

Configuration Reference

Section Purpose
host, queryPort, serverId, username, password Server Query connection
db MariaDB connection details
lobbies[] One entry per lobby channel that triggers private channel creation
cleaner.channel Auto-delete bot-created channels inactive for X days
cleaner.client Auto-delete inactive entries from the TS3 client database (disabled by default)

Lobby options

Field Description
channelId The lobby channel that triggers creation
channelNameTemplate Name template, %c is replaced with the client's nickname
subchannel true = create under parentChannelId, false = root level
sortAfter / sortAfterId Sort the new channel after a specific channel ID
adminGroupId Channel group assigned to the channel owner
channelType permanent | semipermanent | temporary
restrictToGroups Server group IDs allowed to use this lobby (empty = everyone)

Project Structure

src/
├── index.js              # Entry point — connects, loads modules
├── lib/
│   ├── db.js              # MariaDB connection pool
│   └── logger.js          # Shared logger (winston)
└── modules/
    ├── channels.js         # Private channel creation & persistence
    └── cleaner.js          # Inactive channel/client cleanup
config.example.js          # Configuration template
schema.sql                 # Initial database schema

Adding a New Module

Each module exports a register(ts3, db) function that receives the connected TeamSpeak client and the MariaDB pool, and sets up its own event listeners.

// src/modules/example.js
async function register(ts3, db) {
  ts3.on("clientmoved", (evArr) => {
    const ev = Array.isArray(evArr) ? evArr[0] : evArr;
    // your logic here
  });
}

module.exports = { register };

Then add it to the module list in src/index.js:

const modules = [
  require("./modules/channels.js"),
  require("./modules/cleaner.js"),
  require("./modules/example.js"), // ← new module
];

Note on event names: node-ts strips the notify prefix from TS3 server notifications but keeps everything else, e.g. the server sends notifyclientmoved and the library emits it as clientmoved — with the payload wrapped in an array. Always unwrap with Array.isArray(ev) ? ev[0] : ev before reading properties.

Running as a systemd service

# /etc/systemd/system/ts3bot.service
[Unit]
Description=TS3 Bot
After=network.target

[Service]
Type=simple
User=ts3bot
WorkingDirectory=/opt/ts3bot
ExecStart=/usr/bin/node src/index.js
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now ts3bot
sudo journalctl -u ts3bot -f

Logs

  • logs/combined.log — all log entries (JSON)
  • logs/error.log — errors only (JSON)
  • Console — colorized output

Log level is set in config.js: error | warn | info | debug

License

MIT

About

Modular TeamSpeak Server Query bot

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors