Skip to content

feat(whatsapp): rich messaging — lists, location/contacts/template sends, inbound reply metadata - #6

Merged
PauGuirao merged 3 commits into
mainfrom
feat/whatsapp-rich-messaging
Jun 25, 2026
Merged

feat(whatsapp): rich messaging — lists, location/contacts/template sends, inbound reply metadata#6
PauGuirao merged 3 commits into
mainfrom
feat/whatsapp-rich-messaging

Conversation

@PauGuirao

Copy link
Copy Markdown
Contributor

Why

The adapter sent text + reply buttons, but dropped WhatsApp's richer messaging: interactive lists, location/contacts, templates, and inbound button/list/flow replies were invisible. Scope follows the official Kapso adapter — messaging that maps to Chat SDK primitives lives in the adapter; WhatsApp-only sends go through the exported client used alongside. Calls + delivery-status are intentionally out (no Chat SDK primitive).

What

  • card-mapper: Select/RadioSelect → WhatsApp interactive list (was dropped). Fixes wrong structural types (options, radio_select).
  • ZernioApiClient: sendInteractive (buttons/list/cta_url/flow/location-request/voice-call), sendLocation, sendContacts, sendTemplate, reply.
  • types: extended send body + new WhatsApp content types; inbound interactive-reply metadata (interactiveType/interactiveId/flowResponse/referral/quoted).
  • adapter: surfaces inbound metadata on message.raw.metadata; wires card interactive into the send body.
  • tests: +10 (94 passing), typecheck clean.

Follow-ups

  • README support matrix not yet updated to reflect list/interactive support.

🤖 Generated with Claude Code

PauGuirao and others added 3 commits June 25, 2026 09:45
…/template sends, inbound reply metadata

Adds the WhatsApp messaging surface that maps to Chat SDK primitives, plus
direct-client helpers for the WhatsApp-only types (the "alongside client"
pattern the official Kapso adapter uses). Calls and delivery-status are
intentionally out of scope — the Chat SDK has no such primitive.

- card-mapper: Select/RadioSelect now map to a WhatsApp interactive list
  (previously dropped). Fixes the wrong structural types (options/radio_select).
- ZernioApiClient: sendInteractive (buttons/list/cta_url/flow/location-request/
  voice-call), sendLocation, sendContacts, sendTemplate, reply (quote).
- types: extend send body (interactive/location/contacts/WA template/voice note/
  replyTo/sticker), new WhatsApp content types, inbound interactive-reply
  metadata (interactiveType/interactiveId/flowResponse/referral/quoted).
- adapter: surface inbound metadata on message.raw.metadata; wire card
  interactive into the send body; safer attachment-type mapping.
- tests: +10 (lists, client helpers, inbound metadata, call/status ignored).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Closes the one capability Kapso had that we lacked: starting a conversation
from a phone number with no prior inbound.

- openDM(userId): standard Chat SDK method. userId is "{accountId}:{recipient}"
  (one account = one channel). Resolution-only, no network — the inbox send
  endpoint accepts the recipient handle as the conversation id, so the first
  post() opens the thread.
- openConversation({ accountId, to, message?, template? }): cold-starts via
  POST /v1/inbox/conversations, returning the thread id. WhatsApp needs a
  template (24h-window rule); other platforms can open with message.
- ZernioApiClient.createConversation() wraps the endpoint.
- tests: +4 (98 passing).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…tive replies, openDM/openConversation

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@PauGuirao
PauGuirao merged commit c4f924b into main Jun 25, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant