Bothost API Reference
Документация по API для разработчиков ботов на платформе Bothost.Содержание
Переменные окружения
Каждый бот получает следующие переменные окружения:Основные переменные
| Переменная | Описание | Пример |
|---|---|---|
BOT_ID | Уникальный ID бота | bot_1764482446_5595_proxyrp |
BOT_TOKEN | Токен бота (основной) | 8424863414:AAF1Plz... |
USER_ID | ID пользователя (владельца) | username123 |
DOMAIN | Доменное имя бота (если назначено) | mybot.bothost.ru |
TEMPLATE | Шаблон бота | discord, telegram, n8n |
PORT | Внутренний порт | 3000 |
Токены (для совместимости)
Для разных библиотек доступны альтернативные имена:BOT_TOKEN- основной (рекомендуется)DISCORD_TOKEN/DISCORD_BOT_TOKEN- для Discord ботовTELEGRAM_BOT_TOKEN- для Telegram ботовTOKEN- универсальное имяAPI_TOKEN- альтернативное имя
Как получить переменные в коде
Python:import os
BOT_ID = os.getenv('BOT_ID')
BOT_TOKEN = os.getenv('BOT_TOKEN')
if not BOT_TOKEN:
print("❌ Токен не найден!")
exit(1)const BOT_ID = process.env.BOT_ID;
const BOT_TOKEN = process.env.BOT_TOKEN;
if (!BOT_TOKEN) {
console.error('❌ Токен не найден!');
process.exit(1);
}API для управления ботом
⚠️ Важно: Безопасность
API агента доступен только из внутренней сети Docker. Бот может управлять только самим собой, используя свойBOT_ID.
Базовый URL
API агента доступен по адресу:- Из контейнера бота:
http://agent:8000(внутренняя сеть Docker) - Извне:
http://agent.bothost.ruилиhttp://msk1.bothost.ru(зависит от ноды)
Endpoints
#### 1. Перезапуск бота (самоперезапуск) ⭐ Рекомендуется Endpoint:POST /api/bots/self/restart
Описание: Безопасный endpoint для самоперезапуска бота. Бот может перезапустить только сам себя.
Заголовки:
X-Bot-ID: bot_1764482446_5595_proxyrpBOT_ID из имени контейнера.
Запрос:
POST /api/bots/self/restart
X-Bot-ID: bot_1764482446_5595_proxyrp{
"ok": true,
"message": "Бот bot_1764482446_5595_proxyrp перезапущен"
}{
"ok": false,
"msg": "BOT_ID не найден. Передайте его в заголовке X-Bot-ID"
}import os
import aiohttp
BOT_ID = os.getenv('BOT_ID')
AGENT_URL = os.getenv('BOTHOST_AGENT_URL', 'http://agent:8000')
async with aiohttp.ClientSession() as session:
async with session.post(
f"{AGENT_URL}/api/bots/self/restart",
headers={'X-Bot-ID': BOT_ID}
) as response:
result = await response.json()
print(result)POST /api/bots/restart
Описание: Перезапускает контейнер бота (требует bot_id и user_id).
Запрос:
{
"bot_id": "bot_1764482446_5595_proxyrp",
"user_id": "username123"
}{
"ok": true,
"message": "Бот bot_1764482446_5595_proxyrp перезапущен"
}{
"ok": false,
"msg": "Ошибка перезапуска бота: ..."
}POST /api/bots/stop
Запрос:
{
"bot_id": "bot_1764482446_5595_proxyrp",
"user_id": "username123"
}POST /api/bots/start
Запрос:
{
"bot_id": "bot_1764482446_5595_proxyrp",
"user_id": "username123"
}POST /api/bots/logs
Запрос:
{
"bot_id": "bot_1764482446_5595_proxyrp",
"lines": 100
}{
"ok": true,
"logs": "Логи бота..."
}GET /api/bots/{bot_id}/stats
Ответ:
{
"ok": true,
"stats": {
"cpu_percent": 15.5,
"memory_usage": "125MB",
"memory_percent": 12.3,
"uptime": "2h 30m"
}
}Примеры использования
Python (discord.py) - Перезапуск бота
import os
import aiohttp
import discord
from discord.ext import commands
BOT_ID = os.getenv('BOT_ID')
AGENT_URL = os.getenv('BOTHOST_AGENT_URL', 'http://agent:8000')
USER_ID = os.getenv('USER_ID')
bot = commands.Bot(command_prefix='!', intents=discord.Intents.default())
@bot.command(name='restart')
async def restart_command(ctx):
"""Перезапустить бота через API"""
if not BOT_ID:
await ctx.send("❌ BOT_ID не найден в переменных окружения")
return
async with aiohttp.ClientSession() as session:
try:
async with session.post(
f"{AGENT_URL}/api/bots/restart",
json={
"bot_id": BOT_ID,
"user_id": USER_ID
},
timeout=aiohttp.ClientTimeout(total=10)
) as response:
result = await response.json()
if result.get('ok'):
await ctx.send(f"✅ {result.get('message', 'Бот перезапущен')}")
else:
await ctx.send(f"❌ Ошибка: {result.get('msg', 'Неизвестная ошибка')}")
except Exception as e:
await ctx.send(f"❌ Ошибка подключения к API: {str(e)}")
bot.run(os.getenv('BOT_TOKEN'))Python (aiogram) - Перезапуск бота
import os
import aiohttp
from aiogram import Bot, Dispatcher, types
from aiogram.filters import Command
BOT_ID = os.getenv('BOT_ID')
AGENT_URL = os.getenv('BOTHOST_AGENT_URL', 'http://agent:8000')
USER_ID = os.getenv('USER_ID')
bot = Bot(token=os.getenv('BOT_TOKEN'))
dp = Dispatcher()
@dp.message(Command("restart"))
async def restart_command(message: types.Message):
"""Перезапустить бота через API"""
if not BOT_ID:
await message.answer("❌ BOT_ID не найден")
return
async with aiohttp.ClientSession() as session:
try:
async with session.post(
f"{AGENT_URL}/api/bots/restart",
json={"bot_id": BOT_ID, "user_id": USER_ID},
timeout=aiohttp.ClientTimeout(total=10)
) as response:
result = await response.json()
if result.get('ok'):
await message.answer(f"✅ {result.get('message')}")
else:
await message.answer(f"❌ {result.get('msg')}")
except Exception as e:
await message.answer(f"❌ Ошибка: {str(e)}")
if __name__ == '__main__':
import asyncio
asyncio.run(dp.start_polling(bot))Node.js (discord.js) - Перезапуск бота
const { Client, GatewayIntentBits } = require('discord.js');
const axios = require('axios');
const BOT_ID = process.env.BOT_ID;
const AGENT_URL = process.env.BOTHOST_AGENT_URL || 'http://agent:8000';
const USER_ID = process.env.USER_ID;
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
client.on('ready', () => {
console.log(✅ Бот ${client.user.tag} запущен!);
});
client.on('messageCreate', async (message) => {
if (message.content === '!restart') {
if (!BOT_ID) {
return message.reply('❌ BOT_ID не найден');
}
try {
const response = await axios.post(
${AGENT_URL}/api/bots/restart,
{
bot_id: BOT_ID,
user_id: USER_ID
},
{ timeout: 10000 }
);
if (response.data.ok) {
message.reply(✅ ${response.data.message});
} else {
message.reply(❌ ${response.data.msg});
}
} catch (error) {
message.reply(❌ Ошибка: ${error.message});
}
}
});
client.login(process.env.BOT_TOKEN);Определение URL агента
Автоматическое определение
Бот может автоматически определить URL агента: Python:import os
import socket
def get_agent_url():
"""Определяет URL агента автоматически"""
# Пробуем подключиться к внутренней сети Docker
try:
socket.create_connection(('agent', 8000), timeout=1)
return 'http://agent:8000'
except:
# Fallback на внешний URL
return os.getenv('BOTHOST_AGENT_URL', 'http://agent.bothost.ru')Через переменную окружения
Можно установить переменнуюBOTHOST_AGENT_URL в настройках бота:
http://agent:8000- для внутренней сети Docker (рекомендуется)http://agent.bothost.ru- для внешнего доступаhttp://msk1.bothost.ru- для второй ноды
Обработка ошибок
Типичные ошибки
- Контейнер не найден
json
{"ok": false, "msg": "Контейнер не найден"}
`
Решение: Убедитесь, что бот запущен
- Таймаут
`json
{"ok": false, "msg": "Таймаут при перезапуске"}
`
Решение: Увеличьте timeout или повторите запрос
- Ошибка подключения
- Проверьте доступность агента
- Убедитесь, что используете правильный URL
- Проверьте сетевые настройки Docker
Безопасность
⚠️ Важные моменты
- Бот может управлять только самим собой
- Используйте BOT_ID из переменных окружения
- Не передавайте чужие bot_id в запросах
- Внутренняя сеть Docker
- API доступен только из контейнеров
- Внешний доступ ограничен
- Валидация
- Всегда проверяйте наличие BOT_ID` перед вызовом API
- Обрабатывайте ошибки корректно
Дополнительные ресурсы
Версия документации: 1.0 Последнее обновление: 2025-01-XX