code examples
code examples
How to Build SMS Marketing Campaigns with Plivo and RedwoodJS [2025 Guide]
Complete RedwoodJS + Plivo SMS tutorial: Build automated marketing campaigns with GraphQL, track delivery with Prisma, implement retry logic, and deploy to production. 2-3 hour implementation.
Build SMS Marketing Campaigns with Plivo and RedwoodJS
Send SMS marketing campaigns using Plivo's messaging API and RedwoodJS's full-stack JavaScript framework. This comprehensive guide demonstrates how to integrate Plivo SMS with RedwoodJS, covering GraphQL API implementation, Prisma database setup, React component development, and production deployment strategies.
Learn how to build a production-ready SMS campaign system that combines RedwoodJS's GraphQL mutations with Plivo's reliable SMS delivery infrastructure. This tutorial covers authentication, error handling with automatic retries, phone number validation, and campaign logging – everything you need for enterprise-grade SMS marketing functionality.
What you'll build in this RedwoodJS Plivo integration:
- GraphQL mutations for sending SMS messages via Plivo API
- Prisma ORM schema for SMS campaign logging and analytics
- Automatic error handling with retry mechanisms
- React frontend components for campaign management
- Production-ready deployment with environment security
Requirements:
- Node.js 20.x or higher
- Yarn 1.22.21 or higher
- RedwoodJS 8.x (this guide uses current best practices)
- Plivo account with API credentials
Table of Contents
- Prerequisites for Plivo SMS Integration
- Set Up Your RedwoodJS Project
- Configure Your Environment Variables
- Create the Database Schema
- Define Your GraphQL Schema
- Implement the SMS Service
- Validate Phone Numbers (E.164 Format)
- Build the Frontend Form
- Add Error Handling and Retries
- Implement Authentication
- Test Your SMS Integration
- Deploy to Production
- Frequently Asked Questions
- Next Steps
Quick Summary: This guide shows you how to integrate Plivo SMS API with RedwoodJS to build SMS marketing campaigns. You'll set up GraphQL mutations, implement Prisma database logging, add React frontend components, configure error handling with retries, and deploy to production. The complete implementation takes approximately 2–3 hours and requires Node.js 20+, Yarn, and a Plivo account.
Prerequisites for Plivo SMS Integration
Before integrating Plivo with RedwoodJS, ensure you have:
- Node.js (>=18.x recommended, tested with v18.18.0, check RedwoodJS docs for current requirements)
- Yarn (>=1.15)
- A Plivo account (Sign up at https://www.plivo.com/)
- You'll need your Auth ID and Auth Token.
- You'll need a Plivo phone number capable of sending SMS messages. (Note: Trial accounts have restrictions).
- Basic understanding of RedwoodJS concepts (sides, cells, services, GraphQL).
- Familiarity with command-line tools.
Expected Outcome:
A RedwoodJS application with a page containing a form. Submitting the form (with a recipient phone number and message text) triggers a backend function that uses the Plivo API to send the SMS. A record of the attempt (success or failure) is logged in the database.
Set Up Your RedwoodJS Project
Create a new RedwoodJS application if you don't have one yet:
yarn create redwood-app my-plivo-app
cd my-plivo-appInstall the Plivo Node.js SDK (version 4.74.0 is the latest as of October 2025):
yarn workspace api add plivoThe Plivo SDK package name is plivo on npm – this is the official, maintained version of the SDK.
Related guides:
- Learn about phone number validation and E.164 format
- Compare SMS API providers and pricing
- Explore RedwoodJS GraphQL best practices
- Understand SMS marketing campaign best practices
- Set up 10DLC registration for US SMS campaigns
Configure Your Environment Variables
Plivo requires an Auth ID and Auth Token for authentication. Store these securely using environment variables.
-
Create a
.envfile in the root of your project (if it doesn't exist). -
Add your Plivo credentials and a Plivo source phone number to the
.envfile:text# .env PLIVO_AUTH_ID=YOUR_PLIVO_AUTH_ID PLIVO_AUTH_TOKEN=YOUR_PLIVO_AUTH_TOKEN PLIVO_SOURCE_NUMBER=YOUR_PLIVO_PHONE_NUMBER -
How to find Plivo Credentials:
- Log in to your Plivo console (https://console.plivo.com/).
- The Auth ID and Auth Token are displayed prominently on the main dashboard overview page.
- Navigate to
Messaging -> Phone Numbersto find or purchase a Plivo number to use as thePLIVO_SOURCE_NUMBER. Ensure it's SMS-enabled for your target region.
-
IMPORTANT: Add
.envto your.gitignorefile (RedwoodJS usually includes this by default) to prevent committing secrets.text# .gitignore # ... other entries .env # ... -
Purpose: Storing sensitive credentials in environment variables is a standard security practice. RedwoodJS automatically loads variables from the
.envfile intoprocess.env.
Ensure your basic RedwoodJS development environment works:
yarn redwood devThis should start the development servers for both the api and web sides and open your browser to http://localhost:8910. Stop the server (Ctrl+C) once confirmed.
Create the Database Schema
Define a CampaignLog model to track all SMS campaigns. Open api/db/schema.prisma and add:
model CampaignLog {
id Int @id @default(autoincrement())
to String
text String
plivoMessageId String?
status String // SENT, FAILED, PENDING
errorDetails String?
sentAt DateTime @default(now())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([status])
@@index([sentAt])
}Index strategy:
@@index([status])– speeds up queries filtering by message status@@index([sentAt])– optimizes date-range queries for campaign analytics
These indexes follow Prisma best practices for production databases. Indexes on frequently queried fields improve performance as your campaign logs grow.
Run the migration to create the table:
yarn rw prisma migrate dev --name create_campaign_log-
Entity Relationship Diagram (ERD): For this simple case, we only have one model.
mermaiderDiagram CampaignLog { Int id PK String to String text String plivoMessageId NULL String status // e.g., 'SENT', 'FAILED', 'PENDING' String errorDetails NULL DateTime sentAt DateTime createdAt DateTime updatedAt }
Define Your GraphQL Schema
Define the mutation input and output types:
// api/src/graphql/plivoCampaign.sdl.ts
export const schema = gql`
type PlivoMessageResult {
success: Boolean!
messageId: String
error: String
}
input SendPlivoMessageInput {
to: String!
text: String!
}
type Mutation {
sendPlivoMessage(input: SendPlivoMessageInput!): PlivoMessageResult! @requireAuth
}
`Generate the necessary GraphQL and service files:
yarn rw g sdl PlivoCampaign --empty
yarn rw g service PlivoCampaign --emptyThis creates:
-
api/src/graphql/plivoCampaign.sdl.ts -
api/src/services/plivoCampaign/plivoCampaign.ts -
api/src/services/plivoCampaign/plivoCampaign.test.ts -
PlivoMessageResult: Defines the structure of the data returned after attempting to send a message. Includes success status, the Plivo message UUID if successful, or an error message if not. -
SendPlivoMessageInput: Defines the required input fields for the mutation. -
Mutation.sendPlivoMessage: Declares the mutation endpoint. -
@requireAuth: For security, we require authentication for this mutation. This ensures only logged-in users can send messages. In a production application, you should always use@requireAuthfor sensitive operations.
Implement the SMS Service
Create the service that sends SMS messages via Plivo's API:
// api/src/services/plivoCampaign/plivoCampaign.ts
import * as plivo from 'plivo'
import retry from 'async-retry'
import type { MutationResolvers } from 'types/graphql'
import { logger } from 'src/lib/logger'
import { db } from 'src/lib/db'
export const sendPlivoMessage: MutationResolvers['sendPlivoMessage'] = async ({ input }) => {
const { to, text } = input
const authId = process.env.PLIVO_AUTH_ID
const authToken = process.env.PLIVO_AUTH_TOKEN
const sourceNumber = process.env.PLIVO_SOURCE_NUMBER
if (!authId || !authToken || !sourceNumber) {
logger.error('Plivo credentials or source number missing in .env file.')
return {
success: false,
error: 'Server configuration error: Plivo credentials missing.',
}
}
// Basic input validation
if (!to || !text || text.trim() === '') {
return { success: false, error: 'Recipient number and message text cannot be empty.' }
}
if (!/^\+?[1-9]\d{1,14}$/.test(to)) {
return { success: false, error: 'Invalid recipient phone number format. Use E.164 format (e.g., +14155552671).' }
}
const client = new plivo.Client(authId, authToken);
let logEntry;
try {
// Log attempt before trying
logEntry = await db.campaignLog.create({
data: { to, text, status: 'PENDING', sentAt: new Date() }
})
logger.info(`Attempting to send Plivo message to: ${to} (Log ID: ${logEntry.id})`);
const response = await retry(
async (bail, attempt) => {
logger.debug(`Retry attempt ${attempt} for message to ${to} (Log ID: ${logEntry.id})`);
return await client.messages.create(sourceNumber, to, text);
},
{
retries: 3,
factor: 2,
minTimeout: 1000,
onRetry: (error, attempt) => {
logger.warn(
`Retrying Plivo send (${attempt}/${3}) for ${to} (Log ID: ${logEntry.id}) due to error: ${error.message}`
)
},
}
);
// Update log on success
await db.campaignLog.update({
where: { id: logEntry.id },
data: {
status: 'SENT',
plivoMessageId: response.messageUuid[0],
},
})
logger.info(`Plivo message sent successfully to ${to}. Message UUID: ${response.messageUuid[0]} (Log ID: ${logEntry.id})`);
return {
success: true,
messageId: response.messageUuid[0],
error: null,
};
} catch (error) {
logger.error({ error, logId: logEntry?.id }, `Failed to send Plivo message to ${to} after retries`);
// Update log on failure
if (logEntry) {
await db.campaignLog.update({
where: { id: logEntry.id },
data: {
status: 'FAILED',
errorDetails: error.message || 'Unknown error after retries',
},
});
}
return {
success: false,
error: `Failed to send message after retries: ${error.message || 'Unknown error'}`,
};
}
}Install the retry library:
yarn workspace api add async-retry @types/async-retryHow this works:
- Initialize the Plivo client with your credentials
- Validate input (phone format and message content)
- Create a database log entry with PENDING status
- Call
client.messages.create()with automatic retry logic (3 attempts with exponential backoff) - Update database log with SENT status and Plivo message UUID on success
- Catch errors, log failed attempts with error details, and update database with FAILED status
- Return structured results to the GraphQL client
The message UUID from Plivo allows you to track delivery status later.
Validate Phone Numbers (E.164 Format)
Plivo requires phone numbers in E.164 format. This international standard includes the country code and removes all formatting characters.
E.164 format rules:
- Start with
+followed by country code - Include area code and number without spaces, dashes, or parentheses
- Maximum 15 digits (including country code)
Examples:
- ✅
+14155552671(US number) - ✅
+442071838750(UK number) - ✅
+551155256325(Brazil number) - ❌
(415) 555-2671(contains formatting) - ❌
4155552671(missing country code)
The validation logic is already included in the service implementation above. The regex /^\+?[1-9]\d{1,14}$/ checks for valid E.164 format.
Why E.164 matters: Using the standard format ensures your messages reach the correct recipients across any country. It eliminates ambiguity in phone number interpretation.
For more details, see our complete guide to E.164 phone number format.
Build the Frontend Form
Create a React component for sending SMS campaigns. Generate a new page:
yarn rw g page SendCampaign /send-campaignUpdate web/src/pages/SendCampaignPage/SendCampaignPage.tsx:
// web/src/pages/SendCampaignPage/SendCampaignPage.tsx
import { useState } from 'react'
import { Toaster, toast } from '@redwoodjs/web/toast'
import {
Form,
Label,
TextField,
TextAreaField,
FieldError,
Submit,
useForm,
} from '@redwoodjs/forms'
import { MetaTags, useMutation } from '@redwoodjs/web'
// Define the GraphQL Mutation
const SEND_PLIVO_MESSAGE_MUTATION = gql`
mutation SendPlivoMessageMutation($input: SendPlivoMessageInput!) {
sendPlivoMessage(input: $input) {
success
messageId
error
}
}
`
interface FormData {
to: string
text: string
}
const SendCampaignPage = () => {
const formMethods = useForm<FormData>()
const [sendPlivoMessage, { loading, error }] = useMutation(
SEND_PLIVO_MESSAGE_MUTATION,
{
onCompleted: (data) => {
if (data.sendPlivoMessage.success) {
toast.success(
`Message sent successfully! ID: ${data.sendPlivoMessage.messageId}`
)
formMethods.reset()
} else {
toast.error(`Failed to send message: ${data.sendPlivoMessage.error}`)
}
},
onError: (error) => {
toast.error(`GraphQL Error: ${error.message}`)
}
}
)
const onSubmit = (data: FormData) => {
console.log('Form data submitted:', data)
sendPlivoMessage({ variables: { input: data } })
}
return (
<>
<MetaTags title="Send Campaign Message" description="Send SMS via Plivo" />
<Toaster toastOptions={{ className: 'rw-toast', duration: 6000 }} />
<h1 className="text-2xl font-semibold mb-4">Send Plivo SMS Campaign</h1>
<Form<FormData> onSubmit={onSubmit} formMethods={formMethods} className="space-y-4 max-w-md">
<div>
<Label name="to" className="block text-sm font-medium text-gray-700">
Recipient Number (E.164 format, e.g., +14155552671)
</Label>
<TextField
name="to"
className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"
validation={{ required: true, pattern: { value: /^\+?[1-9]\d{1,14}$/, message: 'Use E.164 format' } }}
/>
<FieldError name="to" className="mt-1 text-xs text-red-600" />
</div>
<div>
<Label name="text" className="block text-sm font-medium text-gray-700">
Message Text
</Label>
<TextAreaField
name="text"
className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"
validation={{ required: true, minLength: 1 }}
/>
<FieldError name="text" className="mt-1 text-xs text-red-600" />
</div>
{error && <div className="text-red-600">Error: {error.message}</div>}
<div>
<Submit
disabled={loading}
className="inline-flex justify-center rounded-md border border-transparent bg-indigo-600 py-2 px-4 text-sm font-medium text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 disabled:opacity-50"
>
{loading ? 'Sending...' : 'Send Message'}
</Submit>
</div>
</Form>
</>
)
}
export default SendCampaignPageKey features:
- E.164 format validation with helpful error messages
- Loading state prevents duplicate submissions
- Toast notifications for success and error feedback
- Form clears after successful send
- Client-side and server-side validation
Add Error Handling and Retries
The service implementation above already includes comprehensive error handling with automatic retries using the async-retry library.
Retry configuration explained:
retries: 3– attempts the request up to 3 times before failingfactor: 2– exponential backoff (2x delay between retries)minTimeout: 1000– waits 1 second before first retry
Why retry matters: Network issues or temporary Plivo API failures can cause messages to fail. Implementing retries improves reliability without requiring manual intervention.
When NOT to retry: The current implementation retries all errors. In production, you may want to bail immediately on validation errors (400 status codes) by inspecting the error structure Plivo returns.
Learn more about handling SMS delivery failures and retry strategies.
Implement Authentication
Protect your SMS endpoint from unauthorized access. RedwoodJS provides built-in authentication through the @requireAuth directive.
Set up authentication:
yarn rw setup auth dbAuthThis creates the authentication infrastructure with database-backed auth (dbAuth).
The @requireAuth directive on your mutation (already included in the SDL above) ensures only logged-in users can send SMS:
export const schema = gql`
type Mutation {
sendPlivoMessage(input: SendPlivoMessageInput!): PlivoMessageResult! @requireAuth
}
`Implement role-based access control (optional):
Restrict SMS sending to specific user roles:
export const schema = gql`
type Mutation {
sendPlivoMessage(input: SendPlivoMessageInput!): PlivoMessageResult!
@requireAuth(roles: ["ADMIN", "MARKETING"])
}
`Why this matters: Without authentication, anyone who discovers your API endpoint could send SMS messages using your Plivo account. This leads to unauthorized charges and potential abuse.
For complete authentication setup, see the RedwoodJS authentication documentation.
Test Your SMS Integration
Start your development server:
yarn rw devAccess your application:
- Open your browser to
http://localhost:8910/send-campaign - Enter a phone number in E.164 format (e.g.,
+14155552671) - Type a test message
- Click "Send Message"
Verify the results:
- Check for a success toast notification with the message UUID
- Confirm the SMS arrives at the destination phone
- Inspect the
CampaignLogtable in your database:
yarn rw prisma studioLook for the new record with status SENT and the Plivo message UUID.
Test error handling:
- Try an invalid phone number format (e.g.,
4155552671without+) - Verify you see an error message
- Check the database for a record with status
FAILED
Test with GraphQL Playground:
Use the GraphQL Playground (http://localhost:8910/graphql) to test the mutation directly:
mutation TestPlivoSend {
sendPlivoMessage(input: {
to: "+1YOUR_TEST_PHONE_NUMBER",
text: "Test message from RedwoodJS GraphQL Playground!"
}) {
success
messageId
error
}
}Deploy to Production
Configure your environment variables on your hosting platform before deploying.
For Vercel:
vercel env add PLIVO_AUTH_ID
vercel env add PLIVO_AUTH_TOKEN
vercel env add PLIVO_SOURCE_NUMBERFor Netlify:
Add environment variables in the Netlify dashboard:
- Navigate to Site settings → Environment variables
- Add each variable:
PLIVO_AUTH_ID,PLIVO_AUTH_TOKEN,PLIVO_SOURCE_NUMBER - Click "Save"
For AWS/Render/Fly.io:
Consult your platform's documentation for setting environment variables. Each platform has a different method, but all require the same three variables.
Deploy your application:
yarn rw deployPost-deployment checklist:
- Verify environment variables are set correctly
- Test sending an SMS through the production URL
- Check your Plivo dashboard for message logs
- Monitor your database for campaign log entries
- Set up error monitoring (Sentry, Rollbar, or similar)
Production recommendations:
- Enable Plivo's delivery receipts to track message status
- Set up webhooks for real-time delivery updates
- Implement rate limiting to prevent abuse
- Monitor SMS costs and set billing alerts
- Review logs regularly for failed deliveries
Learn more about SMS compliance requirements for production applications.
Frequently Asked Questions (FAQ)
How much does it cost to send SMS with Plivo?
Plivo charges per SMS segment, with pricing varying by destination country. US SMS typically costs $0.0075–$0.01 per segment. Check Plivo's pricing page for current rates in your target countries. A standard SMS segment is 160 characters.
What is E.164 phone number format?
E.164 is the international phone number format required by Plivo. It starts with + followed by country code and number without spaces or formatting (e.g., +14155552671 for a US number). Maximum 15 digits total. See our complete E.164 format guide.
Can I send bulk SMS campaigns with RedwoodJS and Plivo?
Yes. Modify the GraphQL mutation to accept an array of phone numbers and implement batch sending with rate limiting. Consider using a queue system like Bull or Graphile Worker for large campaigns to prevent API throttling. For high-volume sending, you'll also need to register for 10DLC.
How do I track SMS delivery status with Plivo?
Plivo returns a message UUID for each sent SMS. Use this UUID to query the Plivo API for delivery status, or implement webhook handlers to receive real-time delivery notifications when messages are delivered or fail. Check the Plivo delivery reports documentation.
Does RedwoodJS support other SMS providers besides Plivo?
Yes. RedwoodJS works with any SMS provider with a Node.js SDK. Popular alternatives include Twilio, Vonage, MessageBird, and Sinch. The integration pattern remains similar – initialize the client in your service and call the provider's API.
What Node.js version does RedwoodJS require?
RedwoodJS 8.x requires Node.js 20.x or higher. Some deploy targets like AWS Lambda may have restrictions with Node.js 21+. Use the LTS version (20.x) for best compatibility.
How do I handle SMS opt-out requests?
Create a database table to track opt-out requests. Before sending messages, query this table to filter out opted-out numbers. Include an opt-out message in your campaigns (e.g., "Reply STOP to unsubscribe") and implement webhook handlers to process replies. See our SMS compliance guide for TCPA requirements.
Next Steps: Enhance Your SMS Marketing System
You've built a complete SMS marketing campaign system with Plivo and RedwoodJS. Your implementation includes GraphQL mutations, database logging, error handling, and automatic retries.
Advanced features to add:
Bulk SMS campaigns and scheduling:
- Modify your GraphQL mutation to accept arrays of phone numbers for batch sending
- Implement queue systems (Bull, BullMQ, or Graphile Worker) for scheduled campaigns
- Add rate limiting to comply with Plivo's API throughput limits
- Create campaign templates with variable substitution for personalization
SMS analytics and reporting:
- Build dashboards showing delivery rates, failure analysis, and cost tracking
- Implement webhook handlers for real-time delivery status updates
- Track campaign ROI with conversion tracking and A/B testing
- Generate reports on optimal send times and engagement metrics
Compliance and subscriber management:
- Create opt-in/opt-out subscription systems with double opt-in confirmation
- Implement automatic STOP/START keyword processing
- Add TCPA and GDPR compliance features for US and EU markets
- Build subscriber segmentation for targeted campaigns
Integration enhancements:
- Connect with CRM systems (Salesforce, HubSpot) for contact synchronization
- Implement two-way SMS conversations with automated responses
- Add MMS support for multimedia marketing campaigns
- Integrate with analytics platforms (Google Analytics, Segment)
Related guides:
- Twilio vs Plivo: SMS API comparison
- 10DLC SMS registration for US campaigns
- Building two-way SMS conversations
- SMS compliance guide: TCPA and GDPR
- SMS marketing best practices for 2025
Additional resources:
- Plivo SMS API documentation – Official Plivo API reference
- RedwoodJS GraphQL guide – GraphQL best practices in RedwoodJS
- Prisma schema reference – Complete Prisma documentation
- E.164 phone number format specification – International telecommunication standard
Get help and support:
Join the RedwoodJS Discord community for framework questions or consult Plivo's support documentation for API-specific issues. Both communities actively help developers implement SMS solutions.
About this guide: Last updated October 2025 with RedwoodJS 8.x, Plivo Node.js SDK 4.74.0, and Node.js 20.x requirements. Code examples tested on production deployments with Netlify, Vercel, and AWS Lambda.
Frequently Asked Questions
How to send SMS messages with RedwoodJS?
Integrate Plivo's messaging API into your RedwoodJS application. This involves installing the Plivo Node.js SDK, setting up environment variables for your Plivo credentials, creating a GraphQL mutation, and building a frontend form to trigger the message sending process. The provided tutorial guides you through each step to create a fully functional SMS sending feature within your RedwoodJS app.
What is Plivo used for in RedwoodJS?
Plivo is a cloud communications platform used to send SMS messages programmatically from your RedwoodJS application. It acts as the SMS gateway, removing the need for you to build that infrastructure yourself. The Plivo Node.js SDK facilitates the integration within your RedwoodJS service.
Why use RedwoodJS for sending SMS campaigns?
RedwoodJS provides a full-stack JavaScript/TypeScript framework with integrated frontend (React) and backend (GraphQL API, Prisma) capabilities, simplifying the development process. This integration allows you to build and deploy SMS campaigns easily by combining the Plivo API with a user-friendly interface.
How to set up Plivo API keys in RedwoodJS?
Create a `.env` file in the root of your RedwoodJS project and add your `PLIVO_AUTH_ID`, `PLIVO_AUTH_TOKEN`, and `PLIVO_SOURCE_NUMBER`. RedwoodJS loads these into `process.env`. Never hardcode these credentials directly in your code. Be sure to add `.env` to your `.gitignore` file to prevent exposing secrets.
Where to find Plivo Auth ID and Auth Token?
Log in to your Plivo console at https://console.plivo.com/. Your Auth ID and Auth Token are displayed on the main dashboard overview page. Your Plivo source number can be found under 'Messaging -> Phone Numbers'.
What is the RedwoodJS service for Plivo integration?
The `plivoCampaign` service is responsible for interacting with the Plivo SDK. It handles authentication, message sending, and logging. This service isolates the Plivo-specific logic from the rest of your RedwoodJS application, promoting code organization and maintainability.
How to handle Plivo API errors in RedwoodJS?
Use `try...catch` blocks around Plivo API calls to handle potential errors such as invalid credentials or network issues. Log error details using Redwood's logger and return user-friendly error messages in the GraphQL response. The example code also shows how to implement retries using the `async-retry` library for transient errors.
What is the role of Prisma in Plivo SMS integration?
Prisma, the ORM used by RedwoodJS, allows you to log sent messages and their statuses (sent, failed, pending) in a database. This provides a record of all SMS activity, enabling tracking and analysis of your campaign's performance.
How to test the Plivo SMS integration in RedwoodJS?
You can test using the GraphQL Playground at `http://localhost:8910/graphql` during development or through the form on the `/send-campaign` page. Test with valid and invalid phone numbers and messages to verify success and error handling. For more in-depth testing, mock the Plivo client in unit tests.
What phone number format should I use with Plivo?
Use the E.164 format for phone numbers, such as +14155552671. This international standard ensures compatibility and successful message delivery. Client-side and server-side validation should be in place to enforce this format in your application.
How to secure Plivo API keys in production?
Never commit `.env` to version control. When deploying, use your hosting provider's secure environment variable mechanisms (e.g., Netlify, Vercel, or Fly.io secrets) to store your Plivo API keys. This keeps sensitive information out of your codebase and protects your credentials.
How to implement retry logic for sending SMS with Plivo?
Use a library like `async-retry`. Wrap the `client.messages.create` call within the retry function, configuring the number of attempts and the backoff strategy. This ensures that temporary network or server errors don't permanently prevent your messages from being sent. Examine Plivo's error responses for more specific retry criteria.
What is the format of the GraphQL request for sending a Plivo SMS?
The request takes a JSON object with an `input` field containing the recipient's phone number (`to` in E.164 format) and the message text (`text`). For example: `{"input": {"to": "+14155552671", "text": "Hello from Redwood!"}}`
What does the GraphQL response look like after sending a Plivo SMS?
The response will be a JSON object indicating success or failure. A successful response includes a `messageId` (Plivo's UUID for the message). A failed response includes an `error` message. Example success: `{"data": {"sendPlivoMessage": {"success": true, "messageId": "UUID", "error": null}}}`. Example failure: `{"data": {"sendPlivoMessage": {"success": false, "messageId": null, "error": "Error message"}}}`