Frequently Asked Questions
You can send WhatsApp messages within your RedwoodJS application by integrating with the MessageBird API. This involves setting up a MessageBird account, configuring a WhatsApp channel, and then using the MessageBird Node.js SDK within your RedwoodJS services to send messages programmatically. This guide provides step-by-step instructions for setting up this integration and leveraging RedwoodJS functions and services.
MessageBird acts as a Communication Platform as a Service (CPaaS) provider, simplifying the complexities of the WhatsApp Business API. It provides the necessary infrastructure and API for sending and receiving WhatsApp messages, including template messages (HSM), through a unified interface that can be accessed through its Node.js SDK and REST API from your RedwoodJS application.
MessageBird simplifies WhatsApp integration by handling the complexities of the WhatsApp Business API. Combined with RedwoodJS, it offers a structured, serverless approach for building robust WhatsApp integrations with features like database message logging and secure handling of credentials, all within a full-stack JavaScript environment.
Incoming WhatsApp messages are handled using MessageBird webhooks. Set up a dedicated RedwoodJS function as your webhook endpoint and configure this URL within your MessageBird dashboard. Ensure proper signature verification for security. This function will receive message data and status updates and should be used to update your database or trigger other logic within your application.
Integrate the WhatsApp Business API by using MessageBird as an intermediary. You'll need a MessageBird account, an approved WhatsApp Business number, and the MessageBird Node.js SDK installed in your RedwoodJS API side. Configure your RedwoodJS services to make API calls to MessageBird, enabling your RedwoodJS application to send and receive WhatsApp messages.
The guide recommends PostgreSQL or a similar relational database to store message logs. Prisma, an ORM used by RedwoodJS, handles database interactions and migrations. This enables efficient storage and retrieval of message history, metadata, and delivery status updates.
ngrok
is useful during local development for testing your MessageBird webhook endpoint. It creates a public HTTPS tunnel to your local server, allowing MessageBird to deliver webhook events to your development environment. You will need to replace the ngrok URL with your application URL after deployment.
The webhook signing key is critical for security. This secret key, generated by you and configured within MessageBird, allows your webhook handler to verify the authenticity of incoming webhook requests. This prevents unauthorized actors from sending fake events to your application. It’s crucial to keep this key secure.
Prisma serves as the Object-Relational Mapper (ORM) in the RedwoodJS application. It simplifies database interactions, allowing you to define your data models (like MessageLog) and perform database operations (create, read, update, delete) using JavaScript instead of raw SQL. Prisma migrations also manage database schema changes.
RedwoodJS uses .env
files for environment variables. Store your MESSAGEBIRD_API_KEY
, MESSAGEBIRD_WHATSAPP_CHANNEL_ID
, and MESSAGEBIRD_WEBHOOK_SIGNING_KEY
in a .env
file in your project root. Ensure this file is added to your .gitignore
to avoid exposing sensitive information in version control.
The provided sendWhatsappMessage
service handles both 'text' messages and 'hsm' (Highly Structured Messages, also known as Template Messages). Ensure your 'content' payload matches the MessageBird API specification for each type. 'text' messages require a 'text' field, while 'hsm' messages require template details like namespace, templateName, and parameters.
The RedwoodJS service encapsulates the logic for interacting with the MessageBird API. This includes sending messages, handling different message types (text, HSM), logging messages to the database, and managing API errors. It helps keep your API routes clean and your business logic centralized.
Yes, you can send template messages (HSM) with this integration. Ensure you have pre-approved templates configured in your MessageBird account. When calling the sendWhatsappMessage
service, set the type
to 'hsm' and provide the required template details and parameters in the content.hsm
object.
A typical structure uses Redwood's functions to handle API requests and webhooks, services to interact with MessageBird's API and the database, and Prisma models to represent message logs. The 'api' directory houses backend code, including the MessageBird SDK. The 'web' directory handles the frontend. Your database, accessed via Prisma, stores message history and metadata.
WhatsApp Business API Integration with RedwoodJS and MessageBird: Complete Developer Guide
Build a production-ready WhatsApp Business API integration into your RedwoodJS application using the MessageBird API (now Bird). This comprehensive guide covers sending outbound WhatsApp messages (including pre-approved template messages), receiving inbound messages via webhooks, database logging with Prisma, and secure deployment patterns.
> Platform Update (February 2024): MessageBird rebranded as "Bird" with aggressive pricing cuts (up to 90% savings on SMS). The legacy MessageBird API and Node.js SDK remain fully functional and supported. For WhatsApp Business API integrations, you can use either the MessageBird platform (dashboard.messagebird.com) or the new Bird platform (app.bird.com). Both platforms support the same API endpoints documented in this guide. See Bird's platform documentation for migration details.
By the end of this guide, you'll have a functional RedwoodJS serverless application that leverages WhatsApp as a customer communication channel – perfect for notifications, support tickets, appointment reminders, and two-factor authentication.
Quick Reference: RedwoodJS WhatsApp Integration
What You'll Build: Full-stack RedwoodJS application with WhatsApp messaging via MessageBird/Bird API
Technologies: RedwoodJS v8, Node.js 20, MessageBird SDK v4.0.1, Prisma ORM, PostgreSQL, GraphQL
Key Components:
Prerequisites: Node.js 20+, Yarn 1.22.21+, MessageBird account, approved WhatsApp Business number
Time to Complete: 45–60 minutes
What is the WhatsApp Business API?
The WhatsApp Business API (officially the WhatsApp Business Platform) enables businesses to send and receive messages programmatically at scale. Unlike the WhatsApp Business app (designed for small businesses), the API supports:
MessageBird/Bird as CPaaS Provider: MessageBird (now Bird) acts as a Communication Platform as a Service (CPaaS) provider, simplifying WhatsApp Business API access. They handle Meta's complex onboarding, provide unified APIs across channels (SMS, WhatsApp, Voice), and offer embedded sign-up for faster deployment.
24-Hour Messaging Window: WhatsApp enforces a customer service window that opens when a user messages your business. During this 24-hour period, you can send any message type freely. Outside this window, you must use pre-approved template messages (called HSM – Highly Structured Messages) to initiate conversations. This policy prevents spam while enabling legitimate business communication.
What Problem Does This Integration Solve?
This integration allows businesses using RedwoodJS applications to leverage WhatsApp – a ubiquitous communication channel – for customer engagement, notifications, support, and potentially two-factor authentication, directly from their application's backend. It abstracts the complexities of the WhatsApp Business API through MessageBird's unified interface.
Project Goals:
Problem Solved:
This integration allows businesses using RedwoodJS applications to leverage WhatsApp – a ubiquitous communication channel – for customer engagement, notifications, support, and potentially two-factor authentication, directly from their application's backend. It abstracts the complexities of the WhatsApp Business API through MessageBird's unified interface.
Technologies Used:
ngrok
: For exposing local development webhook endpoints to the internet for testing.System Architecture:
Prerequisites:
ngrok
installed.Final Outcome:
By the end of this guide, you will have:
How Do You Set Up Your RedwoodJS Project?
We'll start with a fresh RedwoodJS project. If you have an existing project, adapt the steps accordingly.
Create RedwoodJS Project: Open your terminal and run:
Follow the prompts (choose JavaScript or TypeScript). This guide will use JavaScript examples, but the concepts are identical for TypeScript.
Verify Node/Yarn: Ensure your Node.js and Yarn versions meet RedwoodJS requirements.
Environment Variables: RedwoodJS uses
.env
files for environment variables. Create one in the project root:Add the following placeholders. You will get the actual values from your MessageBird dashboard later.
MESSAGEBIRD_API_KEY
: Your live API access key from the MessageBird Dashboard (Developers -> API access).MESSAGEBIRD_WHATSAPP_CHANNEL_ID
: The unique ID of your configured WhatsApp channel in MessageBird (Channels -> WhatsApp).MESSAGEBIRD_WEBHOOK_SIGNING_KEY
: A secret key you configure in MessageBird webhooks for request signature verification. Generate a strong random string for this.Important: Add
.env
to your.gitignore
file to avoid committing secrets. RedwoodJS automatically loads.env
variables intoprocess.env
.Install MessageBird SDK: Add the official MessageBird Node.js SDK to your project's API side dependencies.
This installs the SDK and adds it to
api/package.json
.Project Structure: RedwoodJS provides a clear structure:
api/
: Backend code (GraphQL API, serverless functions, services, database).api/src/functions/
: Serverless functions triggered via HTTP (our API endpoint and webhook).api/src/services/
: Business logic, interacting with external APIs (like MessageBird) and the database.api/db/
: Database schema (schema.prisma
) and migrations.web/
: Frontend React code. (We won't focus heavily on the UI in this guide).How Do You Design the Database Schema for Message Logging?
We need a way to store message history.
Define Prisma Schema: Open
api/db/schema.prisma
and add aMessageLog
model:?
) where data might not always be present (e.g.,messageBirdId
before sending,errorCode
on success).content
is stored as JSON to handle various message structures flexibly.@unique
constraint onmessageBirdId
helps prevent duplicate entries if webhooks are delivered multiple times.@@index
directives for potentially common query fields.Apply Migrations: Generate and apply the database migration.
This creates the SQL migration file and updates your database schema.
Prisma Client: RedwoodJS automatically generates and provides the Prisma client instance (
db
) available in services and functions. We'll use this later to interact with theMessageLog
table.How Do You Send WhatsApp Messages from RedwoodJS?
We'll create a RedwoodJS service to encapsulate the logic for sending messages via MessageBird.
Generate Service:
This creates
api/src/services/whatsapp/whatsapp.js
andwhatsapp.test.js
.Implement Sending Logic: Open
api/src/services/whatsapp/whatsapp.js
and add the following:Explanation:
messagebird
client using the API key from environment variables. Added checks for missing keys.sendWhatsappMessage
function takes the recipient (to
), messagetype
('text' or 'hsm'), and thecontent
payload.conversations.send
API endpoint. Crucially,from
is set to yourMESSAGEBIRD_WHATSAPP_CHANNEL_ID
.messageBirdId
). This ensures traceability even if the API call fails network-wise. Error logging includes details fromerror.errors
.messagebird.conversations.send
. The SDK uses callbacks, so we wrap it in aPromise
forasync/await
compatibility.type: 'hsm'
, thecontent
object must match the structure shown in the MessageBird API documentation. You need thenamespace
andtemplateName
from your approved template in the MessageBird dashboard. Parameter substitution happens via theparams
array (orcomponents
for media templates).try...catch
block handles API errors, logs them (including MessageBird-specific error details), updates the database record to 'failed', and includes error details.getMessageLogsByRecipient
is an example of how to query the logs using Prisma.How Do You Build the API Endpoint for Message Sending?
We need an HTTP endpoint to trigger our
sendWhatsappMessage
service. A RedwoodJS serverless function is perfect for this.Generate Function:
This creates
api/src/functions/sendWhatsapp.js
.Implement API Endpoint: Open
api/src/functions/sendWhatsapp.js
and implement the handler:Explanation:
POST
request with a JSON body.zod
for robust input validation (phone number format_ type enum_ basic content structure). Invalid requests are rejected with a400 Bad Request
and details.sendWhatsappMessage
service using the validated data.200 OK
response with the service result on success_ or appropriate error codes (400
_401
_403
_405
_500
) on failure. It attempts to map some known errors (like the 24-hour window) to more specific status codes/messages.Testing the Endpoint: Start the development server:
Install Zod if you haven't already:
Use
curl
or a tool like Postman to send a request (replace placeholders with your actual test number_ approved template details):Text Message (Requires user to have messaged you within 24h):
HSM Template Message (Can initiate conversation): (Replace
namespace
_templateName
_ and params with your actual approved template)HSM Media Template Example (Document): (Replace template details and document URL)
Check your terminal logs (
api |
) and the MessageLog table in your database. You should see the message logged_ and hopefully_ receive it on your test WhatsApp number. Test invalid inputs (bad phone number_ wrong type) to see the Zod validation errors.How Do You Handle Incoming WhatsApp Messages with Webhooks?
MessageBird uses webhooks to notify your application about incoming messages and status updates for outgoing messages.
Generate Webhook Function:
This creates
api/src/functions/messagebirdWebhook.js
.Implement Webhook Handler: Open
api/src/functions/messagebirdWebhook.js
:Explanation:
verifyMessageBirdSignature
function is crucial. It reconstructs the signature based on the timestamp, raw body, and your secret signing key (MESSAGEBIRD_WEBHOOK_SIGNING_KEY
) and compares it securely usingcrypto.timingSafeEqual
against the signature provided in themessagebird-signature
header. This prevents unauthorized requests. Headers are normalized to lowercase.message.created
(for incoming messages and potentially initial outgoing status) andmessage.updated
(for status changes like 'delivered', 'failed').message.created
,direction: 'received'
):MessageLog
with the samemessageBirdId
already exists. If so, it skips creation to prevent duplicates from potential webhook retries.MessageLog
record withdirection: 'incoming'
, storing the sender's number, content, type, and MessageBird timestamps.message.updated
):MessageLog
record (found viamessageBirdId
) with the newstatus
(e.g., 'sent', 'delivered', 'failed').200 OK
quickly to acknowledge receipt to MessageBird. Errors during processing return a500 Internal Server Error
.Local Testing with
ngrok
:yarn rw dev
).ngrok
:ngrok
will provide a public HTTPS URL (e.g.,https://<random-string>.ngrok.io
).ngrok
HTTPS URL followed by your function path:https://<random-string>.ngrok.io/messagebirdWebhook
message.created
andmessage.updated
..env
file forMESSAGEBIRD_WEBHOOK_SIGNING_KEY
.ngrok
terminal and logs in your Redwood API terminal showing the incoming message being processed./sendWhatsapp
endpoint. You should seemessage.updated
events arriving at the webhook as the message status changes (e.g., accepted -> sent -> delivered). Check theMessageLog
table for status updates.Deployment: When deploying your RedwoodJS application (e.g., to Vercel, Netlify, AWS Serverless), ensure:
MESSAGEBIRD_API_KEY
,MESSAGEBIRD_WHATSAPP_CHANNEL_ID
,MESSAGEBIRD_WEBHOOK_SIGNING_KEY
,DATABASE_URL
) are correctly configured in your deployment environment.https://your-app.com/api/messagebirdWebhook
)./sendWhatsapp
endpoint.Frequently Asked Questions
What is the difference between MessageBird and Bird?
MessageBird rebranded as "Bird" in February 2024, slashing prices by up to 90% on SMS to compete with Twilio. The legacy MessageBird API, Node.js SDK, and documentation remain fully functional. New customers can use either platform – both support the same WhatsApp Business API endpoints. Bird's platform (app.bird.com) offers the next-generation interface with unified pricing across channels.
How do WhatsApp template messages work in 2025?
WhatsApp template messages (also called HSM – Highly Structured Messages) must be pre-approved by Meta before use. As of July 2024, templates are categorized as Marketing, Utility, or Authentication. Marketing templates require explicit opt-out instructions (e.g., "Reply STOP to unsubscribe"). Utility templates are for transactional messages (order confirmations, shipping updates). All templates must be approved via the MessageBird or Bird dashboard before you can send them. Effective April 2025, Meta will automatically recategorize improperly labeled templates.
Can you send freeform WhatsApp messages outside the 24-hour window?
No. WhatsApp enforces a strict customer service window – you can only send freeform text messages within 24 hours of the user's last message. Outside this window, you must use pre-approved template messages. This policy combats spam while enabling legitimate business communication. Your RedwoodJS integration should detect 24-hour window violations (MessageBird error code 470) and fallback to template messages automatically.
What Node.js version does RedwoodJS require in 2025?
RedwoodJS requires Node.js 20 or higher as of version 8. However, if you're deploying to AWS Lambda or similar serverless platforms, avoid Node.js 21+ due to compatibility issues. Recommended: Node.js 20 LTS (supported until April 2026). The MessageBird SDK (v4.0.1) works with all current Node.js LTS versions (18, 20, 22).
How do you secure MessageBird webhooks in production?
Implement HMAC SHA-256 signature verification using the
MESSAGEBIRD_WEBHOOK_SIGNING_KEY
environment variable. MessageBird includes amessagebird-signature
header in each webhook request, computed from the request timestamp and body. Your RedwoodJS function must reconstruct this signature and compare it usingcrypto.timingSafeEqual()
(constant-time comparison) to prevent timing attacks. Never accept unsigned webhook requests in production – this prevents unauthorized parties from spoofing incoming messages.What is E.164 phone number format and why does it matter?
E.164 is the international phone number standard (ITU-T E.164): a plus sign (+) followed by country code and subscriber number (1–15 digits total, no spaces or special characters). Example:
+14155552671
for a US number. MessageBird requires all phone numbers in E.164 format. Use Zod validation (z.string().regex(/^\+[1-9]\d{1,14}$/)
) to enforce this format in your RedwoodJS API endpoints. Invalid formats cause message delivery failures and wasted API credits.How do you track WhatsApp message delivery status?
MessageBird sends webhook events (
message.updated
) as message status changes:pending
→accepted
→sent
→delivered
→read
. Your RedwoodJS webhook function updates the PrismaMessageLog
table with each status change. ThemessageBirdId
field (unique constraint) ensures idempotent updates. For failed messages, MessageBird provides error codes and descriptions viamsg.error.code
andmsg.error.description
. Store these in theerrorCode
anderrorDescription
fields for debugging.Can you use RedwoodJS GraphQL API instead of serverless functions?
Yes. While this guide uses RedwoodJS serverless functions (simpler for webhook endpoints), you can expose the WhatsApp sending logic via GraphQL mutations using the
@requireAuth
directive for authentication. GraphQL is ideal for integrating WhatsApp messaging into your existing RedwoodJS UI. However, webhooks should remain as serverless functions since MessageBird expects standard HTTP endpoints, not GraphQL queries.Conclusion and Next Steps
Congratulations! You've successfully built a production-ready WhatsApp Business API integration for RedwoodJS using MessageBird/Bird. You learned how to send WhatsApp messages (text and template formats), handle incoming messages via webhooks, log conversations with Prisma, validate phone numbers, and secure webhook endpoints with signature verification.
Next Steps & Potential Improvements:
web/
directory for customer service agents to view conversations and send responses.Conversation
model to group messages byconversationId
, track conversation state (open/closed), and assign conversations to agents.components
structure in template messages or direct media URLs in freeform messages.Code Repository
[Actual repository link should be inserted here if available]
This foundation enables you to build powerful, compliant WhatsApp Business integrations in your RedwoodJS applications. Happy coding!
Sources: