v8.10.0

pascalorg/editorv8.10.0Jul 3, 2026by aldinokemal

AI Summary

This release introduces passkey device pairing, per-device webhook URL overrides, and a REST endpoint for WhatsApp newsletter message history. It also expands MCP tools for media sends and message manipulation while fixing incoming media downloads and device logout behavior.

Key Highlights

  • Phone-initiated passkey device pairing
  • Per-device webhook URL overrides with global fallback
  • REST endpoint for WhatsApp newsletter message history
  • Expanded MCP tools for media sends and message manipulation

Breaking Changes

  • Device logout behavior changed: logout no longer deletes the device slot, requiring explicit DELETE for removal
  • POST /devices now accepts webhook_secret, webhook_events, and webhook_insecure_skip_verify parameters

New Features

  • Passkey Pairing Support (WebAuthn challenge polling and response submission)
  • Per-Device Webhook URLs (PATCH and GET endpoints per device)
  • Newsletter Message History (GET /newsletter/messages endpoint)
  • Expanded MCP Send & Message Tools (video, document, audio, polls, react, edit, revoke, delete, mark-as-read, star/unstar)

Full Release Notes

## What's New in v8.10.0

šŸš€ **Minor Release: Passkey Pairing, Per-Device Webhooks, Newsletter Message History & Media Download Fix**

This release adds phone-initiated passkey device pairing, per-device webhook URL overrides with global fallback, a REST endpoint to fetch newsletter (WhatsApp channel) message history, and a broad MCP tool expansion for media sends and message manipulation. It also fixes incoming media downloads that failed with "no url present", makes device logout disconnect the session without deleting the device slot, and stops `POST /send/file` from panicking on non-multipart requests.

---

## ✨ New Features

### Passkey Pairing Support (#754)
- Adds `GET /app/passkey` to poll a pending WebAuthn challenge or pairing code and its status (`none` / `awaiting_response` / `awaiting_confirmation`)
- Adds `POST /app/passkey/response` to submit the signed WebAuthn assertion, and `POST /app/passkey/confirm` to confirm the pairing code when the phone's 5-minute handoff window has lapsed
- Broadcasts `PASSKEY_REQUEST` / `PASSKEY_CONFIRMATION` / `PASSKEY_ERROR` over the existing websocket, with minimal web UI toasts
- Pending passkey state is stored per device and cleared on pair success, logout, error, or fresh login; the QR login loop no longer logs passkey channel events as errors

### Per-Device Webhook URLs (#671)
- Adds `PATCH /devices/{device_id}/webhook` and `GET /devices/{device_id}/webhook` so each device can override the global webhook URL, falling back to `WHATSAPP_WEBHOOK` when unset
- Closes gaps found in review: label appstate events now forward correctly on a device-only webhook, a device-webhook lookup failure falls back to global instead of aborting delivery, and `POST /devices` now accepts `webhook_secret`, `webhook_events`, and `webhook_insecure_skip_verify` (previously silently dropped)

### Newsletter Message History (#749)
- Adds `GET /newsletter/messages?newsletter_id=...&count=...&before=...`, backed by whatsmeow's `GetNewsletterMessages`, returning `server_id`, `message_id`, `type`, `timestamp`, `views_count`, `reaction_counts`, and extracted `text`
- `count` defaults to 50 (max 100); `before` pages backward by server message id
- Rejects non-newsletter JIDs up front with a clear validation error instead of failing deep inside a WhatsApp protocol round-trip

### Expanded MCP Send & Message Tools (#722)
- Adds MCP send tools for video, document, audio, and polls
- Adds message-manipulation tools: react, edit, revoke, delete, mark-as-read, and star/unstar, with destructive-hint annotations on revoke/delete
- Send handlers migrated to `mcp-go`'s typed request helpers (`RequireString`/`GetBool`/`GetInt`/`GetStringSlice`), matching the existing query tool conventions

---

## šŸ› Bug Fixes

### Incoming Media Downloads Failing with "no url present" (#722)
- whatsmeow's `Client.Download` reads only `DirectPath`, never the stored `URL`, so every reconstructed media message failed to download even though a URL was on file
- Derives `DirectPath` from the already-stored URL at download time (`utils.DeriveDirectPath`) for both the REST/MCP download path and Chatwoot media sync — no migration or backfill needed, previously-received media is downloadable immediately
- Also fixes dropped incoming location messages: adds `FormatLocationSummary` and location/live-location handling to message-text extraction, plus a caption-less extended-text fallback

