A webhooks, reliability, and dashboard release — no breaking changes; everything is additive or a
fix. Webhooks gain optional smart pre-dispatch filters: a trigger can carry AND-ed conditions
(sender/recipient/body/type/mentions/fromMe/hasMedia/isGroup) and fires only when they all match,
with engine-neutral WaId contact matching and a FilterBuilder UI — a webhook with no filters
behaves exactly as before. The whatsapp-web.js engine's first-boot init timeout is now configurable
(WWEBJS_AUTH_TIMEOUT_MS) for slow environments. Fixed: the dashboard no longer crashes on
PostgreSQL when a webhook exists (a JSON column type mismatch). Dashboard: a downed backend no
longer floods the screen with error toasts.
Added
-
Smart webhook filters (optional, additive). A webhook trigger can now carry an optional set of
pre-dispatch conditions, evaluated per event before delivery: it fires only when all conditions
match (AND). Conditions match onsender/recipient/body/type/mentions/fromMe/
hasMedia/isGroupwithis/isNot/contains/equalsoperators;
message-only conditions are skipped for non-message events, so a*-subscribed webhook still fires on
session events. A webhook with no filters behaves exactly as before. Contact-id conditions
(sender/recipient/mentions) match by the engine-neutralWaIdkey, so a filter written as a
plain number or in any dialect (@c.us/@s.whatsapp.net/@lid) matches the same person - and a
lid-addressed sender (e.g. an unresolved@lidgroup participant) matches a phone filter once the
persistentlid -> phonetable knows the mapping. Configurable via the API (filterson create/update)
and a new FilterBuilder UI on the dashboard's Webhooks page. (#379) -
Configurable first-boot init timeout for the whatsapp-web.js engine (
WWEBJS_AUTH_TIMEOUT_MS).
On slow first boots (e.g. WSL2 or low-resource containers) the engine's fixed 30s wait for WhatsApp
Web to finish loading could expire before the QR code was generated, aborting startup. Set
WWEBJS_AUTH_TIMEOUT_MSto a larger value in milliseconds (e.g.120000) to extend it; unset keeps
the previous 30000ms default, so existing deployments are unchanged. (#353)
Changed
- Dashboard collapses connection-error spam into a single toast. When the backend is unreachable
(failed to fetch, network errors, HTTP 502/503), the dashboard now shows one translated "Server
Connection Lost" toast that auto-dismisses, instead of stacking an error toast per failed request —
de-duplicated on a stable key so translation can't break it. Original work by @quinton-8. (#293)
Fixed
- Dashboard no longer crashes ("Something went wrong") when a webhook exists on PostgreSQL. JSON
columns (webhooks.events/headers,sessions.config,messages.metadata,message_batches.*)
were declaredjsonbin their entities but created astextby the baseline migration, so on
Postgres the driver returned them as raw JSON strings and the dashboard'sevents.map()threw an
uncaught error.jsonColumnType()now resolves tosimple-jsonon both dialects (parsed in JS on
read) — no schema migration or data conversion, since the write format was already identical. This
also corrects the same latent string-instead-of-object behavior for session reconnect config,
message-reaction persistence, and bulk-send batches on Postgres. The dashboard additionally
normalizes webhookeventsto an array at the query boundary as defense-in-depth. (#385)