Każdy system monitoringu prędzej czy później staje przed tym samym pytaniem: jak dać znać człowiekowi. Domyślną odpowiedzią od dwudziestu lat jest mail. I to jest odpowiedź, która w praktyce nie działa.
Nie dlatego, że mail jest zły technicznie. Dlatego, że alert konkuruje w skrzynce z fakturami, newsletterami i korespondencją, przegrywa tę konkurencję, po tygodniu dostaje własną regułę i folder, a po miesiącu ten folder ma dwieście nieprzeczytanych wiadomości. Powiadomienie, które trafia do archiwum zamiast do uwagi, nie jest powiadomieniem.
Ten wpis opisuje alternatywę, której używam na co dzień: bota na Telegramie. Jak to zestawić, jak rozdzielić powiadomienia według wagi, jakie pułapki kryje ta z pozoru banalna integracja i kiedy Telegram na pewno nie wystarczy.
Dlaczego akurat Telegram
Powody są prozaiczne i dlatego mocne:
- Push ląduje na telefonie, obok wiadomości od ludzi. Nie w folderze, do którego zagląda się raz na tydzień.
- Grupa zamiast listy adresatów. Alerty widzi cały zespół, a dołączenie nowej osoby to zaproszenie do grupy, a nie edycja konfiguracji na serwerze.
- Wątki (topiki) w grupie, dzięki którym awarie krytyczne i informacje porządkowe nie mieszają się w jednym strumieniu.
- Bot API jest darmowe, stabilne i banalnie proste - jedno zapytanie HTTP, żadnych bibliotek, żadnego SDK.
- Historia jest przeszukiwalna na każdym urządzeniu, więc „kiedy to ostatnio padło” to kwestia wpisania frazy w wyszukiwarkę czatu.
Alternatywy są sensowne i nie chcę ich deprecjonować: ntfy (świetne, gdy chcesz mieć całość u siebie), Discord czy Slack (dobre, gdy zespół i tak tam siedzi), SMS (drogie, ale niezależne od internetu). Telegram wygrywa u mnie stosunkiem nakładu do efektu.
Minimalny działający przykład
Całość sprowadza się do trzech kroków.
1. Załóż bota. Napisz do @BotFather komendę /newbot, podaj nazwę i dostaniesz token. Token to jedyne, co potwierdza tożsamość bota - traktuj go jak hasło.
2. Ustal identyfikator czatu. Napisz do bota (albo dodaj go do grupy i napisz cokolwiek), a potem odczytaj:
curl "https://api.telegram.org/bot<TOKEN>/getUpdates"
W odpowiedzi znajdziesz chat.id. Dla czatu prywatnego to liczba dodatnia, dla grupy ujemna.
3. Wyślij wiadomość.
curl -s "https://api.telegram.org/bot<TOKEN>/sendMessage" \
-d chat_id=<CHAT_ID> \
--data-urlencode "text=Test alertu"
To wszystko. Od tego momentu każdy skrypt, cron czy monitoring, który potrafi wykonać zapytanie HTTP, umie się z Tobą skontaktować.
Wątki, czyli sposób na to, żeby alerty dało się czytać
To jest funkcja, która moim zdaniem decyduje o użyteczności całego rozwiązania, a jest zaskakująco mało znana. Grupa na Telegramie może mieć włączone tematy (topics), a bot potrafi wysłać wiadomość do konkretnego wątku, dokładając jeden parametr:
-d message_thread_id=<ID_WATKU>
Dzięki temu jedna grupa obsługuje kilka strumieni naraz. U mnie podział idzie według wagi zdarzenia:
Krytyczne -> awaria łącza, utrata dostępu (powiadomienia włączone)
Ostrzeżenia -> progi, nietypowy ruch (powiadomienia włączone)
Info -> raport dobowy, nowe urządzenie (wyciszony wątek)
Efekt jest taki, że wyciszam informacje porządkowe, nie tracąc ich, a telefon wibruje wyłącznie przy rzeczach, które naprawdę tego wymagają. To jest różnica między kanałem, który się czyta, a kanałem, który się wycisza w całości po dwóch tygodniach.
Zasada, która przeżyła zderzenie z praktyką: trzy poziomy ważności, nie siedem. Przy siedmiu nikt nie pamięta różnicy między „alert” a „ostrzeżenie”, a przy trzech decyzja „czy to ma zawibrować w nocy” jest oczywista.
I jeszcze jeden szczegół, który warto zaprojektować od razu: jeśli Twój system kiedyś doda nowy poziom ważności, nieznana wartość powinna trafiać do wątku domyślnego. Powiadomienie w niewłaściwym miejscu jest kłopotliwe. Powiadomienie, które nie poszło nigdzie, jest niebezpieczne.
Pułapki, które kosztowały mnie wieczory
Wysyłka działa z przeglądarki, ale nie z crona
Klasyk, który potrafi zająć pół dnia. Skrypt testowany w przeglądarce wysyła wiadomości bez zarzutu, a ten sam kod uruchomiony z crona milczy. Powód bywa banalny: konfiguracja PHP dla linii poleceń różni się od tej dla serwera WWW i funkcja pobierająca zawartość adresu URL może być tam po prostu wyłączona.
Wniosek praktyczny: do integracji używaj cURL-a, nie funkcji typu file_get_contents. Działa tak samo w obu środowiskach i, co ważniejsze, potrafi powiedzieć, dlaczego się nie udało.
Cisza nie do odróżnienia od spokoju
Najgroźniejszy błąd w całej tej układance. Jeśli wyciszysz błędy wysyłki, to zły identyfikator czatu, bot wyrzucony z grupy albo skasowany wątek objawiają się dokładnie tak samo jak brak zdarzeń: ciszą. A ciszę człowiek interpretuje jako „wszystko w porządku”.
Telegram odpowiada czytelnym kodem HTTP i opisem błędu. Zapisuj obie te rzeczy do logu przy każdej nieudanej wysyłce - to jedyny sposób, żeby dowiedzieć się o zepsutym kanale wcześniej niż przy najbliższej awarii. Samej treści powiadomienia w logu nie umieszczaj.
Jeden znak podkreślenia i cała wiadomość przepada
Jeżeli wysyłasz z parse_mode=Markdown, to znaki _, * czy [ w treści są składnią, a nie tekstem. Wystarczy, że urządzenie w sieci nazywa się serwer_backup, a Telegram odrzuci całą wiadomość błędem parsowania. Alert nie dotrze, bo nazwa hosta zawierała podkreślenie.
Masz dwa wyjścia: albo czyścić dane wstawiane do treści, albo w ogóle nie ustawiać trybu formatowania. Jeśli formatowanie nie jest Ci naprawdę potrzebne, drugie wyjście jest bezpieczniejsze.
Polskie znaki wysyłane z linii poleceń
Przy skryptach powłoki potrafi wyskoczyć błąd o tym, że treść musi być zakodowana w UTF-8 - mimo że wygląda poprawnie. Zwykle winne jest kodowanie samego pliku skryptu albo konsoli, nie Telegram. Najprościej jest przekazać treść z pliku zapisanego w UTF-8, zamiast wklejać ją bezpośrednio w polecenie.
Wątki działają tylko w grupach z tematami
Parametr wskazujący wątek ma sens wyłącznie w grupie z włączonymi tematami. Wysłany do czatu prywatnego zostanie odrzucony. Jeśli budujesz to jako opcję konfiguracyjną, pusta wartość powinna oznaczać „nie dokładaj tego parametru w ogóle”, dzięki czemu ta sama instalacja obsłuży i grupę z wątkami, i zwykły czat.
Bezpieczeństwo, o którym trzeba pomyśleć od razu
Token to pełna kontrola nad botem. Kto go ma, może wysyłać wiadomości w Twoim imieniu do wszystkich czatów, w których bot się znajduje, i czytać to, co bot widzi. Nie umieszczaj go w repozytorium - to najczęstszy sposób, w jaki takie tokeny wyciekają. Trzymaj go poza kodem, a na współdzielonym hostingu rozważ przechowywanie go w postaci zaszyfrowanej, tak żeby sam odczyt pliku konfiguracyjnego nie wystarczył do przejęcia kanału.
Bot domyślnie nie czyta rozmów. W trybie prywatności widzi tylko komendy skierowane do siebie. To dobre ustawienie i nie ma powodu go zmieniać, jeśli bot ma wyłącznie wysyłać powiadomienia.
Uważaj, co wkładasz w treść. Alert nie musi zawierać adresów IP, nazw użytkowników ani szczegółów konfiguracji. Wystarczy tyle, żeby wiedzieć, co i gdzie się stało - resztę sprawdzisz w panelu. Wiadomości zostają w chmurze usługodawcy i na telefonach wszystkich członków grupy.
Nie dawaj botowi uprawnień administratora, jeśli tylko wysyła wiadomości. Wyjątkiem jest sytuacja, w której ma pisać do wątków - wtedy sprawdź, jakie minimalne uprawnienia są do tego potrzebne.
Higiena alertu, czyli jak nie zabić własnego kanału
Najlepiej skonfigurowany kanał powiadomień zabija zwykle nie awaria, tylko nadmiar. Cztery zasady, które u mnie się sprawdziły:
- Powiadamiaj o zmianie stanu, nie o stanie. „Łącze padło” i później „łącze wróciło, przerwa 4 minuty” to dwie wiadomości. „Łącze nadal nie działa” co minutę to droga do wyciszenia grupy.
- Odczekaj dwa cykle. Pojedynczy nieudany pomiar to najczęściej chwilowy timeout, a nie awaria.
- Agreguj to, co nie wymaga reakcji. Nowe urządzenia, statystyki i podsumowania mają sens raz na dobę, w jednym raporcie, w wyciszonym wątku.
- Zaplanuj ciszę nocną dla wszystkiego poniżej poziomu krytycznego. Alert, który budzi bez powodu, uczy ludzi ignorować alerty, które budzą słusznie.
Kiedy Telegram nie wystarczy
Uczciwie o ograniczeniach, bo to nie jest rozwiązanie na wszystko:
- Nie jest to ślad audytowy. Jeśli musisz udokumentować, że incydent został wykryty i obsłużony, potrzebujesz systemu zgłoszeń z historią i rozliczalnością. Czat może być powiadomieniem o zdarzeniu, ale nie jego rejestrem.
- To zewnętrzna zależność. Bez internetu nie ma powiadomienia. Przy awarii łącza w tej właśnie lokalizacji ratuje tylko kanał niezależny, na przykład SMS.
- Dane wychodzą na zewnątrz. W środowisku z wysokimi wymaganiami na poufność rozsądniejszy będzie kanał utrzymywany we własnej infrastrukturze.
- Brak potwierdzenia obsługi. Nie ma dyżurów ani eskalacji, gdy nikt nie zareaguje. Przy krytycznych usługach potrzebny jest system, który wie, że nikt nie odebrał, i zawoła następną osobę.
W kontekście regulacyjnym warto o tym pamiętać: pisaliśmy osobno o tym, jak nie pomylić trzech różnych systemów monitoringu pod NIS2 i DORA, a kanał powiadomień jest tylko jednym z ich elementów, nie zamiennikiem całości.
Podsumowanie
Zamiana maila na czat brzmi jak kosmetyka, a jest zmianą jakościową, bo przenosi alert z miejsca, do którego się zagląda, do miejsca, które samo się odzywa. Reszta to konsekwencja: trzy poziomy ważności, osobne wątki, cisza dla rzeczy nieistotnych i logowanie nieudanych wysyłek, żeby cisza zawsze znaczyła spokój, a nie awarię kanału.
W poprzednim wpisie opisałem drugą stronę tej układanki, czyli powody, dla których zbudowałem własny dashboard do sieci UniFi. Jeśli chcesz, żeby Twój monitoring odzywał się wtedy, kiedy trzeba, i do kogo trzeba - tym zajmujemy się w ramach administracji siecią.