feat: PING watchdog, IRCv3 server-time, push notifications

PING watchdog sends PING after configurable silence interval and
disconnects on timeout, detecting stale connections that TCP alone
misses. IRCv3 server-time capability is requested on every connection;
timestamps are injected on dispatch and backlog replay for clients
that support message tags. Push notifications via ntfy or generic
webhook fire on highlights and PMs when no clients are attached,
with configurable cooldown and optional SOCKS5 routing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
user
2026-02-21 17:41:38 +01:00
parent 4dd817ea75
commit 0d762ced49
10 changed files with 1733 additions and 27 deletions

View File

@@ -171,6 +171,83 @@ replay_on_connect = true # set false to disable replay
Stored commands: `PRIVMSG`, `NOTICE`, `TOPIC`, `KICK`, `MODE`.
## PING Watchdog
The bouncer sends periodic PING messages to detect stale server connections
(socket open but no data flowing). If no data is received within the configured
interval, a PING is sent. If the server doesn't respond within the timeout,
the connection is dropped and a reconnect is scheduled.
```toml
[bouncer]
ping_interval = 120 # seconds of silence before sending PING
ping_timeout = 30 # seconds to wait for PONG after PING
```
The watchdog starts automatically when a network enters the READY state.
Any received data (not just PONG) resets the timer.
## IRCv3 server-time
The bouncer requests the `server-time` IRCv3 capability on every connection.
When enabled by the server, timestamps on incoming messages are preserved and
forwarded to clients. When the server does not provide a timestamp, the bouncer
injects one using the current UTC time.
Backlog replay also includes timestamps from when messages were originally
stored, so clients that support `server-time` see accurate times on replayed
messages.
No client configuration is needed -- timestamps appear automatically if the
client supports IRCv3 message tags.
## Push Notifications
When no IRC clients are connected to the bouncer, highlights and private
messages can trigger push notifications via [ntfy](https://ntfy.sh) or a
generic webhook.
### Setup
```toml
[bouncer]
notify_url = "https://ntfy.sh/my-bouncer-topic"
notify_on_highlight = true # mentions of your nick in channels
notify_on_privmsg = true # private messages
notify_cooldown = 60 # min seconds between notifications
notify_proxy = false # route notifications through SOCKS5
```
### ntfy Example
```toml
notify_url = "https://ntfy.sh/my-secret-topic"
```
Install the ntfy app on your phone and subscribe to the topic. Notifications
include the sender, target, and message text.
### Generic Webhook
Any URL that does not contain `ntfy` in the hostname is treated as a generic
webhook. The bouncer POSTs JSON:
```json
{
"network": "libera",
"sender": "user",
"target": "#channel",
"text": "hey mynick, check this out"
}
```
### Behavior
- Notifications only fire when **no clients** are attached
- The cooldown prevents notification floods (one per `notify_cooldown` seconds)
- When `notify_proxy = true`, notification requests are routed through the
configured SOCKS5 proxy
## Configuration Reference
```toml
@@ -199,6 +276,17 @@ email_request_timeout = 20 # per-request timeout for email APIs
# Certificate generation
cert_validity_days = 3650 # client cert validity (~10 years)
# PING watchdog
ping_interval = 120 # seconds of silence before sending PING
ping_timeout = 30 # seconds to wait for PONG after PING
# Push notifications
notify_url = "" # ntfy or webhook URL (empty = disabled)
notify_on_highlight = true # notify on nick mentions
notify_on_privmsg = true # notify on private messages
notify_cooldown = 60 # min seconds between notifications
notify_proxy = false # route notifications through SOCKS5
[bouncer.backlog]
max_messages = 10000 # per network, 0 = unlimited
replay_on_connect = true # replay missed messages on client connect