REST API и Web Query TeamSpeak 6: подключение, API-ключи, примеры
Как включить транспорты SSH/HTTP/HTTPS в TeamSpeak 6, создать API-ключ с ограниченными правами вместо пароля ServerAdmin, и обращаться к серверу через curl и Python requests.
TeamSpeak 6 убрал классический telnet-протокол ServerQuery и заменил его набором транспортов поверх SSH и HTTP(S), плюс добавил API-ключи с ограниченными правами вместо единого пароля serveradmin. По сути это тот же язык команд, что и в TeamSpeak 3 ServerQuery, но доставленный по-другому и с более гибкой моделью доступа. Проблема в том, что схема ещё в бете и меняется от сборки к сборке - часть деталей эндпоинтов не задокументирована стабильно даже на официальном форуме сообщества. В этой статье - как включить транспорты, создать ограниченный API-ключ, и как обращаться к серверу через curl и Python на подтверждённых базовых примерах, с честными оговорками там, где схема ещё нестабильна.
Транспорты: SSH, HTTP, HTTPS
TS6 предлагает три способа подключиться к query-интерфейсу сервера, и все три включаются и настраиваются раздельно:
| Транспорт | Флаг включения | Переменная окружения | Флаг порта |
|---|---|---|---|
| SSH-query | --query-ssh-enable | TSSERVER_QUERY_SSH_ENABLED | --query-ssh-port |
| HTTP web-query | --query-http-enable | TSSERVER_QUERY_HTTP_ENABLED | --query-http-port |
| HTTPS web-query | --query-https-enable | TSSERVER_QUERY_HTTPS_ENABLED | --query-https-port |
Официальные представители проекта на форуме community.teamspeak.com подтверждали, что “запрос со всеми командами, знакомыми по серверам TeamSpeak 3, всё ещё доступен” через SSH и HTTP/HTTPS - именно эти два семейства транспортов заменили голый telnet. По умолчанию используются порты, унаследованные от WebQuery TeamSpeak 3: 10022 для SSH-query, 10080 для HTTP и 10443 для HTTPS - но проверяйте актуальные значения через --help вашей сборки, так как порты по умолчанию могут отличаться от версии к версии.
Включить нужный транспорт можно и в Docker-запуске через переменные окружения:
docker run -d \
--name teamspeak-server \
-p 9987:9987/udp \
-p 10022:10022 \
-p 10080:10080 \
-e TSSERVER_LICENSE_ACCEPTED=accept \
-e TSSERVER_QUERY_SSH_ENABLED=true \
-e TSSERVER_QUERY_HTTP_ENABLED=true \
-v teamspeak-data:/var/tsserver/ \
teamspeaksystems/teamspeak6-server:latest
В продакшне HTTPS-транспорт предпочтительнее HTTP - подробности в разделе про безопасность ниже.
Аутентификация: API-ключи вместо пароля serveradmin
Базовый доступ к query-интерфейсу по-прежнему завязан на аккаунт ServerAdmin (в TS3 - serveradmin), учётные данные которого выдаются или генерируются при первом запуске сервера - подробно об этом в статье про установку TeamSpeak 6. Но для интеграций и ботов TS6 предлагает более гибкий механизм - API-ключи с ограниченным scope и временем жизни, создаваемые изнутри уже открытой query-сессии под ServerAdmin.
Судя по обсуждениям на официальном форуме сообщества, ключ создаётся командой вида:
apikeyadd scope=manage lifetime=0
где scope определяет уровень доступа ключа, а lifetime - время жизни в секундах (значение по умолчанию/бессрочное поведение стоит уточнять в справке вашей сборки). Это подтверждённый факт существования такой команды, но не гарантированно стабильный синтаксис - разработчик проекта прямо говорил на форуме, что в TS6 “нет API в классическом смысле, а есть учётные записи, которые могут подключаться к серверу и использоваться для мониторинга или управления” - то есть API-ключ по сути создаёт ограниченную query-учётку, а не токен в отрыве от концепции пользователя. Перед использованием в проде сверьте точный синтаксис и доступные значения scope с doc/webquery.md внутри вашего дистрибутива сервера или с --help.
Полученный ключ передаётся в HTTP/HTTPS-запросах заголовком:
x-api-key: ВАШ_КЛЮЧ
Базовая структура запросов
Схема эндпоинтов всё ещё меняется между бета-сборками, поэтому не переносите слепо примеры из статей, написанных под другую версию - в разных источниках встречаются варианты путей вида /whoami, /1/clientlist, /version, где префикс версии API (1, v1 или отсутствие префикса вовсе) отличается от сборки к сборке. Общий подход стабилен: HTTP-запрос на порт web-query, заголовок с API-ключом, ответ в JSON. Актуальный список доступных путей для вашей установки правильнее всего смотреть в поставляемом файле документации (doc/webquery.md) или, если ваша сборка его поднимает, в Swagger-интерфейсе на том же HTTP-порту.
Проверочный запрос, чтобы убедиться, что ключ и транспорт работают - обычно это будет что-то вроде опроса собственной идентичности ключа:
curl -H "x-api-key: ВАШ_КЛЮЧ" "http://ваш-сервер:10080/whoami"
Если получаете JSON-ответ с данными о текущей query-сессии, а не ошибку 401/403 - транспорт и ключ настроены верно, и дальше можно переходить к прикладным командам.
Pterohost - серверы TeamSpeak 6 с открытыми query-портами и настроенным firewall из коробки, не нужно поднимать транспорты вручную. Промокод 4START даёт -20% на первый заказ. Арендовать TeamSpeak 6
Примеры на curl
Список подключённых клиентов (путь и версия префикса зависят от сборки - в примере используется распространённый в обсуждениях сообщества вариант):
curl -H "x-api-key: ВАШ_КЛЮЧ" \
"http://ваш-сервер:10080/1/clientlist"
Кик клиента (структура тела запроса - обобщённый пример, сверяйте точные имена полей с документацией вашей сборки):
curl -X POST \
-H "x-api-key: ВАШ_КЛЮЧ" \
-H "Content-Type: application/json" \
-d '{"clid": 12, "reason": "Нарушение правил"}' \
"http://ваш-сервер:10080/1/clientkick"
Бан по IP или уникальному идентификатору клиента следует той же логике - POST-запрос с JSON-телом на соответствующий путь. Прежде чем использовать команды бана/кика в продакшне, обязательно протестируйте их на тестовом сервере той же версии, что и продакшн - синтаксис полей мог измениться в последней бете.
Примеры на Python requests
Минимальный клиент для получения списка клиентов и отправки сообщения в канал:
import requests
BASE_URL = "http://ваш-сервер:10080"
API_KEY = "ВАШ_КЛЮЧ"
HEADERS = {"x-api-key": API_KEY}
def get_clients():
resp = requests.get(f"{BASE_URL}/1/clientlist", headers=HEADERS, timeout=5)
resp.raise_for_status()
return resp.json()
def kick_client(clid: int, reason: str):
payload = {"clid": clid, "reason": reason}
resp = requests.post(
f"{BASE_URL}/1/clientkick",
headers=HEADERS,
json=payload,
timeout=5,
)
resp.raise_for_status()
return resp.json()
def send_channel_message(cid: int, text: str):
payload = {"cid": cid, "msg": text}
resp = requests.post(
f"{BASE_URL}/1/sendtextmessage",
headers=HEADERS,
json=payload,
timeout=5,
)
resp.raise_for_status()
return resp.json()
if __name__ == "__main__":
clients = get_clients()
print(f"Подключено клиентов: {len(clients)}")
Точные имена путей и полей в примерах выше (clid, cid, msg, /1/clientkick, /1/sendtextmessage) даны по аналогии с известной структурой команд ServerQuery TS3 и упоминаниями в обсуждениях сообщества TS6 - перед использованием в проде обязательно сверьте их с документацией установленной у вас версии сервера. Такая осторожность оправдана: между бета-сборками уже менялась обработка прав и структура ответов клиентского списка, значит могли поменяться и поля запросов.
Обработка ошибок
По подтверждённым сведениям с официального форума, REST API TS6 возвращает стандартные HTTP-коды состояния:
| Код | Причина | Что делать |
|---|---|---|
| 401 | Неверный или истёкший API-ключ | Проверить значение ключа, пересоздать через query-сессию |
| 403 | Недостаточно прав у ключа | Проверить scope ключа, создать новый с нужным уровнем доступа |
| 404 | Несуществующий путь или версия API | Свериться с doc/webquery.md вашей сборки |
| 500 | Внутренняя ошибка сервера | Смотреть логи сервера, возможен баг конкретной беты |
Оборачивайте вызовы в try/except с проверкой статус-кода (в примере Python это делает raise_for_status()) и логируйте полное тело ответа при ошибке - в бета-версии полезно сохранять сырые ответы сервера, чтобы позже понять, была ли проблема в вашем коде или в баге конкретной сборки.
Безопасность: как не слить доступ к серверу
REST API даёт управление сервером не хуже полного пароля serveradmin, если выдать ключу широкий scope - относитесь к нему соответственно.
- Не публикуйте ключ в открытом виде. Не коммитьте его в git, не передавайте в URL (только в заголовке), не логируйте целиком на проде.
- Используйте HTTPS-транспорт вместо HTTP в продакшне - HTTP передаёт заголовок с ключом в открытом виде, и его можно перехватить на пути между вашим кодом и сервером.
- Ограничивайте доступ к query-портам по IP через firewall - если бот или скрипт обращается к API с известного статического адреса, не открывайте порт 10080/10443/10022 всему интернету. Базовые правила для игровых серверов разобраны в статье про firewall UFW.
- Выдавайте ключам минимальный scope под конкретную задачу - боту для логирования онлайна не нужны права на управление правами и удаление каналов.
- Ограничивайте время жизни ключа, если сценарий это позволяет, вместо бессрочных ключей на всё - в бете, где схема ещё меняется, скомпрометированный бессрочный ключ с широким доступом - больший риск, чем в стабильном протоколе.
Pterohost - серверы TeamSpeak 6 с NVMe и DDoS-защитой Guard Rise, готовые под интеграции через REST API. Промокод 4START даёт -20% на первый заказ. Заказать TeamSpeak 6
Часто задаваемые вопросы
Чем REST API / Web Query TeamSpeak 6 отличается от ServerQuery TeamSpeak 3?
Набор команд похож, но транспорт другой: TS3 использует сырой telnet-протокол на порту 10011, а TS6 убрал telnet и открывает тот же функционал через SSH-query и HTTP/HTTPS web-query. Дополнительно TS6 добавляет API-ключи с ограниченным набором прав вместо единого пароля serveradmin.
Как создать API-ключ в TeamSpeak 6?
Ключ создаётся через query-сессию (SSH или HTTP) под учётной записью ServerAdmin командой генерации ключа с параметрами области действия и времени жизни, например apikeyadd scope=manage lifetime=0. Точный синтаксис команды может отличаться между бета-сборками - сверяйтесь с doc/webquery.md вашей версии сервера.
Какой порт использует REST API / Web Query TeamSpeak 6?
По умолчанию HTTP web-query слушает порт 10080, HTTPS - 10443, а SSH-query - 10022, это те же порты, что исторически использовались под WebQuery в TeamSpeak 3. Транспорты включаются раздельно флагами —query-http-enable, —query-https-enable и —query-ssh-enable или соответствующими переменными окружения, и порты в конкретной сборке стоит проверять через —help.
Безопасно ли открывать REST API TeamSpeak 6 в интернет?
Не рекомендуется без ограничений. HTTP-транспорт передаёт API-ключ в открытом виде - используйте HTTPS в проде, ограничивайте доступ к query-портам через firewall по IP доверенных систем, и выдавайте ключам минимально необходимый scope вместо полного доступа.
Можно ли получить полную документацию по эндпоинтам REST API TeamSpeak 6?
Официальная документация неполная и меняется вместе с бета-сборками: она поставляется файлом doc/webquery.md внутри дистрибутива сервера, часть версий также поднимает Swagger-интерфейс на HTTP-порту. Точные пути эндпоинтов лучше проверять именно в файлах вашей установленной версии, а не в сторонних гайдах, написанных под другую сборку.