Frequently Asked Questions
Create a RedwoodJS service to handle the messaging logic, integrate the MessageBird Node.js SDK, and expose the service through a GraphQL mutation. This allows your application to send SMS messages programmatically via the MessageBird API.
MessageBird acts as the third-party SMS gateway provider. The RedwoodJS application integrates with MessageBird's API using their Node.js SDK, allowing you to send SMS messages directly from your RedwoodJS application.
RedwoodJS offers a full-stack, serverless-friendly framework with built-in GraphQL and Prisma, simplifying development and deployment. Its structured approach promotes code organization and maintainability for campaign management.
Set a MESSAGEBIRD_DEFAULT_ORIGINATOR
environment variable if you want a consistent sender ID for most campaigns. This simplifies the API call but can be overridden per campaign if needed. If not set, a generic default might be used, potentially affecting deliverability.
The basic implementation provides submission status. For detailed delivery reports (e.g., delivered, failed), configure MessageBird webhooks to receive real-time updates and store them in a database.
Install the MessageBird Node.js SDK, obtain your Live API Key from the MessageBird dashboard, and store it securely in a .env
file in your project root. Never commit API keys directly into your code.
The core technologies include RedwoodJS, Node.js, MessageBird, Prisma (ORM), GraphQL, and Jest (testing). This combination provides a robust and efficient platform for building and managing SMS campaigns.
Error handling ensures your application gracefully manages issues like invalid recipient numbers, network problems, or MessageBird API errors. Implement try-catch blocks, logging, and retry mechanisms in your RedwoodJS service.
Retry logic is useful for handling transient errors, such as temporary network issues or brief MessageBird service disruptions. Use a library like async-retry
to manage retries with exponential backoff.
Be aware of the 160-character limit for standard SMS. Longer messages are split (concatenated), impacting cost. Inform users of potential extra charges. Unicode (emoji) messages have a 70-character limit.
Use the E.164 format (+[country code][number]) for maximum compatibility, especially with international numbers. Consider using a library like libphonenumber-js
for validation and normalization.
Storing campaign information in a database using Prisma allows you to track campaign history, monitor status (submitted, failed, etc.), and analyze campaign performance over time.
Use Redwood's authentication (e.g., requireAuth
, @requireAuth
), validate and sanitize user inputs, protect your MessageBird API key, and implement rate limiting to prevent abuse.
Alphanumeric sender IDs are supported in many countries but not all. Check MessageBird's documentation for country-specific regulations. In some regions (e.g., US/Canada), pre-registered numbers are required.
Adhere to MessageBird's best practices, including using registered sender IDs, handling opt-outs correctly, ensuring valid recipient numbers, and monitoring delivery reports via webhooks.
Build RedwoodJS Marketing Campaigns with MessageBird and Node.js
Build a comprehensive SMS marketing campaign system using RedwoodJS, MessageBird SMS API, and Node.js GraphQL backend. This step-by-step guide covers RedwoodJS SMS integration from initial project setup through production deployment and verification. You'll learn how to create a marketing automation system that sends bulk SMS campaigns, tracks delivery status, and handles errors gracefully.
Important Platform Update (2025): MessageBird rebranded as Bird in February 2024. The legacy MessageBird platform (dashboard.messagebird.com) shuts down March 31, 2025. For new implementations after this date, use the Bird next-gen platform (app.bird.com), though the MessageBird API and Node.js SDK remain functional during the transition. See Bird's migration documentation for details.
By the end of this tutorial, you'll have a RedwoodJS application with a GraphQL API endpoint that accepts campaign details (message content, recipient list) and uses the MessageBird SDK to dispatch SMS messages. This solves the common need to programmatically send bulk or targeted SMS campaigns for marketing or notifications.
Project Overview and Goals
Create a robust system within a RedwoodJS application that sends SMS marketing messages through MessageBird.
Key Goals:
Technologies Used:
System Architecture:
Prerequisites:
node -v
. Install from nodejs.org.yarn -v
.What You'll Build:
You'll create a functional RedwoodJS application endpoint that receives recipient numbers and a message, sends SMS messages via MessageBird, and provides feedback on the operation's success or failure.
How to Set Up Your RedwoodJS Project for SMS Integration
Initialize your project, install dependencies, and set up the basic structure.
Create RedwoodJS App: Open your terminal and run the RedwoodJS create command:
Follow the prompts (choosing JavaScript or TypeScript). For this guide, we'll assume JavaScript, but the steps are very similar for TypeScript.
Navigate to Project Directory:
Install MessageBird SDK: Install the MessageBird Node.js SDK specifically in the
api
workspace.Environment Variables: RedwoodJS uses
.env
files for environment variables. The.env.defaults
file is committed to git and holds default (non-sensitive) values. The.env
file (which should be in your.gitignore
) holds sensitive keys.Create the
.env
file in the project root:Add your MessageBird API Key and optionally a default originator to
.env
. You'll retrieve the API key in Section 4.Add placeholders to
.env.defaults
so others know what's needed:Ensure
.env
is listed in your root.gitignore
file (Redwood typically adds this by default). TheMESSAGEBIRD_API_KEY
is your secret credential. TheMESSAGEBIRD_DEFAULT_ORIGINATOR
is the default sender ID or number if not provided in the request (see Section 4.3).Project Structure: RedwoodJS has a specific structure:
api/
: Backend code (GraphQL API, services, database schema).web/
: Frontend React code.scripts/
: Utility scripts.Focus primarily on the
api/
directory, specificallyapi/src/graphql
,api/src/services
, and potentiallyapi/db
. This structure separates concerns, making the application easier to manage.How to Implement the MessageBird Service Layer
Implement the core logic for interacting with MessageBird within a RedwoodJS service. Services contain your business logic on the API side.
Generate Service: Use the RedwoodJS CLI to generate a service file for handling marketing campaigns.
This creates
api/src/services/marketingCampaigns/marketingCampaigns.js
(and related files like tests).Implement Sending Logic: Open
api/src/services/marketingCampaigns/marketingCampaigns.js
and add the logic to send messages.Why this approach?
try...catch
for robustness and provides informative error messages based on the SDK's potential error structureHow to Build the GraphQL API for SMS Campaigns
Expose the service function via a GraphQL mutation.
Define GraphQL Schema (SDL): Create/edit the GraphQL schema definition file for marketing campaigns.
Open
api/src/graphql/marketingCampaigns.sdl.js
and define the input type and mutation.Explanation:
SendCampaignInput
: Defines the structure of the data needed to call the mutation. Using input types keeps mutations clean.CampaignStatus
: Defines the structure of the response returned by the mutation.sendMarketingCampaign
: The mutation itself, linking to thesendMarketingCampaign
function in your service (Redwood maps this automatically by name convention). It takes the input and returns the status.@skipAuth
/@requireAuth
: Redwood's directive for controlling access. Use@requireAuth
once you have authentication implemented.@skipAuth
makes it publicly accessible (use with caution in production).Testing the Endpoint (GraphQL Playground): RedwoodJS includes a GraphQL Playground.
Start the development server:
Navigate to
http://localhost:8910/graphql
.Use the following mutation (replace placeholders):
Execute the mutation. You should see a response like:
Or an error response if something went wrong:
How to Configure MessageBird API Credentials
Configure the MessageBird SDK correctly to ensure proper functionality.
Obtaining the API Key:
Storing the API Key Securely:
As done in Step 1.4, paste the copied Live API Key into your
.env
file in the project root:Never commit your
.env
file or your API key directly into your code or version control (Git). Redwood's default.gitignore
already includes.env
.Understanding Environment Variables:
MESSAGEBIRD_API_KEY
: (Required) Your secret credential for authenticating with the MessageBird API. The SDK (require('messagebird').initClient()
) automatically looks for this environment variable. Format: A string likelive_xxxxxxxxxxxxxxxxxxxx
. Obtain from: MessageBird Dashboard > Developers > API access (or Bird platform > Settings > API Keys after March 31, 2025).MESSAGEBIRD_DEFAULT_ORIGINATOR
: (Optional) Set a default sender ID or phone number here if you don't want to specify it in every API call. If not set here and not provided in the mutation input, a generic default like "Campaign" might be used, which could impact deliverability. Format: A string (e.g., "MyCompany", "+15551234567"). Obtain/Configure in: MessageBird Dashboard > Numbers or Sender IDs.Fallback Mechanisms: The current code doesn't explicitly implement complex fallback mechanisms for MessageBird outages. For critical systems, consider:
How to Handle Errors and Implement Retry Logic
Handle failures gracefully in your application.
Error Handling Strategy:
try...catch
). Log detailed errors usinglogger.error()
. Return structured error information or throw specific GraphQL errors (UserInputError
,AuthenticationError
, etc.) for the API layer. The current implementation returns a structured error within theCampaignStatus
object.CampaignStatus
), that object returns in thedata
field. If the service throws an error, it appears in theerrors
field of the GraphQL response.error.errors
(an array) for specific API validation issues (e.g., invalid recipient number, insufficient balance). Log these details. The current error handling extracts the first error description.Logging:
pino
for logging. Uselogger.info()
,logger.warn()
,logger.error()
, etc., within your service.api/src/lib/logger.js
as needed.Retry Mechanisms (Basic Example): For transient network issues or temporary MessageBird problems, a simple retry can help. Use libraries like
async-retry
or implement a basic loop.Install
async-retry
:Modify the service function:
Testing Errors:
MESSAGEBIRD_API_KEY
in.env
to test authentication errors (and thebail
condition).How to Track Campaign Data with Prisma Database
Store campaign information to track history and status.
Define Prisma Schema: Open
api/db/schema.prisma
and add aCampaign
model.Database Provider Requirements: Prisma v6.x (included with RedwoodJS v8+) requires PostgreSQL 9.6 minimum if using PostgreSQL. For production deployments, use PostgreSQL 12+ for security patches and performance improvements. SQLite is suitable for development only.
Campaign
. If linked to aUser
, it would be a one-to-many relationship (one User can have many Campaigns).Database Migration: Apply the schema changes to your database.
Enter a name for the migration when prompted (e.g.,
add campaign model
). This creates/updates your database tables.Update Service to Save Campaign: Modify the
sendMarketingCampaign
service to create aCampaign
record.db
object is the Prisma client instance, used for all database operations. This approach logs campaign attempts even if the MessageBird call fails.How to Secure Your SMS Campaign API
Implement security measures for APIs and user data.
Input Validation & Sanitization:
+
followed by country code and number). Add a regex check or use a library (likelibphonenumber-js
) for stricter validation.Authentication & Authorization:
requireAuth()
in the service (marketingCampaigns.js
) once you have RedwoodJS authentication set up (e.g.,yarn rw setup auth dbAuth
). This ensures only logged-in users can trigger campaigns.@requireAuth
to the GraphQL mutation definition (marketingCampaigns.sdl.js
) instead of@skipAuth
.context.currentUser.roles
).API Key Security:
.env
) and ensure.env
is in.gitignore
.Rate Limiting:
sendMarketingCampaign
mutation.yarn rw setup graphql-shield
) or a middleware approach (if using custom server file) to implement rate limiting (e.g., usingrate-limiter-flexible
). MessageBird also has its own API rate limits.Common Vulnerabilities:
userId
againstcontext.currentUser.id
in the service logic).How to Handle SMS Special Cases and Compliance
Address real-world messaging nuances.
Phone Number Formatting (E.164):
+14155551234
). While it might correctly interpret local formats for some regions, relying on E.164 is safer for international delivery.libphonenumber-js
.Character Limits & Encoding:
result.recipients.totalSentCount
vsresult.recipients.totalCount
) might provide clues, and webhooks provide more detail.Opt-Out Handling / Compliance:
Sender ID (Originator):
Delivery Status (Webhooks – Advanced):
delivered
,failed
,expired
arrive later.yarn rw g function messageStatus
). This function needs to handle POST requests from MessageBird, validate them, and update your database (e.g., update theCampaign
status).Frequently Asked Questions About RedwoodJS SMS Integration
What's the difference between MessageBird and Bird platforms?
MessageBird rebranded to Bird in February 2024. The legacy MessageBird platform (dashboard.messagebird.com) shuts down March 31, 2025. For new implementations after this date, use the Bird next-gen platform (app.bird.com) to access enhanced features and consolidated APIs. The MessageBird Node.js SDK and API endpoints remain compatible during the transition, but you should migrate your account and obtain new API keys from Bird's platform before the deadline.
What Node.js and RedwoodJS versions do I need?
RedwoodJS v8+ requires Node.js v20.x minimum. Node.js v18 reached end-of-life in April 2025. Use Node.js v20 LTS ("Iron", maintenance until April 2026) or v22 LTS ("Jod", active support until April 2027) for production deployments. Check your version with
node -v
and upgrade if necessary. RedwoodJS v8+ includes Prisma v6.x, which requires PostgreSQL 9.6+ (12+ recommended for production).How do I send bulk SMS campaigns with RedwoodJS?
Create a GraphQL mutation (
sendMarketingCampaign
) that accepts an array of phone numbers and message content. Use the MessageBird Node.js SDK in your RedwoodJS service layer to send messages viamessagebird.messages.create()
. Pass recipients as an array in E.164 format (e.g.,["+14155551234", "+442071234567"]
). Store campaign metadata in your Prisma database to track status and delivery. Implement rate limiting to prevent abuse and control costs.How do I handle failed SMS deliveries in RedwoodJS?
Implement retry logic using the
async-retry
library in your RedwoodJS service. Configure exponential backoff (2-3 retries with increasing delays). Check MessageBird error codes to distinguish between retryable errors (network issues) and non-retryable errors (authentication failures, invalid numbers). Store delivery attempts in your database with status tracking ("Submitting", "Submitted", "Failed"). Configure MessageBird webhooks for real-time delivery status updates beyond the initial submission confirmation.Can I track SMS campaign analytics in my RedwoodJS app?
Yes, create a Prisma
Campaign
model to store campaign metadata (message content, recipient count, submission time, MessageBird ID, status). Update the status field based on MessageBird webhook callbacks for detailed delivery tracking. Query your database using RedwoodJS services to generate analytics reports. Track metrics like total sent, delivery rate, failure reasons, and campaign performance over time. Use GraphQL queries to expose analytics data to your React frontend.How much does MessageBird SMS cost for marketing campaigns?
MessageBird (now Bird) SMS pricing varies by destination country. US SMS typically costs $0.0075 – $0.0125 per message. International rates range from $0.02 – $0.15+ per message depending on the destination. Longer messages exceeding 160 characters (GSM-7) or 70 characters (Unicode) are split into multiple segments, consuming more credits. Check Bird's pricing page for current rates and consider enterprise pricing for high-volume campaigns (10,000+ messages/month).
How do I secure MessageBird API keys in RedwoodJS?
Store API keys in the
.env
file at your project root and add.env
to your.gitignore
. RedwoodJS uses@fastify/env
for environment validation – define required keys in yourenvSchema.js
. Never commit API keys to version control. Use distinct keys per environment (development, staging, production). For production, use secret management services like AWS Secrets Manager or HashiCorp Vault. Rotate API keys periodically (every 90 days) through Bird's dashboard.Can I schedule SMS campaigns for future delivery with MessageBird?
Yes, MessageBird supports scheduling messages up to 30 days in advance using the
scheduledDatetime
parameter in themessages.create()
call. Pass an ISO 8601 timestamp (e.g.,"2025-12-25T10:00:00Z"
). For campaigns beyond 24 hours, implement a two-stage system: store the scheduled time in your Prisma database immediately, then use a cron job or background worker to send the actual SMS when the time approaches. This reduces API load and allows for cancellations or updates before sending.How do I comply with SMS marketing regulations (TCPA, GDPR)?
Provide recipients an easy opt-out mechanism (e.g., reply STOP). MessageBird can manage opt-out lists automatically – check their compliance documentation. Before sending campaigns, query your internal suppression list or MessageBird's opt-out list. Store user consent records in your database with timestamps and consent method. For US campaigns, register sender IDs through 10DLC or Toll-Free numbers. For EU campaigns under GDPR, obtain explicit consent and honor data deletion requests. Failure to comply can result in legal penalties and carrier filtering.
How do I test MessageBird integration locally in RedwoodJS?
Use MessageBird's Test API key for local development (obtain from dashboard.messagebird.com > Developers > API access). The Test key allows API testing without sending actual SMS or incurring charges. Start your RedwoodJS dev server with
yarn rw dev
and access the GraphQL Playground athttp://localhost:8910/graphql
. Execute test mutations with sample phone numbers. MessageBird returns simulated responses for testing. For production testing, use your own verified phone numbers with the Live API key to confirm actual SMS delivery before launching campaigns.