# Powiadomienia operacyjne z Filamenta na Telegramie

Wtyczka open source do paneli Filament: zapytania, błędy i buildy z panelu docierają na Telegram administratora — na telefon, bez logowania do panelu i bez zmian w istniejącym kodzie.

**Canonical:** https://spoko.space/pl/powiadomienia-telegram-dla-filament/  
**Language:** pl  
**Published:** 2026-09-25  
**Tags:** laravel, filament, telegram, php, open-source, queue  
**Category:** Portfolio  
**GitHub:** https://github.com/spokospace/filament-ops-notify

---
<div class="text-center flex gap-4 justify-center flex-wrap">

</div>

## W skrócie {#w-skrócie}

|  |  |
| --- | --- |
| Problem | Ważne zdarzenia — nowe zapytanie, błąd na produkcji, zakończony build — lądują w dzwonku w panelu, wśród dziesiątek rutynowych powiadomień. Administrator widzi je dopiero po zalogowaniu, a to, co pilne, łatwo w tym szumie przepada. |
| Co powstało | Warstwa dostarczania zdarzeń operacyjnych z Laravela i Filamenta na Telegram — z routingiem do tematów, kolejką, ponawianiem i historią. Ważne trafia na telefon, do właściwego wątku. |
| Co było trudne | Nie samo API Telegrama, tylko niezawodne dostarczanie, gdy aplikacja żyje: limity 429 z backoffem, deduplikacja niezależna od liczby odbiorców, zbieranie serii w digest. |
| Moja rola | Autor i osoba utrzymująca — cały pakiet: kanał powiadomień i API OpsMessage, sterownik Telegrama, routing, kolejkowe dostarczanie, panel, historia, dokumentacja, testy i tłumaczenia. |
| Efekt | Istotne powiadomienia docierają do człowieka na telefon, bez logowania do panelu. Działa na produkcji na moich panelach i panelach klientów. Licencja MIT, publiczny GitHub. |

Panel administracyjny wie o rzeczach, które ktoś powinien zobaczyć szybko: nowe zapytanie, zatrzymane zamówienie, błąd na produkcji, zakończony build. W Filamencie trafiają one do dzwonka w rogu panelu — a dzwonek widzisz dopiero po zalogowaniu.