### Device Logout No Longer Deletes the Device Slot (#728)
- `POST /devices/{id}/logout`, `GET /app/logout`, and a remote unlink from the phone now disconnect the session and clear keys while keeping the device listed, so it can be re-paired under the same id
- Deleting a slot entirely is now exclusively `DELETE /devices/{id}`, which performs a full purge (logout + WhatsApp unlink + registry removal) instead of leaving orphaned rows
- Chat history is preserved on logout and only cleared on delete, matching WhatsApp Web's own behavior; a new `DEVICE_LOGGED_OUT` websocket event keeps the current UI selection

### Non-Multipart `POST /send/file` Panic (#748)
- `SendFile` unconditionally panicked when no multipart file part was present, unlike the sibling `SendImage`/`SendVideo`/`SendAudio`/`SendSticker` handlers, which all guard the lookup
- This made the existing `file_url` JSON-body path unreachable dead code; a non-multipart request now falls through to usecase-level validation instead of a 500

### Chatwoot Contact Creation on Newsletter JIDs
- WhatsApp channel (`@newsletter`) JIDs carry an 18-digit channel id rather than a phone number, so relaying one to Chatwoot failed contact creation with a 422 e164 error
- Adds a shared `utils.IsNewsletterJID` guard to both the live webhook-forward path and the history importer

### Broadcast Messages Leaking to Webhooks with Chatwoot Enabled
- `status@broadcast` messages were only skipped from webhook forwarding when Chatwoot was disabled, so enabling Chatwoot let broadcast/status noise reach plain webhook consumers
- Broadcast/status messages are now skipped unconditionally; `SetDeviceWebhookConfig` also now returns `sql.ErrNoRows` instead of silently no-oping when the target device doesn't exist

---

## šŸ”§ Technical Improvements

### Dependency Updates
- `go.mau.fi/whatsmeow`: refreshed to `v0.0.0-20260630180629-b572e5bcb92b`
- `github.com/vektah/gqlparser/v2`: updated to `v2.5.36`

### Documentation
- OpenAPI spec adds the public health endpoint and marks reserved device-login routes as deprecated
- Documents per-device webhook configuration and new label-related webhook events; refreshed README defaults and event list

### Release Metadata
- `AppVersion` is now `v8.10.0`, so runtime status matches the published release tag

---

## What's Changed
* fix: don't panic on non-multipart POST /send/file requests by @aldinokemal in https://github.com/aldinokemal/go-whatsapp-web-multidevice/pull/748
* feat(newsletter): add endpoint to get latest newsletter messages by @aldinokemal in https://github.com/aldinokemal/go-whatsapp-web-multidevice/pull/749
* fix(media): download incoming media via derived directPath by @nazhiba in https://github.com/aldinokemal/go-whatsapp-web-multidevice/pull/722
* fix(device): logout should disconnect session, not delete device entry by @huboperacional in https://github.com/aldinokemal/go-whatsapp-web-multidevice/pull/728
* feat(app): add passkey pairing support by @aldinokemal in https://github.com/aldinokemal/go-whatsapp-web-multidevice/pull/754
* feat: add per-device webhook support by @mohamedhabibwork in https://github.com/aldinokemal/go-whatsapp-web-multidevice/pull/671
* fix(webhook): skip broadcast messages and return no rows for missing devices by @aldinokemal
* test(utils): cover location summary and extended-text fallback from #722 by @aldinokemal
* refactor(mcp): migrate send handlers to mcp-go request helpers by @aldinokemal
* fix(webhook): close per-device webhook gaps from #671 review by @aldinokemal
* fix(chatwoot): skip @newsletter JIDs before contact creation by @aldinokemal
* docs: update API and webhook documentation by @aldinokemal
* chore: update whatsmeow to latest by @aldinokemal
* chore: bump version to v8.10.0 by @aldinokemal

## New Contributors
* @nazhiba made their first contribution in https://github.com/aldinokemal/go-whatsapp-web-multidevice/pull/722
* @huboperacional made their first contribution in https://github.com/aldinokemal/go-whatsapp-web-multidevice/pull/728
* @mohamedhabibwork made their first contribution in https://github.com/aldinokemal/go-whatsapp-web-multidevice/pull/671

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