AFK Bot — auto-move idle users to AFK channel (SSH ServerQuery, systemd)

Hi everyone,

I’d like to share a small open-source bot I put together for TeamSpeak 6:
TS6 AFK Bot. It automatically moves idle users to a separate AFK channel
and works entirely over SSH ServerQuery — no client-side plugins required.

What it does

  • Connects to the TS6 ServerQuery over SSH (default port 10022).
  • Moves users to the AFK channel after a configurable idle threshold.
  • Optionally sends a poke message before moving.
  • Supports exclusions by client_unique_identifier and by channel.
  • Automatically reconnects if the SSH connection drops.
  • Graceful shutdown on Ctrl+C / SIGTERM in under 0.5 seconds.
  • Uses a single clientlist -uid -times query per tick instead of N+1
    clientinfo calls — matters when you have a few dozen users online.

Requirements

  • Python 3.10+
  • paramiko >= 3.4
  • On the TS6 server: SSH ServerQuery enabled (port 10022 by default) and a
    query account with b_client_move_power and i_client_poke_power.

Installation

The repo ships with an automated installer for Linux (install.py) that
takes care of everything: checks dependencies, creates a system user, clones
the repo, sets up a venv, generates config.json and a hardened systemd
unit, then starts the service.

sudo python3 install.py

It will ask a few questions (server address, ServerQuery port, query login
and password, virtual server id, AFK channel id, etc.). Most fields have
sensible defaults — just hit Enter.

There’s also a non-interactive mode for automation:

sudo python3 install.py --non-interactive \
  --host ts.example.com \
  --query-port 10022 \
  --username bot \
  --password 'SuperSecret' \
  --virtual-server-id 1 \
  --afk-channel-id 12 \
  --timeout-seconds 300 \
  --check-interval 30 \
  --reconnect-delay 10 \
  --poke-message 'You were moved to AFK due to inactivity.'

After installation the bot runs as a systemd service:

systemctl status ts6-afk-bot
journalctl -u ts6-afk-bot -f

Manual installation (venv + systemd unit) is also documented in the README.

Configuration

host              string    TS6 server address
query_port        int       SSH ServerQuery port (usually 10022)
username          string    query account login
password          string    query account password
virtual_server_id int       sid of the virtual server (usually 1)
afk_channel_id    int       cid of the AFK channel
timeout_seconds   int       idle threshold in seconds (default 300)
check_interval    int       polling interval in seconds (default 30)
reconnect_delay   int       pause before reconnect (default 10)
poke_message      string    poke text; empty = don't send
exclude_uids      string[]  UIDs to skip
exclude_channels  int[]     cids to skip

For security the installer keeps the password out of config.json and
stores it in /etc/ts6-afk-bot/env (chmod 600), where it is read via
TS6_QUERY_PASSWORD.

Links

Feedback

I’d love to hear whether this works on your setups, and whether there’s
interest in additional features — for example:

  • Auto-creating the AFK channel if it doesn’t exist.
  • Moving users back to their previous channel when they become active again.
  • Web UI or Prometheus metrics for monitoring.

Bug reports and PRs are welcome. Thanks for reading!

1 Like

Hey, nice little project. I had a look at the repo and I actually like that it stays pretty simple instead of trying to do too much at once.

A few things came to mind while looking through it though.

One thing I’d really like is a proper warning before the user gets moved. At the moment the poke happens after the move, so maybe something like “You’ll be moved to AFK in 60 seconds” would be nicer. If the user becomes active again during that time, the move could just be cancelled.

It would also be really useful if the bot could remember which channel someone was in before being moved to AFK and optionally move them back once they’re active again.

Server group exclusions would be nice too. That way you could just exclude admins, bots or certain staff groups instead of adding every UID manually.

Maybe later on you could also add different AFK times depending on the channel or server group. For example, shorter in the lobby and longer in gaming channels.