v8.11.0

Mail-0/Zerov8.11.0Jul 13, 2026by aldinokemal

AI Summary

This release adds significant new capabilities including message forwarding by ID, outbound proxy support for WhatsApp WebSocket, and comprehensive multi-device Chatwoot routing. It also fixes critical bugs regarding device key mapping and inbound group history sync.

Key Highlights

  • Forward message by ID functionality
  • Outbound proxy support (WHATSAPP_PROXY) for WebSocket
  • Chatwoot multi-device and multi-inbox routing
  • Fix for device key slot mapping using full AD JID

New Features

  • Forward Message by ID API endpoint
  • Outbound proxy support (SOCKS5/HTTP/HTTPS)
  • Webhook JID ignore list for filtering chats
  • Chatwoot multi-device routing with per-device configs
  • Per-device login endpoints
  • Chat composer and auto-scroll in embedded UI

Full Release Notes

## 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}/forward` to forward a message already in local chat storage to another chat, with destination `phone`, optional `duration`, and `force_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's `SetProxyAddress`
- Standard `HTTP_PROXY` / `HTTPS_PROXY` do 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`), mirroring `CHATWOOT_IGNORE_JIDS`, to drop specific chats/JIDs from the generic webhook — e.g. `@g.us` mutes all group traffic
- Supports the `@g.us` / `@s.whatsapp.net` / `@lid` address-space wildcards and exact JIDs, matching the event's `chat_id` **or** `from`
- 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 `ClientRegistry` replaces the Chatwoot singleton; `CHATWOOT_*` env is used only while the `chatwoot_device_configs` table 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_url` is 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_HOSTS` is the escape hatch for trusted internal Chatwoot

### Per-Device Login Endpoints
- `POST /devices/:device_id/login` and `/devices/:device_id/login/code` now delegate to the app login usecase instead of returning not-implemented stubs; the QR handler returns `qr_link` and `qr_duration` like `/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_jid` column (migration 35), mirrored from `Store.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 via `NormalizeJIDFromLID`) 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.PhoneNumber` were empty
- Falls back to `contact.Identifier` so group replies route and send correctly

### Send Link Storage Truncation (#661)
- `POST /send/link` stored 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.0`
- `github.com/mark3labs/mcp-go`: `v0.54.0` → `v0.56.0`
- `modernc.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
- `AppVersion` is now `v8.11.0`, so runtime status matches the published release tag

---

## What's Changed
* feat(message): add forward message by ID (#394) by @aldinokemal in https://github.com/aldinokemal/go-whatsapp-web-multidevice/pull/755
* fix send link storage by @juliomuhlbauer in https://github.com/aldinokemal/go-whatsapp-web-multidevice/pull/661
* feat(webhook): add WHATSAPP_WEBHOOK_IGNORE_JIDS to skip chats/JIDs (e.g. groups) by @huboperacional in https://github.com/aldinokemal/go-whatsapp-web-multidevice/pull/736
* feat(proxy): outbound WHATSAPP_PROXY env -> whatsmeow SetProxyAddress by @Flow-Mind-Company in https://github.com/aldinokemal/go-whatsapp-web-multidevice/pull/664
* fix(device): key slot↔companion mapping by full AD JID by @aldinokemal in https://github.com/aldinokemal/go-whatsapp-web-multidevice/pull/762
* feat: Chatwoot multi-device / multi-inbox support (#696) by @aldinokemal in https://github.com/aldinokemal/go-whatsapp-web-multidevice/pull/710
* fix: store inbound group messages from history sync (fall back to WebMessageInfo participant) by @nasirnaqash in https://github.com/aldinokemal/go-whatsapp-web-multidevice/pull/763
* fix: failed to send message to group chat by @yokowasis in https://github.com/aldinokemal/go-whatsapp-web-multidevice/pull/739

## New Contributors
* @Flow-Mind-Company made their first contribution in https://github.com/aldinokemal/go-whatsapp-web-multidevice/pull/664
* @yokowasis made their first contribution in https://github.com/aldinokemal/go-whatsapp-web-multidevice/pull/739

**Full Changelog**: https://github.com/aldinokemal/go-whatsapp-web-multidevice/compare/v8.10.0...v8.11.0