A polling daemon that watches Fizzy for unread notifications and forwards them to an OpenClaw webhook.
OpenClaw's heartbeat is costly for simple notification checking, which is why this separate polling service exists. We can also added more instructions and references in the webhook payload for better result.
bundle installruby app.rb --url URL --token TOKEN [options]| Flag | Required | Description | Default |
|---|---|---|---|
--url URL |
Yes | Fizzy base URL (e.g. https://app.fizzy.do) |
— |
--token TOKEN |
Yes | Fizzy personal access token | — |
--webhook-url URL |
No | OpenClaw webhook base URL | — |
--webhook-token TOKEN |
No | OpenClaw webhook bearer token | — |
--polling SECONDS |
No | Polling interval in seconds | 10 |
--dry-run |
No | Print webhook payload without sending | — |
--verbose |
No | Print full request/response headers and body (redacts Authorization) | — |
Both --webhook-url and --webhook-token are required unless --dry-run is used.
Dry run (no webhook):
ruby app.rb --url https://app.fizzy.do --token abc123 --dry-runWith webhook forwarding:
ruby app.rb \
--url https://app.fizzy.do \
--token abc123 \
--webhook-url http://localhost:18789 \
--webhook-token my-secretRun as background daemon:
nohup ruby app.rb --url https://app.fizzy.do --token abc123 --dry-run > fizzy-pop.log 2>&1 &docker build -t fizzy-pop .Pass the CLI flags directly as arguments to the container:
docker run --rm fizzy-pop \
--url https://app.fizzy.do \
--token abc123 \
--webhook-url http://host.docker.internal:18789 \
--webhook-token my-secretIf the OpenClaw gateway is running on the host machine, add --add-host so the container can reach it:
docker run --rm \
--add-host host.docker.internal:host-gateway \
fizzy-pop \
--url https://app.fizzy.do \
--token abc123 \
--webhook-url http://host.docker.internal:18789 \
--webhook-token my-secret \
--verboseFizzy Pop includes a Kamal configuration for deploying to a remote server.
Create a .env file in the project root:
HOSTS=your-server-ip
URL=https://app.fizzy.do
TOKEN=your-fizzy-token
WEBHOOK_URL=http://host.docker.internal:18789
WEBHOOK_TOKEN=your-webhook-token
The bin/kamal binstub automatically loads .env before running Kamal. Environment variables already set in your shell take precedence.
bin/kamal setup # First-time server setup and deploy
bin/kamal deploy # Subsequent deploysbin/kamal app logs # Tail container logs
bin/kamal app details # Show running container info
bin/kamal app stop # Stop the service
bin/kamal app start # Start the serviceThe deploy config (config/deploy.yml) automatically passes --add-host host.docker.internal:host-gateway so the container can reach services on the host machine.
Enable webhooks and configure the gateway in your OpenClaw config:
{
gateway: {
port: 18789,
mode: "local",
bind: "lan"
},
hooks: {
enabled: true,
token: "your-webhook-token"
}
}Setting bind to "lan" is required when Fizzy Pop runs inside a Docker container, because the default "loopback" mode only listens on 127.0.0.1 which is unreachable from within a container. The "lan" mode binds to 0.0.0.0 so the container can connect via host.docker.internal. Note that "lan" mode requires authentication to be configured — the gateway will refuse to start without it.
If you run Fizzy Pop directly on the same host (not in Docker), you can use bind: "loopback" instead.
See the OpenClaw security docs for all bind modes (loopback, lan, tailnet, auto).
The hooks.token value is what you pass as --webhook-token. The --webhook-url should point to your gateway (e.g. http://localhost:18789).
Fizzy Pop posts to POST /hooks/agent with Authorization: Bearer <token>.
See the OpenClaw webhook docs for more details.
- Authenticates with Fizzy using a personal access token
- Polls for unread notifications every N seconds
- For each unread notification with a creator (comments/mentions):
- Marks it as read in Fizzy
- Forwards the notification to the OpenClaw webhook (
POST /hooks/agent)
