Webhook Setup (Queues)
Jambo uses Symfony Messenger to process webhooks and other async tasks (image processing, bulk operations) in the background. Without a worker running, these tasks queue up but are never executed.
How it works
- An event occurs (content created, updated, deleted)
- Jambo pushes a message to the queue (
MESSENGER_TRANSPORT_DSN) - A worker process consumes the queue and triggers webhook HTTP calls
Configure the transport
In .env:
# Recommended for production: database transport (reliable, no extra service)MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0
# Redis (faster, requires Redis server)MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages
# Development only (tasks lost on restart)MESSENGER_TRANSPORT_DSN=in-memory://For the doctrine transport, create the queue table:
php bin/console messenger:setup-transportsRunning the worker
Start a worker process manually:
php bin/console messenger:consume async --time-limit=3600The --time-limit flag restarts the worker every hour to free memory.
Production: Supervisor
Use Supervisor to keep workers running permanently:
[program:jambo-worker]command=php /var/www/jambo-api/bin/console messenger:consume async --time-limit=3600directory=/var/www/jambo-apiuser=www-datanumprocs=2autostart=trueautorestart=truestdout_logfile=/var/log/supervisor/jambo-worker.logstderr_logfile=/var/log/supervisor/jambo-worker-error.logsupervisorctl rereadsupervisorctl updatesupervisorctl start jambo-worker:*Production: Systemd
[Unit]Description=Jambo Messenger WorkerAfter=network.target
[Service]User=www-dataWorkingDirectory=/var/www/jambo-apiExecStart=php bin/console messenger:consume async --time-limit=3600Restart=alwaysRestartSec=5
[Install]WantedBy=multi-user.targetsystemctl enable jambo-workersystemctl start jambo-workerWebhook configuration
Webhooks are configured per-project in Project Settings → Webhooks. Each webhook specifies:
- URL — the endpoint to call
- Events — which events trigger the webhook (
entry.created,entry.updated,entry.deleted) - Secret — HMAC-SHA256 signature key (set
APP_WEBHOOK_SECRET_KEYin.env)
Verifying webhook signatures
Each webhook request includes an X-Jambo-Signature header:
X-Jambo-Signature: sha256=abc123...Verify it in your receiver:
$signature = 'sha256=' . hash_hmac('sha256', $rawBody, $secret);if (!hash_equals($signature, $request->headers->get('X-Jambo-Signature'))) { // Invalid signature — reject the request}