To projekt open source na licencji MIT — kod jest [publiczny na GitHubie](https://github.com/spokospace/filament-ops-notify). Poniżej: co robi i, przede wszystkim, jak jest zbudowany.

## Dlaczego sam dzwonek nie wystarcza {#dlaczego-sam-dzwonek-nie-wystarcza}

Dzwonek ma jeszcze jeden problem. Gdy w aplikacji dużo się dzieje, zbiera w sobie dziesiątki powiadomień — tu 117, w większości rutynowych (konwersje mediów, wygenerowane okładki) — i to, co naprawdę ważne, w nich tonie. Dlatego istotne zdarzenia idą dodatkowo na telefon, do osobnych tematów:

<div class="grid grid-cols-2 gap-4 max-w-xl mx-auto not-prose">
  <figure class="m-0">
    <figcaption class="text-sm text-muted dark:text-slate-400 mb-2 text-center">Przedtem: 117 powiadomień w dzwonku</figcaption>
    
    
  </figure>
  <figure class="m-0">
    <figcaption class="text-sm text-muted dark:text-slate-400 mb-2 text-center">Teraz: push na telefonie</figcaption>
    
  </figure>
</div>

## Nie chodziło o wysłanie wiadomości {#nie-chodziło-o-wysłanie-wiadomości}

Łatwo pomyśleć, że to prosta integracja: weź zdarzenie i zrób POST do API Telegrama. Problemem nie jest jednak samo API Telegrama, tylko niezawodne dostarczanie wiadomości w działającej aplikacji. Telegram ogranicza tempo. Cache bywa niedostępny. Jeden request generuje to samo powiadomienie dla dziesięciu odbiorców. Produkcja potrafi wypluć serię błędów w kilka sekund.

Dlatego Ops Notify to nie „wysyłka na Telegram", tylko warstwa dostarczania zdarzeń operacyjnych: kolejka, deduplikacja, ponawianie, routing i historia. O tych decyzjach jest reszta tekstu.

## Dwie ścieżki: istniejące powiadomienia i nowe zdarzenia {#dwie-ścieżki-istniejące-powiadomienia-i-nowe-zdarzenia}

**Istniejące powiadomienia — zero zmian w kodzie.** Wtyczka stoi na [powiadomieniach Laravela](https://spoko.space/pl/slownik/laravel/), nie obok nich. Powiadomienia, które Filament wysyła do dzwonka przez `sendToDatabase()`, są przy okazji przekazywane na Telegram — bez dopisywania linijki kodu. A istniejące powiadomienia Laravela — mailowe i inne kanały — możesz lustrzać na Telegram bez ich zmiany: włączasz forwarding w konfiguracji i wskazujesz kanały, a treść wtyczka bierze z tego, co powiadomienie już definiuje (`toMail`, `toArray`).

**Nowe zdarzenia operacyjne — jawne API.** Zdarzenia, których panel sam z siebie nie zna — build, deploy, zewnętrzny webhook — wysyłasz płynnym API `OpsMessage`:

```php
use Spokospace\OpsNotify\OpsMessage;

OpsMessage::make('build.completed')
    ->success()
    ->title('Frontend build completed')
    ->field('Duration', '4m 12s')
    ->button('Open site', 'https://shop.example')
    ->send();
```

Na jednym ekranie widać całą wiadomość: zdarzenie, jego semantykę (`success`), pola, przycisk i wysyłkę. To jest API, a nie doraźna integracja.

## Co dzieje się, gdy produkcja zaczyna się sypać {#co-dzieje-się-gdy-produkcja-zaczyna-się-sypać}

Tu projekt spędził najwięcej czasu na produkcji. Trzy problemy, które trzeba było rozwiązać, żeby powiadomienia faktycznie docierały:

### `429` i backoff {#429-i-backoff}

Telegram ogranicza tempo wysyłki, więc „wyślij, a jak się nie uda, spróbuj znów" nie wystarcza. Wysyłka respektuje `429`, czeka tyle, ile każe Telegram, i ponawia z backoffem — a robi to w kolejce, więc nigdy nie blokuje requestu, który wywołał powiadomienie. Powiadomienie to skutek uboczny, nie coś, co ma prawo wywrócić zapis zamówienia.

### Duplikaty {#duplikaty}

Filament potrafi wygenerować to samo powiadomienie osobno dla każdego admina. Deduplikacja (współdzielony cache) wysyła je na Telegram raz, niezależnie od liczby odbiorców — dziesięcioosobowy zespół nie dostaje dziesięciu kopii tego samego alertu. A gdy cache pada, deduplikacja odpuszcza i wiadomość i tak idzie, zamiast wywołać błąd 500 i przerwać żądanie.

### Lawina identycznych błędów {#lawina-identycznych-błędów}

Przy awarii potrafi polecieć dwieście identycznych zdarzeń w kilka sekund. Zamiast dwustu wiadomości guard zbiera serię i wysyła jeden digest — tak, żeby zdarzenia na granicy okna nie były pomijane ani dublowane.

Powiadomienia powstające w transakcji trafiają do kolejki dopiero po jej zatwierdzeniu (`afterCommit`), żeby worker nie sięgnął po dane, których jeszcze nie ma w bazie. Do tego rzeczy, które wychodzą dopiero na produkcji: lock przy odkrywaniu czatu, żeby równoległe procesy nie wykonywały tego samego skanu, i poprawne raportowanie statusu, żeby wiadomość nie była oznaczona jako „w kolejce", jeśli faktycznie nie została zakolejkowana.

Każda wiadomość ląduje w historii ze swoim statusem i błędem zwróconym przez Telegram, a nieudane można wysłać ponownie jednym przyciskiem. Strona Ops Notify pokazuje przy tym połączenie i stan kolejki, więc widać nie tylko *co* poszło, ale i *czy w ogóle ma jak iść*.

## Routing: sygnał od szumu {#routing-sygnał-od-szumu}

Samo dostarczenie to połowa sprawy. Druga połowa to nie zalać człowieka wszystkim naraz. Telegram pozwala podzielić grupowy czat na tematy forum, a wtyczka robi z tego oś porządkowania: zapytania idą do jednego tematu, błędy do drugiego, buildy do trzeciego. Reguły dopasowują zdarzenia po wzorcu (`inquiry.*`, `build.*`), a powiadomienia Filamenta — po tytule.

Reszta konfiguracji siedzi w panelu, nie w `.env`: szyfrowany token, id czatu, szablony, profil bota i dostęp oparty na bramkach Laravela. Panel jest przetłumaczony na 25 języków, a język wiadomości ustawia się osobno — czat czyta cały zespół, więc jego język nie zależy od panelu pojedynczego admina.

## Droga wiadomości {#droga-wiadomości}

**Od zdarzenia do kieszeni**

1. **Coś się dzieje w aplikacji** — Filament wysyła powiadomienie do dzwonka, albo kod woła kanał ops czy OpsMessage. To samo źródło, ta sama ścieżka dalej.
2. **Reguła wybiera temat** — Zdarzenie jest dopasowywane po wzorcu (albo po tytule, jeśli to powiadomienie Filamenta) i przypisane do właściwego tematu forum.
3. **Szablon składa wiadomość** — Tytuł, pola i hashtag powstają z szablonu, z prefiksem usługi i przyciskiem prowadzącym do rekordu.
4. **Kolejka wysyła z ponawianiem** — Wiadomość idzie przez kolejkę, ze świadomością limitów Telegrama i ponawianiem — nigdy nie blokując requestu, który ją zrodził.
5. **Historia zapisuje wynik** — Status i ewentualny błąd Telegrama lądują w historii, a nieudaną wysyłkę można powtórzyć jednym przyciskiem.

## Moja rola {#moja-rola}

Routing, kolejka z ponawianiem, deduplikacja, panel, API, historia — wszystko powyżej jest moje. Jestem autorem i osobą utrzymującą pakiet, od modelu zdarzeń po warstwę dostarczania: kanał `ops` i płynne API `OpsMessage`, sterownik Telegrama, routing i tematy, kolejkowe dostarczanie odporne na awarie, panel i profil bota, historię z ponawianiem, dokumentację, testy i tłumaczenia.

## Efekt {#efekt}

Działa na produkcji — na moich panelach i panelach klientów. Ważne zdarzenia trafiają na telefon, a nieudane wysyłki widać w historii i można je powtórzyć jednym przyciskiem.

## Technologie {#technologie}

## Kiedy to ma sens {#kiedy-to-ma-sens}

Jeśli w panelu pojawiają się zdarzenia wymagające reakcji poza godzinami pracy albo bez ciągłego zaglądania do panelu, Telegram staje się dodatkowym kanałem operacyjnym. Wtyczka nie zastępuje powiadomień w aplikacji — przenosi wybrane z nich tam, gdzie zespół i tak odbiera komunikaty.

Powstała, bo potrzebowałem jej na własnych panelach — tych samych, na których stoi mój [autorski CMS](https://spoko.space/pl/autorski-cms-z-ai/). A skoro problem („ważne powiadomienia nie docierają na czas") ma każdy, kto prowadzi panel administracyjny, nie ma powodu trzymać rozwiązania u siebie. Kod jest na GitHubie — MIT, `composer require spokospace/filament-ops-notify`.

<div class="text-center flex gap-4 justify-center flex-wrap mt-8">

</div>
