Буває, що важливі події системи трапляються саме тоді, коли ви не за терміналом. Тому сьогодні я покажу, як відправляти системні сповіщення Linux у Telegram: короткий bash-скрипт, підключення до rsyslog для подій з журналів, а також варіанти через systemd (OnFailure і таймери). Це простий та надійний трюк для автоматизації задач 🚀

Що і навіщо ми робимо

Мета — отримувати в Telegram все важливе: критичні помилки з log-файлів Linux, падіння сервісів systemd та регулярні дайджести. Ми створимо Telegram-бота, напишемо легкий bash скрипт для надсилання повідомлень, підключимо його до rsyslog, а потім додамо сповіщення через OnFailure та щоденний звіт за допомогою cron та systemd timers (ми використаємо саме systemd-таймери як сучасніші).

Підготовка: Telegram-бот і chat_id

  1. Відкрийте Telegram і знайдіть @BotFather. Створіть бота (/newbot) і збережіть токен (вигляду 123456:ABC...).
  2. Напишіть вашому новому боту будь-яке повідомлення, щоб з’явився chat_id.
  3. Отримайте chat_id (потрібен curl):
export TG_TOKEN="YOUR:BOT_TOKEN"
curl -s "https://api.telegram.org/bot$TG_TOKEN/getUpdates" | sed -n 's/.*"chat":{\"id\":\([-0-9]\+\).*/\1/p' | head -n1

Побачите число на кшталт 123456789 — це і є ваш TG_CHAT_ID.

Основний How-to: bash-скрипт + rsyslog

1) Зберігаємо токен і chat_id в окремому файлі

Створіть файл із секретами (так безпечніше, ніж хардкодити в скрипті):

sudo sh -c 'cat >/etc/default/tg-notify <<EOF
TG_TOKEN="YOUR:BOT_TOKEN"
TG_CHAT_ID="123456789"
EOF'
sudo chmod 600 /etc/default/tg-notify

2) Пишемо скрипт надсилання в Telegram

Скрипт приймає текст як аргумент або з stdin. Будемо URL-кодувати текст, щоб уникати проблем зі спецсимволами.

sudo tee /usr/local/bin/tg-notify.sh >/dev/null <<'BASH'
#!/usr/bin/env bash
set -Eeuo pipefail

# Завантажуємо змінні TG_TOKEN і TG_CHAT_ID
source /etc/default/tg-notify
: "${TG_TOKEN:?TG_TOKEN is required}"
: "${TG_CHAT_ID:?TG_CHAT_ID is required}"

# Текст з аргументу або зі stdin
if [[ $# -gt 0 ]]; then
  TEXT="$*"
else
  TEXT="$(cat)"
fi

# Порожні повідомлення не шлемо
[[ -z "${TEXT//[[:space:]]/}" ]] && exit 0

# Надсилання
curl -sS -X POST \
  "https://api.telegram.org/bot${TG_TOKEN}/sendMessage" \
  -d "chat_id=${TG_CHAT_ID}" \
  --data-urlencode "text=${TEXT}" \
  -d "disable_web_page_preview=true" >/dev/null
BASH
sudo chmod +x /usr/local/bin/tg-notify.sh

3) Тестуємо

/usr/local/bin/tg-notify.sh "Привіт з Linux! Це тестове сповіщення."

Якщо все ок — у Telegram з’явиться повідомлення.

4) Підключаємо rsyslog (критичні події)

Надсилатимемо все з рівнем err і вище (3 і менше за пріоритетом syslog). Потрібен модуль omprog.

sudo sh -c 'cat >/etc/rsyslog.d/30-telegram.conf <<"RSYS"
module(load="omprog")
# Фільтр: важливі повідомлення (err, crit, alert, emerg)
if ($syslogseverity <= 3) then {
  action(type="omprog" binary="/usr/local/bin/tg-notify.sh" template="RSYSLOG_TraditionalFileFormat")
  stop
}
RSYS'

sudo systemctl restart rsyslog

Готово! Тепер суттєві події з log-файлів Linux прилітатимуть у Telegram. За потреби додавайте умови, наприклад за $programname чи $syslogfacility, щоб зменшити шум.

Альтернативні способи з systemd

Сповіщення про падіння сервісів (OnFailure)

Коли будь-який сервіс завершується з помилкою, systemd може викликати окрему юніт-дію. Налаштуємо шаблон:

sudo tee /etc/systemd/system/tg-notify@.service >/dev/null <<'UNIT'
[Unit]
Description=Send Telegram alert for %i failure

