Короткий ответ: виджет для игрового бота лучше делать как маленький веб-интерфейс: Node.js-сервер получает данные от бота, отдает их через API, а на странице виджет показывает статус, онлайн, последнюю активность или игровые события. Если данные должны обновляться без перезагрузки, добавьте WebSocket через Socket.IO
Под “виджетом” могут иметь в виду разные вещи: блок на сайте, панель статуса для Discord-бота, мини-окно с игровой статистикой, оверлей для стрима или карточку сервера. Поэтому начнем с универсальной схемы, которую можно адаптировать под конкретную игру и платформу
Архитектура простого виджета
Минимальная схема такая
игровой бот -> Node.js сервер -> /api/widget -> HTML-виджет в браузере
Бот или модуль бота хранит состояние: онлайн, ник, текущую игру, счет, последнюю команду, количество игроков. Express отдает это состояние через API, а браузер забирает JSON и рисует карточку
Создайте проект
mkdir game-bot-widget
cd game-bot-widget
npm init -y
npm install express
Структура
game-bot-widget/
public/
widget.html
server.js
Сервер Express с API виджета
Файл server.js
const express = require("express");
const path = require("path");
const app = express();
const botState = {
name: "ArenaBot",
online: true,
game: "Duel Arena",
playersOnline: 18,
lastEvent: "Игрок Dinar выиграл матч"
};
app.use(express.static(path.join(__dirname, "public")));
app.get("/api/widget", (req, res) => {
res.json(botState);
});
app.listen(3000, () => {
console.log("Виджет запущен: http://localhost:3000/widget.html");
});
Запуск
node server.js
Откройте
http://localhost:3000/api/widget
Если видите JSON, серверная часть готова
HTML-виджет
Файл public/widget.html
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<title>Виджет игрового бота</title>
<style>
body {
margin: 0;
font-family: Arial, sans-serif;
background: #0f172a;
color: #e5e7eb;
}
.widget {
width: 320px;
padding: 20px;
border: 1px solid #334155;
background: #111827;
border-radius: 12px;
}
.status {
display: inline-block;
margin-bottom: 12px;
padding: 4px 10px;
border-radius: 999px;
background: #14532d;
color: #bbf7d0;
font-size: 14px;
}
</style>
</head>
<body>
<div class="widget">
<div id="status" class="status">загрузка</div>
<h1 id="name">Бот</h1>
<p id="game"></p>
<p id="players"></p>
<p id="event"></p>
</div>
<script>
async function loadWidget() {
const response = await fetch("/api/widget");
const data = await response.json();
document.getElementById("status").textContent = data.online ? "онлайн" : "офлайн";
document.getElementById("name").textContent = data.name;
document.getElementById("game").textContent = `Игра: ${data.game}`;
document.getElementById("players").textContent = `Игроков онлайн: ${data.playersOnline}`;
document.getElementById("event").textContent = data.lastEvent;
}
loadWidget();
</script>
</body>
</html>
Это уже рабочий виджет: он берет данные с Node.js-сервера и показывает их в браузере
Как подключить реальные данные бота
Вместо объекта botState обычно делают отдельный модуль
const state = {
name: "ArenaBot",
online: false,
game: null,
playersOnline: 0,
lastEvent: "Бот запускается"
};
function updateState(patch) {
Object.assign(state, patch);
}
function getState() {
return state;
}
module.exports = {
updateState,
getState
};
Бот обновляет состояние через updateState, а Express-роут возвращает getState(). Так виджет не должен напрямую лезть во внутренний код бота
Если нужны обновления в реальном времени
Для живого виджета используйте Socket.IO
npm install socket.io
Серверная идея такая: когда бот получает новое событие, Node.js отправляет его всем подключенным браузерам
const http = require("http");
const express = require("express");
const { Server } = require("socket.io");
const app = express();
const server = http.createServer(app);
const io = new Server(server);
function publishBotEvent(event) {
io.emit("bot:event", event);
}
server.listen(3000);
На клиенте
<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io();
socket.on("bot:event", (event) => {
document.getElementById("event").textContent = event.message;
});
</script>
Так виджет может обновляться сразу после события, без постоянного опроса API
Что обязательно продумать
Не отдавайте в виджет токены бота, приватные ID, внутренние ошибки, ключи API и админские команды. Виджет работает в браузере, а все, что попало в браузер, пользователь может посмотреть
Если виджет будет встроен на другой сайт, настройте CORS осознанно. Не открывайте API на все домены, если данные не публичные
Мини-практика
Сначала сделайте статический виджет с /api/widget. Затем добавьте кнопку или таймер на сервере, который меняет playersOnline, и обновляйте виджет раз в 5 секунд через fetch. Только после этого переходите к Socket.IO
Так проще отладить модель данных и внешний вид, не смешивая все сразу
Частые ошибки
Пытаются рисовать виджет прямо из кода бота Лучше разделить: бот собирает события, сервер отдает API, браузер рисует интерфейс
Отдают секреты в JSON Виджет должен получать только публичные данные
Сразу подключают WebSocket без простой версии Сначала сделайте обычный /api/widget, потом добавляйте real-time
Не думают про встраивание на сайт Если виджет будет вставляться на чужую страницу, заранее продумайте размеры, CORS, стили и изоляцию CSS
Что почитать дальше по Node.js
Если нужен общий маршрут по теме, откройте рубрику Node.js. Для соседних задач пригодятся эти разборы:
- Node.js + MongoDB: первая коллекция из приложения
- Node.js + MySQL: REST API для первых данных
- Node.js LTS: какую версию ставить новичку
- Node.js выводит странные имена файлов: как исправить кодировку и пути



