Frequently Asked Questions
Integrate the Vonage SMS API into your RedwoodJS application. This involves setting up a backend GraphQL endpoint to handle SMS details, a service function using the Vonage Server SDK, and frontend elements for user input. The provided step-by-step guide outlines the complete process.
The Vonage SMS API, a robust Communication Platform as a Service (CPaaS), enables sending and receiving SMS messages globally. It's known for reliability, scalability, and easy-to-use SDKs, making it ideal for various communication needs.
RedwoodJS offers a full-stack, serverless-first framework with integrated API and web sides, simplifying development. Its opinionated structure, generators, and built-in components like forms and cells enhance developer experience.
Always use environment variables for sensitive information like API keys. Store your Vonage API Key, API Secret, and Sender ID in a .env file. This crucial security practice keeps credentials out of your source code.
The Vonage SMS API supports sending messages globally. Ensure the recipient numbers are in E.164 format (e.g., +14155550100). Be mindful of trial account limitations, which may require verifying recipient numbers.
Implement robust error handling in your service function by checking the Vonage API response status. Log errors using Redwood's logger and return informative error messages to the frontend for user feedback.
The RedwoodJS web frontend collects user input and triggers a GraphQL mutation. The backend API resolver calls a service function which uses the Vonage Node.js SDK to send the SMS via the Vonage API, which then delivers the SMS to the recipient.
Install the Vonage Server SDK specifically within the API workspace of your Redwood project using the command yarn workspace api add @vonage/server-sdk. This ensures the SDK is correctly placed in your project structure.
You need Node.js (v18.x or 20.x), Yarn (v1.x), the RedwoodJS CLI, a Vonage API account (with API Key, API Secret, and a Vonage phone number), and a basic grasp of JavaScript, React, and command-line interfaces.
Define a Mutation type with a sendSms field that accepts a SendSmsInput object containing to (recipient number) and text (message content). It should return a SendSmsResponse indicating success/failure, message ID, and any errors.
The Sender ID is the "from" number or name displayed to the SMS recipient. It's usually your purchased Vonage virtual number (in E.164 format), but can also be an alphanumeric Sender ID if pre-registered and approved by Vonage.
Store your Vonage API Key and API Secret as environment variables in a .env file at your project's root. RedwoodJS automatically loads these during development. This practice is essential for preventing accidental exposure of sensitive information.
While Prisma is part of the RedwoodJS stack, this initial tutorial doesn't utilize complex database interactions. However, Prisma can be used later to store SMS campaign details, logs, or user information, enhancing project functionality.
Create a new RedwoodJS project using yarn create redwood-app <project-name>. Navigate to the project directory, install the Vonage Server SDK (yarn workspace api add @vonage/server-sdk), and configure your Vonage API credentials in the .env file.
Your Vonage API Key and API Secret are available on the Vonage API Dashboard homepage after you sign up for an account. These credentials are essential for authenticating your application with Vonage.
.env
This comprehensive guide walks you through integrating Twilio's Programmable Messaging API into a RedwoodJS application to send SMS marketing campaigns programmatically. You'll learn how to build a complete SMS marketing system with proper A2P 10DLC compliance, subscriber management, and bulk messaging capabilities.
By the end of this tutorial, you will have a production-ready RedwoodJS application capable of sending SMS messages via Twilio, complete with essential configurations, error handling, security best practices, and full compliance with US A2P 10DLC regulations for marketing campaigns. This serves as a solid foundation for building sophisticated SMS marketing features.
Project Overview and Goals
What We're Building:
Problem Solved:
This project enables developers to programmatically send targeted SMS messages directly from their web application, facilitating communication for:
Technologies Used:
System Architecture:
The flow is straightforward:
messages.create()method to dispatch the SMS message via the Twilio platform.Prerequisites:
npm install -g @redwoodjs/clioryarn global add @redwoodjs/cli).Expected Outcome:
A running RedwoodJS application where you can enter a phone number and message text into a form, click "Send", and have an SMS delivered to that number via your Twilio account.
1. Setting up the Project
Let's create the RedwoodJS project and install necessary dependencies.
Step 1: Create RedwoodJS Application
Open your terminal and run the RedwoodJS create command. We'll name our project
redwood-twilio-sms.Follow the prompts. Choose TypeScript if you prefer, but this guide will use JavaScript for broader accessibility.
Step 2: Navigate to Project Directory
Step 3: Install Twilio Node.js SDK
The Twilio SDK needs to be installed in the API workspace of your Redwood project.
This command specifically adds the
twiliopackage to theapi/package.jsonfile and installs it within theapi/node_modulesdirectory.Step 4: Configure Environment Variables
RedwoodJS uses
.envfiles for environment variables. The.envfile is gitignored by default for security.Create a
.envfile in the root of your project:Add your Twilio API credentials and your Twilio sending number to this file.
TWILIO_ACCOUNT_SID: Found on your Twilio Console Dashboard. Purpose: Authenticates your application with Twilio.TWILIO_AUTH_TOKEN: Found on your Twilio Console Dashboard. Purpose: Authenticates your application with Twilio. Keep this secret!TWILIO_PHONE_NUMBER: One of your purchased Twilio phone numbers in E.164 format (e.g.,+14155550100). Purpose: The 'From' number displayed to the recipient.Security Best Practices:
.envfile to version controlExplanation: Using environment variables keeps sensitive credentials out of your source code, which is crucial for security. RedwoodJS automatically loads variables from
.envduring development. For deployment, you'll need to configure these variables in your hosting provider's environment settings.2. Defining the API Layer (GraphQL)
Now, let's define the backend API endpoint using GraphQL.
Step 1: Generate SDL and Service Files
Use the Redwood generator to create the Schema Definition Language (SDL) and service files for SMS functionality:
This command creates:
api/src/graphql/sms.sdl.ts(or.js)api/src/services/sms/sms.ts(or.js)api/src/services/sms/sms.test.ts(or.js)Step 2: Define the GraphQL Schema
Edit
api/src/graphql/sms.sdl.ts(or.js) to define thesendSmsmutation:Explanation:
Mutationtype with one field:sendSms.sendSmstakes a requiredinputargument of typeSendSmsInput.SendSmsInputdefines the required fields:to(recipient) andtext(message body). Using an input type keeps the mutation arguments organized.sendSmsreturns aSendSmsResponsetype.SendSmsResponseindicatessuccess(boolean) and provides optionalmessageSid(Twilio's unique message identifier) orerrordetails.@skipAuth: For simplicity in this guide, we disable authentication for this mutation. In a production application, you must implement authentication (@requireAuth) to ensure only authorized users can send SMS.3. Implementing the Service Logic
Now, implement the logic within the service file generated earlier. This function will initialize the Twilio client and call its API.
Edit
api/src/services/sms/sms.ts(or.js):Explanation:
twilioSDK and Redwood'slogger.sendSmsfunction receives theinputobject matching ourSendSmsInputGraphQL type.toortext. Production apps should have more robust validation (e.g., usingzodor checking phone number format with a library likelibphonenumber-js).process.env. Crucially, it checks if they exist and throws an error if not.twilio(accountSid, authToken).logger.infoandlogger.errorto record actions and potential issues.client.messages.create(): Call the Twilio SDK method to send SMS:body: Message contentfrom: Your Twilio phone numberto: Recipient numbersid(unique message identifier) andstatusproperty.message.sidexists, we consider it successful and return{ success: true, messageSid }.statusfield indicates the message state (e.g.,queued,sent,delivered,failed). Initially, it's typicallyqueued.try...catch): Catches errors thrown by the SDK (e.g., invalid credentials, network problems, invalid phone numbers). Twilio errors include acodeand descriptivemessagethat should be logged and returned.SendSmsResponseGraphQL type.Important Notes:
queuedorsentmeans Twilio accepted the message, not that it was delivered4. Building the Frontend
Now, let's create a simple page on the web side to interact with our API.
Step 1: Generate the Page
Use the Redwood generator to create a page:
This creates
web/src/pages/SmsSenderPage/SmsSenderPage.js(or.tsx) and adds a route inweb/src/Routes.js(or.tsx).Step 2: Implement the Page Component
Edit
web/src/pages/SmsSenderPage/SmsSenderPage.js(or.tsx):Explanation:
MetaTags,useMutation,@redwoodjs/forms,@redwoodjs/web/toast).SEND_SMS_MUTATION: Define the GraphQL mutation string that matches the one defined in the SDL.useForm: Initialize Redwood Forms for handling form state and validation.useState: Track aloadingstate for user feedback during submission.useMutationHook:onCompleted: Called when the mutation successfully executes. Checksdata.sendSms.successto show appropriate success/error toasts.onError: Called if there's a GraphQL or network-level error.onSubmitHandler: Called when form is submitted, triggers the mutation.<Toaster>: Required bytoastto display notifications.<Form>Component: Redwood's form wrapper with validation.<Submit>Button: Disabled during loading to prevent duplicate submissions.Note: SMS messages are typically segmented at 160 characters (GSM-7) or 70 characters (UCS-2 for Unicode). The 1600 character limit allows for approximately 10 segments. For production, consider warning users about message segmentation and costs.
5. Understanding A2P 10DLC Compliance for SMS Marketing Campaigns
When sending marketing SMS messages to US recipients using 10-digit long codes (10DLC), you must comply with A2P 10DLC regulations. This section covers critical compliance requirements for SMS marketing.
What is A2P 10DLC?
A2P 10DLC (Application-to-Person 10-Digit Long Code) is a system in the United States that requires businesses to register their brand and campaign use cases before sending SMS messages via 10-digit phone numbers. This system improves deliverability, reduces spam, and ensures compliance with carrier requirements.
Registration Requirements:
How to Register for A2P 10DLC via Twilio Console
Follow these steps to register for A2P 10DLC:
Step 1: Register Your Brand
Navigate to Twilio Console → Messaging → Regulatory Compliance and complete brand registration with:
Step 2: Register Your Campaign
After brand approval, register your campaign with:
Step 3: Associate Phone Numbers
Link your Twilio 10DLC phone numbers to your approved campaign through a Messaging Service.
Important Notes:
For detailed guidance, see Twilio's A2P 10DLC Registration Guide.
SMS Marketing Opt-In and Consent Requirements
Legal Requirements for Marketing SMS:
Implementation Example:
Required Message Content:
Every marketing message should include:
Example:
"Hi from Acme Corp! Get 20% off today only. Reply STOP to opt-out or HELP for help."SMS Marketing Rate Limits and Throughput
Twilio Rate Limits:
Best Practices:
Alternative: Toll-Free Numbers for SMS Marketing
For marketing campaigns, consider Toll-Free verification as an alternative to 10DLC:
Pros:
Cons:
6. Implementing Proper Error Handling, Logging, and Retry Mechanisms
Error Handling (Covered Above):
useMutation'sonErrorcatches GraphQL/network errors.onCompletedchecks thesuccessflag from the service response for Twilio-specific errors. Toasts provide user feedback.try...catchblocks handle SDK exceptions (auth, network).message.sid) handles errors reported by Twilio.{ success, messageSid, error }).Common Twilio Error Codes:
21211: Invalid 'To' phone number21408: Permission to send to unverified number (trial account)21610: Unsubscribed recipient (has opted out)30007: Message blocked as spam30008: Unknown destination carrierFor a complete list, see Twilio Error Codes.
Logging (Covered Above):
loggerfromsrc/lib/logger) is used in the service.logger.infologs successful attempts and outcomes.logger.errorlogs configuration issues, SDK errors, and Twilio API errors, including error objects for detailed stack traces.yarn rw dev). In production, configure your hosting provider or logging service (e.g., Logflare, Datadog) to capture these logs.Retry Mechanisms:
Implementing retries adds complexity. For SMS, retries should be handled carefully to avoid duplicate messages.
Client-Side Retries: Generally not recommended for actions like sending SMS, as network issues could lead to multiple successful submissions if the user retries manually after the first request actually succeeded but the response was lost. The loading state and disabled button help prevent this.
Server-Side Retries: If the
client.messages.create()call fails due to transient issues (e.g., temporary network error, Twilio rate limit), you could implement a retry strategy within the service function.500series HTTP errors from Twilio, rate limit errors429). Do not retry on errors like invalid credentials, invalid phone numbers, or exceeded account limits.async-retryorp-retrycan simplify implementing exponential backoff.async-retry):Recommendation: Start without automatic retries. Add them only if you observe frequent transient failures in production and have carefully considered the idempotency implications. Logging and monitoring are key to identifying the need for retries.
7. Creating a Database Schema and Data Layer (Optional Extension)
While not strictly required for sending a single SMS, storing campaign details or message logs is often necessary for marketing applications. RedwoodJS uses Prisma for database interactions.
Step 1: Define Schema
Edit
api/db/schema.prisma:Step 2: Create Migration
Generate the SQL migration file and apply it to your database:
This creates a migration file in
api/db/migrationsand updates your database schema.Step 3: Update Service to Log
Modify
api/src/services/sms/sms.tsto use the Prisma client (db) to save a log entry:Benefits of Database Logging:
Next Steps for Production:
SmsLogrecords8. Testing Your Application
Step 1: Start Development Server
This starts both the API server and web development server.
Step 2: Navigate to the SMS Sender Page
Open your browser and go to
http://localhost:8910/sms-senderStep 3: Send a Test Message
+14155550100)Step 4: Verify in Twilio Console
Navigate to Twilio Console → Messaging → Logs to see message details, status, and any errors.
9. Deployment Considerations
When deploying your RedwoodJS application to production:
Environment Variables:
Configure these in your hosting provider (Vercel, Netlify, AWS, etc.):
TWILIO_ACCOUNT_SIDTWILIO_AUTH_TOKENTWILIO_PHONE_NUMBERDATABASE_URL(if using database logging)Security Best Practices:
@skipAuthand add proper user authenticationScaling Considerations:
10. Next Steps and Advanced Features
To build a production-ready marketing campaign system, consider implementing:
Additional Resources:
Frequently Asked Questions (FAQ)
How do I send bulk SMS messages with Twilio?
To send bulk SMS messages with Twilio and RedwoodJS, implement a message queue system using Bull or BullMQ. This allows you to process large recipient lists without hitting rate limits. Store subscriber lists in your database, then create a background job that iterates through recipients and calls the Twilio API for each message.
Is SMS marketing legal in the USA?
Yes, SMS marketing is legal in the USA when you comply with TCPA regulations. You must obtain express written consent before sending marketing messages, provide clear opt-out mechanisms (like "Reply STOP"), and register for A2P 10DLC if using 10-digit long codes.
How much does Twilio SMS cost?
Twilio SMS pricing varies by country. In the US, outbound SMS typically costs $0.0079 per message segment. Additionally, A2P 10DLC registration costs $4/month for brand registration and a one-time $15 campaign registration fee. Check current pricing at the Twilio pricing page.
What is the SMS open rate for marketing campaigns?
SMS marketing typically achieves 98% open rates, with most messages read within 3 minutes of delivery. This makes SMS one of the most effective marketing channels for time-sensitive promotions and urgent notifications.
Conclusion
You now have a functional RedwoodJS application integrated with Twilio's Programmable Messaging API for sending SMS marketing campaigns. This guide covered:
This foundation can be extended to build sophisticated marketing campaign systems with advanced features like subscriber management, campaign scheduling, analytics, and multi-channel messaging.
Remember to always comply with TCPA regulations, obtain proper consent, and respect opt-out requests when sending marketing messages. Happy coding!