Pusk: samodzielny serwer alertów o rozmiarze 16 MB napisany w Go
Samodzielne rozwiązanie Pusk zastępuje zależność od zewnętrznych komunikatorów w monitoringu. Jeden plik wykonywalny o rozmiarze 16 MB obsługuje 13 metod Telegram Bot API, WebSocket, Web Push oraz klienta PWA. Działa bez Postgresa czy innych baz danych — tylko SQLite w czystym Go. Zaprojektowany dla scenariuszy, w których zewnętrzne API są niedostępne: limity, blokady lub izolacja.
Architektura wyklucza zewnętrzne serwisy. Go wybrano za szybki czas kompilacji (7 sekund) i wbudowany net/http. Baza danych — modernc.org/sqlite bez CGO, RSS ~4 MB przy starcie. Logi przez slog w JSON lub text.
Dlaczego nie standardowe komunikatory
Alternatywy wymagają migracji, baz danych i zasobów:
| Platforma | Zależności | Kompatybilność botów | ACK | RAM |
|-----------|-------------|---------------------|-----|-----|
| Mattermost | Postgres, SMTP | Przepisywanie | Wtyczka | 500+ MB |
| Matrix | Synapse, Postgres | Przepisywanie | Nie | 500+ MB |
| Telegram | Chmura | — | Nie | — |
Gotify/ntfy — tylko push bez czatu i ACK. VPN dla Telegrama dodaje punkty awarii. Pusk emuluje Bot API: zmieniasz base_url w bocie — i działa on z twoją infrastrukturą.
Struktura pliku binarnego
pusk (16 MB, ~6600 linii Go, 110 testów)
├── Bot API — /bot/<token>/<method> (13 z 80+ metod Telegram Bot API)
├── Client API — /api/* (backend PWA)
├── WebSocket — /api/ws (statusy w czasie rzeczywistym, pisanie)
├── Web Push — FCM / Mozilla (powiadomienia bez polling)
├── Pliki — /file/<id> (media)
├── PWA — / (klient webowy)
└── SQLite — data/orgs/*/pusk.db (oddzielna baza danych dla każdej organizacji)
Obsługiwane metody: sendMessage, editMessageText, deleteMessage, answerCallbackQuery, sendPhoto, sendDocument, sendVoice, sendVideo, setWebhook, deleteWebhook, getWebhookInfo, getMe, getUpdates.
Middleware dla kompatybilności:
func TelegramCompat(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
p := r.URL.Path
if strings.HasPrefix(p, "/bot") && !strings.HasPrefix(p, "/bot/") {
r.URL.Path = "/bot/" + p[4:]
}
next.ServeHTTP(w, r)
})
}
Migracja python-telegram-bot:
# Było:
app = ApplicationBuilder().token(TOKEN).build()
# Stało się:
app = ApplicationBuilder().token(TOKEN).base_url("https://pusk.internal/bot").build()
Long Polling i dostarczanie aktualizacji
/getUpdates utrzymuje połączenie przez timeout sekund, uwzględnia offset, kolejka w pamięci (100 aktualizacji/bot). Przy restarcie bot otrzymuje kolejne alerty bez persystencji.
Dla botów za NAT — WebSocket relay:
import websockets, json, asyncio
async def relay():
async with websockets.connect("wss://pusk.internal/bot/TOKEN/relay") as ws:
async for msg in ws:
update = json.loads(msg)
print(update["message"]["text"])
asyncio.run(relay())
Automatyczny wybór: webhook (z ochroną SSRF), relay (limit 30 wiad./min) lub getUpdates.
SQLite dla każdej organizacji i gorąca kopia zapasowa
Każda organizacja — oddzielny pusk.db w trybie WAL. Nie blokuje czytelników przy zapisie. Kopia zapasowa: sqlite3 pusk.db ".backup backup.db". Nadaje się dla dziesiątek wiadomości/min bez JOIN'ów Postgresa.
Przepływ pracy
- Administrator uruchamia serwer (docker run lub plik binarny), tworzy organizację — generuje się #general i bot systemowy.
- Zaproszenie przez link (7 dni, do 50 os.), automatyczne powiadomienie na czacie.
- Utworzenie #alerts, webhook z Zabbix/Grafana/Alertmanager (?format=alertmanager).
- Dyżurny: push/WebSocket, przycisk ACK, cały zespół widzi status.
Role:
- Administrator: wszystkie uprawnienia + zarządzanie użytkownikami/kanałami.
- Członek: czat, ACK, pliki, @mention.
Ulepszenia dla alertowania
- ACK → Silence: POST /api/v2/silences do Alertmanager przez PUSK_ALERTMANAGER_URL.
- Kolory: czerwony/zielony pasek dla firing/resolved.
- Optymalizacja push: WebSocket aktywny i kanał otwarty — nie wysyłać push.
- Izolacja: frontend wbudowany, bez CDN. Web Push wymaga FCM/Mozilla.
Co jest ważne
- Jeden 16 MB plik binarny bez zewnętrznych zależności, SQLite w Go.
- Częściowa emulacja Telegram Bot API dla migracji bez przepisywania.
- ACK z automatycznym wyciszeniem Alertmanager, kolorowa wskazówka statusów.
- WebSocket relay dla NAT, limity szybkości, ochrona SSRF.
- PWA z push, role administrator/członek, izolacja przez org.db.
— Editorial Team
Brak komentarzy.