What's New in v8.11.0
🚀 Minor Release: Forward-by-ID, Outbound Proxy, Chatwoot Multi-Device Routing & History-Sync Group Fixes
This release adds forward-a-message-by-ID, an outbound WHATSAPP_PROXY for the WhatsApp WebSocket, a per-JID webhook ignore list, and full Chatwoot multi-device / multi-inbox routing. It also hardens the multi-device lifecycle by keying companion sessions on the full AD JID, recovers inbound group history that was previously dropped during history sync, and fixes Chatwoot group replies plus link-message storage.
✨ New Features
Forward Message by ID (#755)
- Adds
POST /message/{message_id}/forwardto forward a message already in local chat storage to another chat, with destinationphone, optionalduration, andforce_reupload - Rebuilds the whatsmeow protos from SQLite metadata (
BuildForwardMessageFromStorage), sets forwarded context (IsForwarded,ForwardingScore), and falls back to download + re-upload when media references are stale - v1 supports text and standard media (image, video, video note, audio, document, sticker); contact/location/poll/link/call return an explicit unsupported-type error
- Also exposed via the MCP tool
whatsapp_forward_message, OpenAPI docs, and the embedded UI (SendForward.js)
Outbound Proxy Support (#664)
- Adds
WHATSAPP_PROXY(SOCKS5 / HTTP / HTTPS) to route the WhatsApp WebSocket through an outbound proxy via whatsmeow'sSetProxyAddress - Standard
HTTP_PROXY/HTTPS_PROXYdo not apply to the WebSocket dialer, so this unblocks deployments behind DPI, corporate egress restrictions, or datacenter-ASN reputation issues - Wired into both the legacy single-client path and the multi-device path; empty/unset keeps the current direct-connection behavior (100% backward-compatible), and a bad URL logs a warning without aborting startup
Webhook JID Ignore List (#736)
- Adds
WHATSAPP_WEBHOOK_IGNORE_JIDS(and--webhook-ignore-jids), mirroringCHATWOOT_IGNORE_JIDS, to drop specific chats/JIDs from the generic webhook — e.g.@g.usmutes all group traffic - Supports the
@g.us/@s.whatsapp.net/@lidaddress-space wildcards and exact JIDs, matching the event'schat_idorfrom - Orthogonal to
WHATSAPP_WEBHOOK_EVENTS: an event forwards only if its type is allowed and its JID is not ignored; the default (no list) forwards unchanged
Chatwoot Multi-Device / Multi-Inbox Routing (#710)
- Routes each WhatsApp device to its own Chatwoot destination (URL + account + inbox + token) in both directions, configurable at runtime via REST
- New
ClientRegistryreplaces the Chatwoot singleton;CHATWOOT_*env is used only while thechatwoot_device_configstable is empty, then switches to fail-fast (unmapped devices are skipped on forward / error on reverse rather than silently using the global inbox) - Adds
POST /chatwoot/webhook/:device_id(route-by-config, validates payload account/inbox against the device config), account-scoped conversation lookup, echo-dedup partitioned by(accountID, messageID), and per-device sync services - REST CRUD:
GET /chatwoot/configs,GET/PUT/DELETE /devices/:device_id/chatwoot/config— API token masked on read and never logged, routing-identity edits blocked with 409 once links exist chatwoot_urlis validated (http(s) only, no embedded credentials, SSRF guard rejecting private/loopback/link-local/metadata addresses) with a connect-time re-check closing the DNS-rebinding window;CHATWOOT_ALLOWED_HOSTSis the escape hatch for trusted internal Chatwoot
Per-Device Login Endpoints
POST /devices/:device_id/loginand/devices/:device_id/login/codenow delegate to the app login usecase instead of returning not-implemented stubs; the QR handler returnsqr_linkandqr_durationlike/app/login
Chat Composer & Auto-Scroll
- Embedded chat UI gains a message composer and an auto-scroll refresh
🐛 Bug Fixes
Device Key Slot↔Companion Mapping by Full AD JID (#762)
- Two device slots on the same phone number are distinct companion sessions, but the multi-device lifecycle keyed the slot↔companion mapping by the bare-number JID, making siblings indistinguishable — causing session hijack, registry data loss (a legitimate second slot deleted on every boot), and reconnect churn / wrong-row deletes
- Tracks the full AD JID as the slot's companion identity via a new nullable
ad_jidcolumn (migration 35), mirrored fromStore.ID, persisted on connect, and backfilled at boot for older records - Lookups resolve by exact AD JID; a bare-number fallback resolves only when exactly one row matches (never guesses among siblings), and boot reconciliation no longer deletes ambiguous registry records — it logs and skips them
- Single-slot installs keep working unchanged; ambiguous legacy multi-slot state is logged instead of guessed
Inbound Group Messages Dropped During History Sync (#763)
- History sync read the group sender only from
key.participant, which is empty for synced group messages, so every inbound group message hit the "no participant info" branch and was discarded — a paired/re-paired device recovered only its own outbound group history - Falls back to the
WebMessageInfo-level participant (usually a@lid, then resolved viaNormalizeJIDFromLID) before giving up; verified against a real payload (198 skipped → 0, 149 inbound group messages now stored)
Chatwoot Group Message Send Failure (#739)
- Sending to a group chat from Chatwoot failed with "No destination phone for contact" when both the destination attribute and
contact.PhoneNumberwere empty - Falls back to
contact.Identifierso group replies route and send correctly
Send Link Storage Truncation (#661)
POST /send/linkstored a simplified content string that dropped the actual URL when a caption was present- Reuses a single composed text for both the WhatsApp payload and stored message content, so search/history views now show the full link text instead of a caption-only placeholder
🔧 Technical Improvements
Dependency Updates
go.mau.fi/whatsmeow: refreshed to the latest snapshot (v0.0.0-20260713112832-d8960d9575d2)github.com/gofiber/fiber/v2:v2.52.13→v2.52.14;github.com/valyala/fasthttp:v1.71.0→v1.72.0github.com/mark3labs/mcp-go:v0.54.0→v0.56.0modernc.org/sqlite:v1.50.1→v1.53.0;github.com/mattn/go-sqlite3:v1.14.45→v1.14.48- Plus minor bumps to brotli, klauspost/compress, pelletier/go-toml, golang.org/x/image, and others (
go get -u ./...+go mod tidy)
Release Metadata
AppVersionis nowv8.11.0, so runtime status matches the published release tag
What's Changed
- feat(message): add forward message by ID (#394) by @aldinokemal in #755
- fix send link storage by @juliomuhlbauer in #661
- feat(webhook): add WHATSAPP_WEBHOOK_IGNORE_JIDS to skip chats/JIDs (e.g. groups) by @huboperacional in #736
- feat(proxy): outbound WHATSAPP_PROXY env -> whatsmeow SetProxyAddress by @Flow-Mind-Company in #664
- fix(device): key slot↔companion mapping by full AD JID by @aldinokemal in #762
- feat: Chatwoot multi-device / multi-inbox support (#696) by @aldinokemal in #710
- fix: store inbound group messages from history sync (fall back to WebMessageInfo participant) by @nasirnaqash in #763
- fix: failed to send message to group chat by @yokowasis in #739
New Contributors
- @Flow-Mind-Company made their first contribution in #664
- @yokowasis made their first contribution in #739
Full Changelog: v8.10.0...v8.11.0