Вы арендовали VPS (VPS — виртуальный сервер в дата-центре, к которому вы подключаетесь по SSH) и узнаёте о проблемах поздно: сайт лёг, диск переполнился, память кончилась — а вы об этом узнаёте от клиентов или вообще случайно. Этот гайд решает задачу так: скрипт на сервере собирает метрики, Telegram-бот присылает алерты в чат, а Mini App (Mini App — веб-страница, которая открывается прямо внутри Telegram по кнопке меню) показывает дашборд со свежими цифрами. Подходит для Linux-серверов (Ubuntu/Debian и аналоги) с доступом root или sudo, для новичка без опыта в мониторинге.


1. Подключитесь к серверу по SSH и обновите пакеты.
ssh root@203.0.113.10
apt update && apt install -y python3 python3-pip
Почему это работает: SSH даёт вам командную строку удалённой машины, а `apt update` подтягивает свежие списки пакетов, иначе установка может упасть на устаревших ссылках.
Пример:после ввода пароля приглашение меняется на `root@vps:~#` — это ожидаемый результат.
2. Создайте бота в @BotFather и получите токен.
Откройте Telegram, напишите @BotFather команду `/newbot`, задайте имя и username (обязательно заканчивается на `bot`). В ответ придёт строка с токеном.
Пример:BotFather отвечает `Use this token to access the HTTP API: 123456789:AAExampleTokenFromBotFather`. Проверьте токен командой `curl -s "https://api.telegram.org/bot<TOKEN>/getMe"` — ожидаемый вывод `{"ok":true,"result":{"id":123456789,"username":"my_monitor_bot"}}`.
3. Установите библиотеки для метрик и HTTP-запросов.
pip3 install psutil requests
Почему это работает: `psutil` читает нагрузку, память и диск из системных файлов, а `requests` отправляет HTTP-запрос в Telegram Bot API. Ожидаемый результат — строка `Successfully installed psutil-... requests-...`. Если планируете держать на том же сервере дополнительные self-hosted-сервисы, посмотрите как подключить ИИ к домашнему серверу — там разобрана логика установки и изоляции сервисов.
4. Напишите скрипт сбора метрик и сохраните его в `/opt/monitor/check.py`.
import psutil, requests
TOKEN = "123456789:AAExampleTokenFromBotFather"
CHAT_ID = "123456789"
load = psutil.getloadavg()[0]
disk = psutil.disk_usage("/").percent
mem = psutil.virtual_memory().percent
if disk > 85 or mem > 90:
requests.post(
f"https://api.telegram.org/bot{TOKEN}/sendMessage",
data={"chat_id": CHAT_ID, "text": f"Диск {disk}%, память {mem}%, load {load:.2f}"},
)
Почему это работает: порог задаётся прямо в условии `if`, а `sendMessage` — метод Bot API для отправки текста. Ожидаемый результат: при превышении порога в чате появляется сообщение, и API отвечает `{"ok":true,...}`.
Пример:при заполненном диске на 91% придёт текст `Диск 91%, память 62%, load 0.34`.
5. Проверьте отправку вручную, не дожидаясь проблемы.
python3 /opt/monitor/check.py
Ожидаемый результат: либо сообщение в Telegram, либо тишина — тишина значит, что пороги не превышены. Чтобы убедиться, что канал связи рабочий, временно поставьте порог `disk > 1` и запустите снова.
6. Поставьте скрипт на расписание через cron (cron — системный планировщик, который запускает команды по расписанию).
crontab -e
Добавьте строку:
*/5 * * * * /usr/bin/python3 /opt/monitor/check.py >> /var/log/monitor.log 2>&1
Почему это работает: `*/5` означает «каждые 5 минут», полный путь к `python3` нужен потому, что у cron своё окружение и короткое имя может не найтись. Ожидаемый результат: через 10 минут файл `/var/log/monitor.log` перестанет быть пустым.
7. Соберите Mini App: HTML-страница в `/var/www/monitor/index.html`, отдаваемая по HTTPS.
<!doctype html>
<html><body>
<h3>Мониторинг VPS</h3>
<pre id="out">загрузка…</pre>
<script>
fetch('/api/metrics').then(r => r.json()).then(d => {
document.getElementById('out').textContent = JSON.stringify(d, null, 2);
});
</script>
</body></html>
Почему это работает: Mini App — обычная веб-страница, Telegram просто открывает её во встроенном окне, поэтому нужен домен с валидным сертификатом (бот откроет только HTTPS-адрес).
8. Привяжите страницу к боту как кнопку меню.
curl -s -X POST "https://api.telegram.org/bot${TOKEN}/setChatMenuButton" \
-H "Content-Type: application/json" \
-d '{"menu_button":{"type":"web_app","text":"Мониторинг","web_app":{"url":"https://monitor.example.com/"}}}'
Ожидаемый результат: ответ `{"ok":true,"result":true}` и новая кнопка рядом с полем ввода в чате с ботом.
9. Прогоните чек-лист перед тем, как считать задачу закрытой.

Ошибка вида `{"ok":false,"error_code":401,"description":"Unauthorized"}`.Симптом: скрипт запускается, но в Telegram ничего не приходит. Причина — неверный токен или лишний пробел в кавычках. Решение: скопируйте строку из @BotFather заново, проверьте `curl -s "https://api.telegram.org/bot<TOKEN>/getMe"`, убедитесь, что `CHAT_ID` — число без кавычек-ёлочек.
Mini App не открывается, Telegram пишет про неверный URL.Симптом: кнопка есть, но окно пустое или ругается на адрес. Причина — самоподписанный сертификат или HTTP вместо HTTPS. Решение: выпустите валидный сертификат (например, через `certbot` от Let's Encrypt), проверьте, что `https://monitor.example.com/` открывается в обычном браузере без предупреждений, и только потом зовите `setChatMenuButton`.
Скрипт не срабатывает по расписанию, хотя руками всё работает.Симптом: `python3 /opt/monitor/check.py` даёт сообщение, а в логе cron пусто. Причина — у cron другое окружение и нет ваших переменных PATH. Решение: указывайте полный путь `/usr/bin/python3`, добавьте `>> /var/log/monitor.log 2>&1` для перехвата ошибок и проверьте `journalctl -u cron` или `/var/log/syslog`.
Обязательно ли делать Mini App, или хватит обычного бота?
Для старта хватит бота: алерты текстом работают без домена и SSL. Mini App нужен, когда вы хотите видеть дашборд с графиками и свежими метриками в одном окне, а не листать историю сообщений.
Можно ли обойтись без домена и HTTPS?
Для Mini App — нет, Telegram откроет только защищённый адрес. Для отправки сообщений через Bot API домен не нужен вообще: запросы идут с сервера наружу на `api.telegram.org`.
Как часто опрашивать сервер, чтобы не создать лишнюю нагрузку?
Начните с интервала в 5 минут через cron: для типичного VPS этого достаточно, чтобы поймать переполнение диска или скачок памяти, и при этом не забивать чат. Частоту повышайте только для критичных сервисов и с отдельным порогом срабатывания.
Можно ли, чтобы бот не просто присылал цифры, а писал текстовое объяснение?
Да, скрипт может вызвать внешний API и вставить ответ в сообщение. Как это устроено с ключами и запросами, разобрано в гайде как использовать GPT-6.1 Sol через API. Ключ храните в переменных окружения, а не в коде скрипта.