[Service]
Type=oneshot
EnvironmentFile=/etc/default/tg-notify
ExecStart=/usr/local/bin/tg-notify.sh "⚠️ Unit %i failed on %H"
UNIT

sudo systemctl daemon-reload

Додайте рядок OnFailure у будь-який сервіс, який хочете моніторити:

sudo systemctl edit nginx.service
# У відкритому редакторі додайте:
[Unit]
OnFailure=tg-notify@%n.service

sudo systemctl daemon-reload

Щоб перевірити, штучно зламайте сервіс або гляньте логи падіння — прийде сповіщення.

Щоденний дайджест помилок через systemd timer

Замість cron використаємо cron та systemd timers у стилі systemd. Надсилатимемо дайджест помилок за останні 24 години о 9:00.

# Сервіс, що збирає дайджест і шле в Telegram
sudo tee /etc/systemd/system/tg-daily-journal.service >/dev/null <<'UNIT'
[Unit]
Description=Daily Telegram digest of last 24h errors

[Service]
Type=oneshot
ExecStart=/bin/bash -lc 'journalctl -p err -S -24h | tail -n 200 | sed "1iDaily errors on $(hostname)" | /usr/local/bin/tg-notify.sh'
UNIT

# Таймер на 09:00 щодня
sudo tee /etc/systemd/system/tg-daily-journal.timer >/dev/null <<'UNIT'
[Unit]
Description=Run tg-daily-journal.service daily at 09:00

[Timer]
OnCalendar=*-*-* 09:00:00
Persistent=true

[Install]
WantedBy=timers.target
UNIT

sudo systemctl daemon-reload
sudo systemctl enable --now tg-daily-journal.timer

Це гарний спосіб для стислих оглядів без спаму.

GUI-спосіб: швидке повідомлення через zenity

Хочете іноді вручну надіслати коротку нотатку в Telegram з робочого столу? Зробимо маленьке GUI віконце:

sudo apt install -y zenity  # або відповідний пакет у вашому дистрибутиві

sudo tee /usr/local/bin/tg-notify-gui.sh >/dev/null <<'BASH'
#!/usr/bin/env bash
MSG=$(zenity --entry --title="Telegram notify" --text="Введіть повідомлення:") || exit 0
[[ -n "$MSG" ]] && /usr/local/bin/tg-notify.sh "$MSG"
BASH
sudo chmod +x /usr/local/bin/tg-notify-gui.sh

Створіть ярлик у меню або швидку клавішу — і готово 🙂

FAQ

  • Чим відрізняються journald і rsyslog? systemd-journald збирає події, а rsyslog — потужний маршрутизатор/фільтр, у т.ч. для розсилки та зберігання. Ми використовуємо rsyslog з модулем omprog, аби запускати скрипт.
  • Немає модуля omprog? Переконайтеся, що у вашому пакеті rsyslog він увімкнений. На Debian/Ubuntu зазвичай є за замовчуванням. Інакше оновіть/перевстановіть rsyslog або використайте альтернативу (іменований pipe + скрипт-«хвіст»).
  • Повідомлень забагато. Як зменшити шум? У правилі rsyslog підвищте поріг ($syslogseverity <= 2) або фільтруйте за $programname. Можна додати дедуплікацію в скрипт (кеш останніх N хешів).
  • Безпека токена? Тримайте /etc/default/tg-notify з правами 600, власник root. Не комітьте його в репозиторії.
  • Telegram заблокований у мережі? Додайте опції проксі до curl (наприклад, змінні оточення https_proxy).
  • Як надіслати в кілька чатів? Або запускайте скрипт кілька разів з різними TG_CHAT_ID, або розширте скрипт, щоб приймав chat_id параметром.
  • Форматування Markdown/HTML? Можна додати -d parse_mode=MarkdownV2, але тоді обов’язково екрануйте спецсимволи. Для простоти лишили plain text.

Порада від Kernelka

Секрет стабільних сповіщень — не перетворюйте Telegram на смітник. Відправляйте лише суттєве, використовуйте рівні важливості, а для масових викидів — щоденні дайджести. І тримайте скрипт максимально простим — тоді він переживе будь-які оновлення системи 😉

Підсумок

  • Створили Telegram-бота й отримали chat_id.
  • Написали універсальний bash скрипт для надсилання.
  • Підключили критичні події з rsyslog у Telegram.
  • Додали сповіщення OnFailure та щоденний дайджест через systemd timers.
  • Зробили простий GUI-лаунчер на zenity для ручних повідомлень ✅

Готово! Тепер ви не пропустите важливі події навіть далеко від термінала.