Frequently Asked Questions
Use Node.js with Express.js and the Plivo Node.js SDK to build an application that interacts with the Plivo API for sending SMS messages. The application can accept campaign details, send messages, handle replies, and store campaign data. This guide provides a walkthrough for setting up this system.
Plivo is a cloud communication platform that provides the necessary infrastructure for sending SMS messages, managing phone numbers, and receiving webhooks for incoming replies and delivery reports. It acts as the SMS gateway for the Node.js application.
Node.js is chosen for its asynchronous, event-driven architecture. This makes it highly efficient for I/O-heavy tasks like handling API interactions and webhook requests, which are central to sending and managing SMS campaigns effectively.
Express.js simplifies the creation of the web server and API endpoints needed for managing campaign requests and Plivo webhooks. It provides a minimal and flexible framework for handling HTTP requests and responses.
Use npm (or yarn) to install the required packages: npm install express plivo dotenv body-parser
. For development, install nodemon
with: npm install --save-dev nodemon
to automatically restart the server on code changes.
ngrok creates a public tunnel to your locally running development server. This allows Plivo's webhooks to reach your application during development, as Plivo needs a publicly accessible URL to send webhook requests to.
Create a .env
file in the project root and store your Plivo Auth ID, Auth Token, Plivo phone number, server port, and ngrok URL (during development) in this file. This is crucial for security best practices.
Configure a Plivo application with a webhook URL pointing to your /webhooks/inbound-sms
endpoint. When a user replies to a campaign message, Plivo will send a request to this URL. You can then process the reply within your application.
In your Plivo Application settings, configure a Delivery Report URL pointing to an endpoint in your app, such as /webhooks/status
, and select the POST
method. Plivo will then send delivery status updates (e.g., sent, delivered, failed) to this URL.
While the tutorial provides a simplified example, for production systems, avoid sending many messages in a tight loop. Implement rate limiting, such as sending one message per second, or use a message queue like RabbitMQ or Redis Queue for better performance and reliability.
Your Plivo Auth ID and Auth Token can be found on your Plivo Console dashboard under "API -> Keys & Tokens". These credentials are necessary to authenticate with the Plivo API.
Trial Plivo accounts have limitations. You can send test messages to verified numbers within your Plivo Sandbox. Ensure the recipient numbers you use for testing are added and verified in your sandbox environment.
The tutorial uses an in-memory store for simplicity, but this isn't suitable for production. Integrate a database (e.g., PostgreSQL, MySQL, MongoDB) to persist campaign details, recipient information, and message statuses reliably.
Robust input validation prevents unexpected errors and potential security issues. The tutorial demonstrates basic checks, but use libraries like express-validator to thoroughly sanitize and validate user-provided data in a production environment.
Complete Guide: Sending Bulk SMS Marketing Campaigns with Plivo (Node.js, Express)
This guide walks you through building a production-ready SMS marketing campaign system using Plivo's SMS API, Node.js, and Express. You'll learn everything from initial project setup to deployment, monitoring, and handling real-world complexities like bulk messaging, TCPA compliance, and rate limiting.
Note: This guide uses the Express framework. You can adapt these concepts and Plivo integration patterns for Next.js API routes and Supabase for data persistence (covered in Section 6).
By the end of this tutorial, you'll have a functional marketing automation application that sends targeted SMS messages, handles replies, and manages campaign data – built with scalability, security, and reliability in mind.
Project Overview and Goals
What You'll Build:
A Node.js application using Express that enables you to define and execute SMS marketing campaigns via Plivo's API. Your system will:
Problem This Solves:
Automating bulk SMS messages for marketing or notifications provides a more scalable and manageable solution than manual sending. It establishes a foundation for tracking campaign effectiveness and handling customer responses.
Compliance Is Critical:
SMS marketing is heavily regulated. Your application must comply with:
Technologies You'll Use:
System Architecture:
Your system follows this flow:
Prerequisites for Building Plivo SMS Marketing Campaigns
Before you start building your SMS marketing system, ensure you have:
ngrok
installed for local webhook testing (Download ngrok).Step 1: Initialize Your Node.js SMS Marketing Project
Initialize your Node.js project and install the necessary dependencies.
Create Project Directory: Open your terminal and create a new directory for the project, then navigate into it.
Initialize Node.js Project: Create a
package.json
file to manage dependencies and project metadata.Install Dependencies: Install Express for the web server, the Plivo SDK,
dotenv
for environment variables, andbody-parser
for parsing request bodies. Addnodemon
for development – it automatically restarts the server on file changes.Configure
nodemon
(Optional but Recommended): Add a script to yourpackage.json
for easy development server startup. Openpackage.json
and add/modify thescripts
section:You can now run
npm run dev
to start the server with automatic restarts.Set up Environment Variables: Create a file named
.env
in the project root. This file will store sensitive credentials and configurations. Never commit this file to version control.PLIVO_AUTH_ID
/PLIVO_AUTH_TOKEN
: Find these on your Plivo Console dashboard under ""API -> Keys & Tokens"".PLIVO_SENDER_ID
: The Plivo phone number you purchased or will use for sending messages, in E.164 format (e.g.,+12025551234
). For countries outside the US/Canada, you might use an Alphanumeric Sender ID if registered and approved by Plivo.PORT
: The port your Express server will listen on.BASE_URL
: The publicly accessible URL where your application will be hosted. During development, this will be yourngrok
forwarding URL.Create Basic Project Structure: Organize your code for better maintainability.
Configure
.gitignore
: Create a.gitignore
file in the root directory to prevent sensitive files and unnecessary directories from being committed to Git.Initialize Plivo Client: Create a file to encapsulate the Plivo client initialization using the environment variables.
> Why: Centralizing the client creation makes it easy to manage and reuse throughout the application. Using
dotenv.config()
loads the variables from.env
.Create Main Application File (
index.js
): Set up the basic Express server.> Why: This sets up the core Express application, includes necessary middleware for parsing request bodies, defines a basic health check, mounts routers for different functionalities, includes a simple error handler, and starts the server listening on the configured port.
You now have a structured project ready for implementing the core campaign logic.
2. Install Plivo SMS API SDK and Dependencies
We'll focus on the service layer responsible for sending the campaign messages.
Define Campaign Service Logic: Create the
services/campaignService.js
file. This service will take campaign details and send messages via Plivo. For now, we'll use an in-memory store for simplicity, but structure it for potential database integration later.> Note: The in-memory store used here is not suitable for production; Section 6 outlines database integration.
> Why: This isolates the logic for interacting with Plivo and managing campaign state. It uses the configured Plivo client, iterates through recipients (with basic validation and delay), calls
plivoClient.messages.create
, and stores results in memory. It includes crucial comments about rate limiting, queuing, and the need for a database for production readiness. ThegetCampaignStatus
function provides a way to check progress.3. Building a Complete API Layer
Now, let's create the Express routes to expose our campaign functionality.
Create Campaign Routes File: Define the endpoints for creating and checking campaigns in
routes/campaign.js
.> Why: This sets up two endpoints: > *
POST /api/campaigns
: Takes a list of recipients and a message. It performs basic validation, generates a uniquecampaignId
(usinguuid
), initiates thesendCampaign
service asynchronously (so the API responds quickly), and returns a202 Accepted
status with thecampaignId
and a URL to check the status. > *GET /api/campaigns/:campaignId/status
: Allows checking the progress/results using thecampaignId
.Install
uuid
: This code uses theuuid
package to generate unique IDs. Install it:Testing with
curl
: Start your server:npm run dev
Send a Campaign: Replace the placeholder numbers
+1SANDBOXNUMBER1
and+1SANDBOXNUMBER2
with actual phone numbers verified in your Plivo Sandbox account. Remember trial accounts can only send to verified numbers.You should receive a response like:
Check Status: Use the
campaignId
from the previous response.Initially, it might show
{""status"":""processing"",""results"":[]}
. After a short while, it should show{""status"":""completed"", ""results"": [...]}
with details for each recipient.4. Integrating with Third-Party Services (Plivo Webhooks)
To handle replies or delivery reports, we need to configure Plivo to send HTTP requests (webhooks) to our application.
Start
ngrok
: If your server is running locally on port 3000, expose it to the internet:ngrok
will display a forwarding URL (e.g.,https://<unique-subdomain>.ngrok.io
). Copy thehttps
version.Update
.env
: Set theBASE_URL
in your.env
file to yourngrok
forwarding URL. Restart your Node.js server after changing.env
.Configure Plivo Application:
${BASE_URL}/webhooks/inbound-sms
. For example:https://<your-unique-subdomain>.ngrok.io/webhooks/inbound-sms
.POST
.${BASE_URL}/webhooks/status
) if you want delivery status updates. Set method toPOST
.Assign Application to Plivo Number:
PLIVO_SENDER_ID
.XML Application
(orMessaging Application
if you chose that type).Create Webhook Routes File: Define the endpoint to handle incoming SMS messages in
routes/webhooks.js
.> Why: This file defines the
/webhooks/inbound-sms
endpoint. When Plivo receives an SMS to your configured number, it POSTs data (like sender number, message text) to this URL. The code logs the incoming message details. It shows different options for responding: simply acknowledging receipt (required), sending an immediate XML-based auto-reply, or handling it for a later API-based reply. An optional/status
endpoint demonstrates handling delivery reports.Testing Webhooks:
ngrok
is running andBASE_URL
is set correctly in.env
.npm run dev
).5. Implementing Proper Error Handling, Logging, and Retry Mechanisms
Production systems need robust error handling and logging.
Consistent Error Handling Strategy:
try...catch
blocks for asynchronous operations (API calls, DB interactions).next
function (next(error);
).index.js
.Logging:
console.log
,console.warn
,console.error
might suffice initially.winston
orpino
for structured logging (JSON format), log levels (info, warn, error, debug), and outputting to files or log management services.Install
winston
:Example using
winston
:Retry Mechanisms: Network issues or temporary Plivo API glitches can occur. Implement retries for critical operations like sending messages. Use libraries like
async-retry
or implement manual exponential backoff.Install
async-retry
:Example using
async-retry
:Frequently Asked Questions About Plivo SMS Marketing
How much does Plivo SMS marketing cost?
Plivo SMS pricing varies by destination country. US/Canada SMS costs approximately $0.0075-$0.01 per segment. International rates vary significantly. Volume discounts are available for high-volume senders. Check Plivo's pricing page for current rates by country.
What is TCPA compliance for SMS marketing?
TCPA (Telephone Consumer Protection Act) requires express written consent before sending promotional SMS messages. Under the FCC's December 2023 ruling, consent must be specific to your business – you cannot share consent across multiple companies. You must provide opt-out mechanisms (STOP keyword) and honor requests within seconds.
What are Plivo's SMS rate limits?
Plivo enforces a default limit of 100 simultaneous API requests. Additionally, your account has a configured messages-per-second (MPS) rate. If you exceed limits, Plivo returns HTTP 429 "Too Many Requests" – messages are queued, not lost. For higher throughput, implement message queuing (RabbitMQ, Redis Queue) or use number pooling.
Can I send SMS with Plivo using Next.js?
Yes. While this guide uses Express, Plivo works seamlessly with Next.js API routes. Replace Express endpoints with Next.js API route handlers in the
/pages/api
or/app/api
directory. The Plivo SDK code remains identical. See Section 6 for Supabase integration patterns.What is SHAFT content and why is it prohibited?
SHAFT stands for Sex, Hate, Alcohol, Firearms, Tobacco – content categories prohibited by CTIA Guidelines. Mobile carriers automatically block messages containing SHAFT content, and violations can result in immediate account suspension or permanent bans. Always review message content for compliance.
How do I test Plivo webhooks locally?
Use ngrok to expose your local development server to the internet. Run
ngrok http 3000
, copy the HTTPS URL (e.g.,https://abc123.ngrok.io
), and configure it as your webhook URL in the Plivo dashboard. Ngrok tunnels incoming webhook requests to your local Express server.What happens if a Plivo SMS fails to deliver?
Plivo provides detailed delivery reports via webhooks. Failed messages return error codes indicating the failure reason (invalid number, carrier rejection, blocked content, etc.). Implement retry logic with exponential backoff for transient failures. Monitor delivery rates to identify systematic issues.
How do I implement opt-out management with Plivo?
Handle incoming SMS webhooks, check for keywords (STOP, CANCEL, END, QUIT, UNSUBSCRIBE), and remove numbers from your campaign database. Confirm opt-out with a final message: "You've been unsubscribed. Reply START to opt back in." Process opt-outs in real-time to maintain TCPA compliance.
Conclusion
You've built a production-ready SMS marketing campaign system with Plivo, Node.js, and Express. Your application now handles bulk messaging, webhook callbacks, error handling, and retry logic – all while maintaining TCPA and CTIA compliance.
Key Takeaways:
Next Steps:
For questions about Plivo integration, consult the official Plivo Node.js SDK documentation and CTIA messaging guidelines.