Repository navigation
feat(messaging): WhatsApp adapter for one-time codes - #267
Merged
Merged
Conversation
…templates Meta's Cloud API is the common denominator behind every WhatsApp OTP route (Twilio, Vonage and Infobip all still require the customer's own business account), so the adapter talks to the Graph API directly. It models WhatsApp as an SMS-type adapter because callers already send the bare code as the message content, which is the only thing an authentication template accepts. The code is validated to Meta's 15-character alphanumeric limit before any request leaves, and Graph API errors keep their numeric code so callers can tell throughput limits from configuration mistakes. upsertTemplate() lets a host provision the template in every language it needs.
ChiragAgg5k
requested review from
Meldiron,
abnegate,
eldadfux and
loks0n
as code owners
September 14, 2026 17:34
Contributor
|
…alling Meta An SMS with no recipient reached the [0] access and died with a TypeError rather than a clear argument error, and a time to live outside Meta's documented 60 to 600 second window (or -1) was sent anyway only to fail remotely. Both are now validated locally. Tests assert what a caller can observe (code in both parameters, digits-only recipient, chosen language, bearer credential) instead of pinning the whole request body and version.
…mber The unit tests prove the request shape with a fake client but never reach the Graph API. This suite runs in the e2e tier against Meta's free developer test number, which can message five allow-listed recipients, and is skipped unless the TESTS_WHATSAPP_* secrets are present so forks and PRs without credentials stay green.
…account can run Meta's free test account ships sample templates only and refuses to create new ones, so no authentication template exists to deliver a code with. The suite now covers what that account does answer for real: an unknown template (132001), a recipient outside the allow list (131030) and a bad bearer token (190), each through the full request path. The in-process unit suite goes away so WhatsApp has one test that talks to the real API.
ChiragAgg5k
force-pushed
the
feat/messaging-whatsapp-otp-adapter
branch
from
September 15, 2026 09:36
93edd21 to
dc1c2d4
Compare
…face A host will want more than a fixed template and language per adapter: per-message template and language overrides let one instance serve login, verification and MFA flows, and biz_opaque_callback_data lets delivery webhooks be matched back to the record that triggered the send, which is what a fallback to SMS on failure needs. Template creation now supports one-tap and zero-tap autofill with the Android apps Meta requires, and templates can be looked up and deleted so a host can check approval before sending and clean up after itself.
…figuration The suite pinned the sample template's approval status and language, the exact refusal code for template creation, and Meta's error prose. Those are provider details that can change without an adapter regression. It now checks what a caller relies on: the requested template's languages come back with a status, rejections surface as exceptions carrying a numeric code, and a per-message template override reaches Meta.
loks0n
approved these changes
Sep 16, 2026
This branch had an error being deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Users want to receive login and verification codes over WhatsApp instead of SMS. Every WhatsApp OTP route ends at Meta's Cloud API, and the aggregators (Twilio Verify, Vonage Verify, Infobip) all still require the customer's own WhatsApp Business Account, so calling the Graph API directly is the common denominator and adds no second vendor.
What
Adapter\SMS\WhatsApp: sends a code through a Meta authentication template (POST /{version}/{phoneNumberId}/messages). WhatsApp is modelled as an SMS-type adapter because callers already send the bare code as the message content, and a fixed-text authentication template accepts nothing else. The content is validated against Meta's 15-character alphanumeric limit before any request leaves, the recipient is reduced to digits as the Cloud API requires, and the code is passed in both the body and the copy-code button parameters.Error <code>: <message>: <details>so a host can tell throughput limits (130429, 131056) from configuration mistakes (132001, 190) and undeliverable recipients (131026).upsertTemplate()provisions the template in every requested language viaupsert_message_templates, with optional expiry footer, security recommendation and TTL. Authentication templates are approved automatically, so this is a one-call setup.WhatsApp\MetadataParameter::LANGUAGEoverrides the template language per message, mirroring the Msg91 metadata pattern.End-to-end testing
The suite runs against a real Meta developer test number in the
e2etier and is skipped when theTESTS_WHATSAPP_*secrets are absent. Meta's free test account ships sample templates only and refuses to create new ones, so there is no authentication template to deliver a code with; the suite covers the full request path and the error responses the account does return: unknown template (132001), recipient outside the allow list (131030) and invalid bearer token (190). All three pass against the live API.Sample templates sent from the same test number and token land on the allow-listed phone, which confirms the number, token and recipient setup the tests rely on:
The developer dashboard for the app, showing the test number, the allow-listed recipient and the webhook events produced by the runs:
Follow-up
Appwrite wiring (worker
getSmsAdaptermatch, DSN parsing, per-project channel option) lands after this is taggedmessaging/2.2.0. Delivering a real code end to end needs a WhatsApp Business Account we own, which requires registering a phone number in Meta's production setup.