Multimedia Messaging Service (MMS) allows you to enrich your user communication by sending images, videos, and audio alongside text. This guide provides a comprehensive, step-by-step walkthrough for building a production-ready service to send MMS messages using Node.js, Express, and the Plivo communication platform.
We'll start with a basic script and progressively build towards a robust API endpoint capable of handling MMS requests, covering setup, core implementation, error handling, security, and deployment considerations.
Project Overview and Goals
What We're Building:
We will create a Node.js application that can programmatically send MMS messages via Plivo's API. This involves:
- A standalone script for sending a single MMS message.
- An Express.js API endpoint (
POST /send-mms
) that accepts recipient details, text, and a media URL to send an MMS.
Problem Solved:
This guide enables developers to integrate rich media messaging capabilities into their applications, moving beyond simple text (SMS) to create more engaging user experiences for notifications, alerts, marketing, or customer support.
Technologies Used:
- Node.js: A JavaScript runtime environment ideal for building scalable network applications.
- Express.js: A minimal and flexible Node.js web application framework used here to create an API endpoint.
- Plivo: A cloud communications platform providing APIs for voice, SMS, and MMS. We'll use their Node.js SDK.
dotenv
: A module to load environment variables from a.env
file, keeping sensitive credentials out of source code.
System Architecture:
The basic flow for sending an MMS via our API endpoint looks like this:
[Client Application (e.g., Frontend, Mobile App, Backend Service)]
|
| Makes HTTP POST request to /send-mms
| (with destination number, text, media URL)
V
[Node.js/Express API Server] --(Uses Plivo SDK)--> [Plivo API Platform]
| |
| 1. Receives request | 2. Processes request, validates
| 2. Validates input | 3. Sends MMS via carrier networks
| 3. Uses Plivo SDK to call Plivo's API |
| 4. Returns response (success/failure) |
V V
[Client Application] [Recipient's Mobile Device]
| |
| Receives API response | Receives MMS message
Prerequisites:
- Node.js and npm (or yarn): Installed on your system. (Verify with
node -v
andnpm -v
). - Plivo Account: Sign up for a free Plivo trial account if you don't have one.
- Plivo Auth ID and Auth Token: Found on the overview page of your Plivo console after signing up.
- An MMS-Enabled Plivo Phone Number: You need a US or Canadian Plivo number (long code or toll-free) that supports MMS. You can check capabilities and purchase numbers in the Plivo console under Phone Numbers > Buy Numbers.
- (Trial Account Limitation): If using a Plivo trial account, you can only send MMS to phone numbers verified in your Plivo console under Phone Numbers > Sandbox Numbers. Trial accounts may also have other limitations (e.g., daily message volume caps, Plivo branding on messages). Please consult the official Plivo documentation for current trial account details.
Expected Outcome:
By the end of this guide, you will have a functional Node.js application capable of sending MMS messages programmatically, both via a direct script and through a secure, testable API endpoint. You will understand the key configuration steps, error handling, and best practices for using Plivo's MMS API.
1. Setting Up the Project
Let's initialize our Node.js project and install the necessary dependencies.
-
Create Project Directory: Open your terminal or command prompt and create a new directory for your project, then navigate into it.
mkdir plivo-mms-sender cd plivo-mms-sender
-
Initialize Node.js Project: This command creates a
package.json
file to manage your project's dependencies and scripts. The-y
flag accepts the default settings.npm init -y
-
Install Dependencies: We need the Plivo Node.js SDK, the Express framework, and
dotenv
for managing environment variables.npm install plivo express dotenv
plivo
: The official Plivo library for interacting with their API.express
: The web server framework for building our API endpoint.dotenv
: To load environment variables from a.env
file.
-
Create Project Structure: Set up the basic file structure:
plivo-mms-sender/ ├── node_modules/ ├── .env # Stores environment variables (API keys, phone number) - DO NOT COMMIT ├── .gitignore # Specifies intentionally untracked files that Git should ignore ├── send-mms.js # Standalone script for sending MMS ├── app.js # Express application with the API endpoint ├── package.json └── package-lock.json
-
Configure Environment Variables (
.env
): Create a file named.env
in the root of your project. This file will hold your sensitive Plivo credentials and your Plivo phone number. Never commit this file to version control.# .env PLIVO_AUTH_ID=YOUR_PLIVO_AUTH_ID PLIVO_AUTH_TOKEN=YOUR_PLIVO_AUTH_TOKEN PLIVO_SENDER_NUMBER=YOUR_MMS_ENABLED_PLIVO_NUMBER
- Replace
YOUR_PLIVO_AUTH_ID
andYOUR_PLIVO_AUTH_TOKEN
with the credentials from your Plivo Console dashboard. - Replace
YOUR_MMS_ENABLED_PLIVO_NUMBER
with the E.164 formatted Plivo phone number you obtained (e.g.,+14155551212
).
- Replace
-
Configure
.gitignore
: Create a file named.gitignore
in the root of your project. Addnode_modules
and.env
to prevent committing them to your Git repository.# .gitignore node_modules .env
Why
.gitignore
? It's crucial for security and efficiency.node_modules
can be large and easily reinstalled usingnpm install
..env
contains sensitive API keys that should never be exposed in your codebase history.
Now your project environment is set up and ready for implementation.
2. Implementing Core Functionality: Sending a Single MMS
First, let's create a simple script to send one MMS message directly using the Plivo SDK. This helps verify your credentials and Plivo number setup.
-
Create the Sending Script (
send-mms.js
): Create the filesend-mms.js
and add the following code:// send-mms.js require('dotenv').config(); // Load environment variables from .env file const plivo = require('plivo'); // Ensure environment variables are loaded const authId = process.env.PLIVO_AUTH_ID; const authToken = process.env.PLIVO_AUTH_TOKEN; const senderNumber = process.env.PLIVO_SENDER_NUMBER; if (!authId || !authToken || !senderNumber) { console.error('Error: Plivo credentials or sender number not found in .env file.'); process.exit(1); // Exit if credentials are missing } // --- Configuration --- // IMPORTANT: Replace with the recipient's phone number in E.164 format. // If using a Plivo trial account, this MUST be a number verified // in your Plivo Console under Phone Numbers > Sandbox Numbers. const recipientNumber = '+14155551234'; // Example - CHANGE THIS to a valid recipient number // Replace with the URL of the media file you want to send (must be publicly accessible) const mediaUrl = 'https://media.giphy.com/media/26gscSULUcfKU7dHq/source.gif'; // Example GIF - CHANGE THIS if needed // The text content of your message const messageText = 'Hello from Node.js with Plivo MMS!'; // --- End Configuration --- // Create a Plivo client instance const client = new plivo.Client(authId, authToken); console.log(`Attempting to send MMS from ${senderNumber} to ${recipientNumber}...`); // Use the client to send the message client.messages.create({ src: senderNumber, // Your Plivo phone number (must be MMS enabled) dst: recipientNumber, // The destination phone number text: messageText, // The text part of the message type: 'mms', // Specify message type as MMS media_urls: [mediaUrl] // Array of publicly accessible URLs for media files // You can also use media_ids if you've uploaded media to Plivo: // media_ids: ['YOUR_UPLOADED_MEDIA_ID'] }) .then(function(message_created) { console.log('MMS Sent Successfully!'); console.log('Message UUID:', message_created.messageUuid[0]); // Plivo returns UUIDs in an array console.log('API Response:', message_created); }) .catch(function(error) { console.error('Error sending MMS:', error); });
-
Explanation:
require('dotenv').config();
: Loads the variables from your.env
file intoprocess.env
.- Credential Check: Basic validation ensures the script doesn't run without necessary credentials.
- Configuration: Clearly defined variables for recipient number, media URL, and text. It is critical to change
recipientNumber
to a valid target number before running. If using a trial account, ensure it's a verified sandbox number. new plivo.Client()
: Initializes the connection to the Plivo API using your Auth ID and Token.client.messages.create()
: This is the core function call.src
: Your MMS-enabled Plivo number (from.env
).dst
: The recipient's number.text
: The message body.type: 'mms'
: Crucial for sending MMS. Without this, it defaults to SMS.media_urls
: An array containing one or more publicly accessible URLs pointing to the media files (images, GIFs, videos, audio). Plivo fetches the media from these URLs. Ensure the URLs are valid and accessible.
.then()
: Handles the successful API response from Plivo, typically containing message UUIDs and status information..catch()
: Catches and logs any errors during the API call (e.g., invalid credentials, invalid number format, inaccessible media URL).
-
Run the Script: Execute the script from your terminal:
node send-mms.js
-
Verification:
- Check your terminal for the ""MMS Sent Successfully!"" message and the response details from Plivo.
- Check the recipient's phone – they should receive the MMS message shortly.
- Check the Plivo Console under Logs > Messaging Logs for the status of the sent message.
- If you encounter errors, check the console output and refer to the ""Troubleshooting"" section below. Common issues include incorrect credentials, non-verified sandbox numbers (for trial accounts), invalid recipient number format (use E.164:
+1...
), or inaccessiblemedia_urls
.
3. Building an API Layer with Express
While the script is useful for testing, a more practical approach is to create an API endpoint that other services or frontends can call to send MMS messages.
-
Create the Express App (
app.js
): Create the fileapp.js
and add the following code:// app.js require('dotenv').config(); const express = require('express'); const plivo = require('plivo'); const app = express(); const port = process.env.PORT || 3000; // Use environment variable for port or default to 3000 // Middleware to parse JSON bodies app.use(express.json()); // Middleware to parse URL-encoded bodies (often used by HTML forms) app.use(express.urlencoded({ extended: true })); // --- Plivo Configuration --- const authId = process.env.PLIVO_AUTH_ID; const authToken = process.env.PLIVO_AUTH_TOKEN; const senderNumber = process.env.PLIVO_SENDER_NUMBER; if (!authId || !authToken || !senderNumber) { console.error('CRITICAL ERROR: Plivo credentials or sender number not found in .env file. API cannot start.'); process.exit(1); // Prevent server start if config is missing } const plivoClient = new plivo.Client(authId, authToken); // --- End Plivo Configuration --- // --- API Endpoint: POST /send-mms --- app.post('/send-mms', async (req, res) => { const { recipientNumber, messageText, mediaUrl } = req.body; // --- Basic Input Validation --- if (!recipientNumber || !messageText || !mediaUrl) { return res.status(400).json({ error: 'Missing required fields: recipientNumber, messageText, mediaUrl', }); } // Basic E.164 format check (improves reliability but not foolproof) // Consider libraries like 'libphonenumber-js' for robust validation in production. if (!/^\+[1-9]\d{1,14}$/.test(recipientNumber)) { return res.status(400).json({ error: 'Invalid recipientNumber format. Use E.164 format (e.g., +14155551212).', }); } // Basic URL validation try { new URL(mediaUrl); } catch (_) { return res.status(400).json({ error: 'Invalid mediaUrl format.' }); } // --- End Basic Input Validation --- console.log(`API Request: Send MMS from ${senderNumber} to ${recipientNumber}`); try { // This implementation expects a single mediaUrl from the request body // and passes it as a single-element array to Plivo. const response = await plivoClient.messages.create({ src: senderNumber, dst: recipientNumber, text: messageText, type: 'mms', media_urls: [mediaUrl], // Expecting a single URL for simplicity here }); console.log('Plivo API Success:', response); res.status(200).json({ message: 'MMS sent successfully initiated.', messageUuid: response.messageUuid[0], // Extract the UUID plivoResponse: response, }); } catch (error) { console.error('Plivo API Error:', error); // Provide more specific feedback if possible let statusCode = 500; let errorMessage = 'Failed to send MMS due to an internal server error.'; if (error.statusCode) { // Use Plivo's status code if available (e.g., 400 Bad Request, 401 Unauthorized) statusCode = error.statusCode; errorMessage = error.message || 'Plivo API request failed.'; } res.status(statusCode).json({ error: errorMessage, details: error.message, // Include Plivo's error message if helpful }); } }); // --- Health Check Endpoint --- app.get('/health', (req, res) => { res.status(200).json({ status: 'UP', timestamp: new Date().toISOString() }); }); // --- Start Server --- app.listen(port, () => { console.log(`MMS Sender API listening on port ${port}`); console.log(`Plivo Sender Number: ${senderNumber}`); if (process.env.NODE_ENV !== 'production') { console.log(`\nTest endpoint locally using curl (replace placeholders!):\n`); console.log(`curl -X POST http://localhost:${port}/send-mms -H ""Content-Type: application/json"" -d '{""recipientNumber"": ""+1..."", ""messageText"": ""API Test"", ""mediaUrl"": ""https://...""}'\n`); } });
-
Explanation:
- Dependencies: Imports
express
andplivo
, loads.env
. - Middleware:
express.json()
andexpress.urlencoded()
are essential for parsing incoming request bodies (JSON and form data). - Plivo Client: The client is initialized once when the app starts.
/send-mms
Endpoint (POST):- Defines a route that listens for
POST
requests at the/send-mms
path. - Extracts
recipientNumber
,messageText
, andmediaUrl
from the request body (req.body
). - Input Validation: Performs basic checks: presence of required fields, basic E.164 format for the number, and basic URL validity. The E.164 regex (
^\+[1-9]\d{1,14}$
) is a basic check; while helpful, it might allow technically invalid numbers (e.g., incorrect length for a country). For production, using a dedicated library likelibphonenumber-js
is highly recommended for robust phone number validation. mediaUrl
Handling: This implementation expects a singlemediaUrl
field in the request body. It then wraps this URL in an array ([mediaUrl]
) as required by the Plivo API'smedia_urls
parameter. The API could be modified to accept an array of URLs directly if needed.- Async/Await: Uses
async/await
for cleaner handling of the asynchronous Plivo API call. - Plivo Call: Calls
plivoClient.messages.create
within atry...catch
block. - Success Response (200): If the Plivo API call is successful (doesn't throw an error), it sends back a JSON response confirming initiation and includes the message UUID.
- Error Response (400/500): If validation fails (400) or the Plivo API call throws an error (usually 500, but uses Plivo's status code if available), it logs the error and sends back a JSON error response.
- Defines a route that listens for
/health
Endpoint (GET): A simple endpoint used for monitoring to check if the service is running.app.listen()
: Starts the Express server on the specified port and provides a samplecurl
command for local testing.
- Dependencies: Imports
-
Run the API Server: Execute the app from your terminal:
node app.js
You should see the message ""MMS Sender API listening on port 3000"" and the sample
curl
command. -
Test the API Endpoint: You can use
curl
(or tools like Postman or Insomnia) to send a POST request to your running server. Open a new terminal window (leave the server running in the first one).IMPORTANT: Replace the placeholder values below (
+14155551234
and themediaUrl
) with a valid recipient number (remember the sandbox verification requirement if using a Plivo trial account) and a working, publicly accessible media URL.curl -X POST http://localhost:3000/send-mms \ -H ""Content-Type: application/json"" \ -d '{ ""recipientNumber"": ""+14155551234"", ""messageText"": ""Testing MMS from my API!"", ""mediaUrl"": ""https://media.giphy.com/media/3o7TKS6AWgP3FpO2LS/giphy.gif"" }'
-
Verification:
- API Response: You should receive a JSON response in your terminal like:
{ ""message"": ""MMS sent successfully initiated."", ""messageUuid"": ""some-uuid-string-from-plivo"", ""plivoResponse"": { ... detailed Plivo response ...} }
- Server Logs: Check the terminal where
node app.js
is running for log messages. - Recipient Phone: The MMS should arrive on the recipient's device.
- Plivo Console: Check the Messaging Logs.
- Error Testing: Try sending requests with missing fields, invalid numbers, or invalid URLs to see the error responses (e.g., 400 Bad Request).
- API Response: You should receive a JSON response in your terminal like:
4. Integrating with Plivo (Details)
We've already used the Plivo credentials, but let's recap where to find them and how they're used.
-
Auth ID and Auth Token:
- Purpose: These act like your username and password for the Plivo API. They authenticate your requests.
- How to Obtain: Log in to your Plivo Console. They are prominently displayed on the main Dashboard/Overview page.
- Secure Storage: Store these in environment variables (
.env
locally, secure configuration management in production) and never hardcode them directly into your source code. Usedotenv
locally and your deployment platform's environment variable system in production.
-
MMS-Enabled Plivo Number (
src
):- Purpose: This is the phone number from which your MMS messages will appear to be sent. It must be capable of sending MMS messages in the US and Canada.
- How to Obtain/Verify:
- Go to Phone Numbers > Your Numbers in the Plivo Console.
- Check the ""Capabilities"" column for your existing numbers. Look for ""MMS"".
- If you need a new number, go to Phone Numbers > Buy Numbers. Filter by ""MMS"" capability and select a US or Canadian number (Long Code or Toll-Free).
- Note: Toll-free numbers may require verification for messaging, follow Plivo's guidelines.
- Format: Use the E.164 format (e.g.,
+14155551212
). - Storage: Store this in your
.env
file asPLIVO_SENDER_NUMBER
.
-
Media URLs (
media_urls
):- Purpose: Plivo needs publicly accessible URLs to fetch the media files (images, videos, audio, GIFs) you want to include in the MMS.
- Requirements:
- Must be publicly accessible (not behind firewalls or login pages).
- Plivo supports various formats (JPEG, PNG, GIF, MP3, MP4, etc.). Check Plivo's documentation for the latest supported types and size limits.
- URLs should be stable.
- Alternative (
media_ids
): You can upload media directly to Plivo via their console (Messaging > MMS Media Upload) or API. Uploaded media gets amedia_id
. You can then usemedia_ids: ['YOUR_MEDIA_ID']
instead ofmedia_urls
. This can be useful for frequently used media or if you don't have a public hosting location.
-
Plivo Console Dashboard: Familiarize yourself with:
- Dashboard: Auth ID/Token, account balance.
- Messaging > Logs: Check the status, content, and any errors for sent/received messages. Indispensable for debugging.
- Phone Numbers > Your Numbers / Buy Numbers: Manage your Plivo numbers.
- Phone Numbers > Sandbox Numbers: Verify recipient numbers for testing during a trial.
- Messaging > MMS Media Upload: Manage pre-uploaded media files.
5. Error Handling, Logging, and Retry Mechanisms
Robust applications need solid error handling and logging.
-
Error Handling Strategy:
- API Level: Use
try...catch
blocks around asynchronous operations like Plivo API calls. - Validation: Catch invalid inputs early (as shown in
app.js
) and return clear4xx
error responses. - Plivo Errors: The Plivo SDK throws errors that often contain useful information, including Plivo-specific error messages and sometimes HTTP status codes. Catch these errors and log them. Return appropriate HTTP status codes (
5xx
for server/Plivo issues,4xx
for client errors) and informative JSON error messages to the API caller. - Network Issues: Network problems between your server and Plivo can occur. Ensure your
catch
blocks handle generic network errors too.
- API Level: Use
-
Logging:
- Basic Logging:
console.log
andconsole.error
are sufficient for simple cases and development. - Production Logging: For production, use a dedicated logging library like
winston
orpino
. These offer:- Log Levels: (debug, info, warn, error) – Allows filtering logs based on severity.
- Structured Logging: Output logs in JSON format for easier parsing by log management systems (like Datadog, Splunk, ELK stack).
- Transports: Send logs to files, databases, or external logging services.
- What to Log:
- Incoming API requests (excluding sensitive data).
- Key parameters used in Plivo calls (sender, recipient, media URL type).
- Successful Plivo API responses (especially message UUIDs).
- Detailed error information when Plivo calls fail (stack traces, error messages, Plivo status codes).
- Validation failures.
Example using
console
(can be adapted for libraries):// Inside the /send-mms route console.info(`[INFO] Received request to send MMS to ${recipientNumber}`); // ... validation ... try { // ... plivo call ... const response = await plivoClient.messages.create({ /* ... params ... */ }); console.info(`[SUCCESS] Plivo API call successful for ${recipientNumber}. UUID: ${response.messageUuid[0]}`); res.status(200).json(/* ... */); } catch (error) { console.error(`[ERROR] Plivo API call failed for ${recipientNumber}. Status: ${error.statusCode || 'N/A'}, Message: ${error.message}`, error); // Log full error object too // Determine statusCode based on error const statusCode = error.statusCode && error.statusCode >= 400 && error.statusCode < 500 ? error.statusCode : 500; res.status(statusCode).json(/* ... */); }
- Basic Logging:
-
Retry Mechanisms:
- Why: Transient network issues or temporary Plivo outages might cause API calls to fail. Retrying can improve reliability.
- Strategy: Implement exponential backoff. If a request fails_ wait a short period (e.g._ 1 second)_ retry. If it fails again_ wait longer (e.g._ 2 seconds)_ retry. Increase the delay exponentially up to a maximum number of retries.
- Implementation: Libraries like
async-retry
orp-retry
can simplify this. Be cautious about retrying errors that are clearly not transient (e.g._ 401 Unauthorized_ 400 Bad Request due to invalid number format). Only retry on likely temporary issues (e.g._ 5xx errors_ network timeouts).
Conceptual example (without a library):
async function sendMmsWithRetry(params_ retries = 3_ delay = 1000) { try { return await plivoClient.messages.create(params); } catch (error) { // Only retry on specific error types (e.g._ network or 5xx) // Example condition: retry on network errors or Plivo server errors (5xx) const shouldRetry = !error.statusCode || error.statusCode >= 500 || (error.code && ['ECONNRESET', 'ETIMEDOUT', 'ENETUNREACH'].includes(error.code)); if (retries > 0 && shouldRetry) { console.warn(`[RETRY] Plivo call failed, retrying in ${delay}ms... (${retries} retries left)`); await new Promise(resolve => setTimeout(resolve, delay)); // Exponential backoff: double the delay for the next retry return sendMmsWithRetry(params, retries - 1, delay * 2); } else { console.error(`[FAIL] Plivo call failed after retries or due to non-retryable error.`); throw error; // Re-throw the error if retries exhausted or not retryable } } } // In your API route: // try { // const response = await sendMmsWithRetry({ /* Plivo params */ }); // // Handle success // } catch (error) { // // Handle final failure // }
6. Creating a Database Schema and Data Layer (Considerations)
While our simple API doesn't require a database, a production system often benefits from one for:
- Tracking Message Status: Storing the
messageUuid
returned by Plivo and later updating its status (sent, delivered, failed) using Plivo's message status callbacks (webhooks). - Auditing and History: Keeping a log of all MMS messages sent, including recipient, content (or reference), timestamp, and status.
- User Data: Associating MMS messages with specific users in your application.
- Rate Limiting/Analytics: Storing usage data.
If adding a database (e.g., PostgreSQL with Prisma):
-
Schema Design (Conceptual
schema.prisma
):// schema.prisma datasource db { provider = ""postgresql"" // or mysql, sqlite, sqlserver, mongodb url = env(""DATABASE_URL"") } generator client { provider = ""prisma-client-js"" } model MmsMessage { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt plivoMessageUuid String? @unique // Store the UUID returned by Plivo senderNumber String // Your Plivo number used recipientNumber String // The destination number messageText String? mediaUrl String? mediaId String? // If using Plivo media upload status String @default(""initiated"") // e.g., initiated, queued, sent, delivered, failed, undelivered plivoStatus String? // Store the status from Plivo callback errorCode String? // Store Plivo error code on failure // Optional: Link to a User model if applicable // userId String? // user User? @relation(fields: [userId], references: [id]) @@index([recipientNumber]) @@index([plivoMessageUuid]) @@index([status]) } // model User { ... } // If needed
-
Data Access: Use an ORM like Prisma or Sequelize to interact with the database, providing type safety and simplifying queries. Your API endpoint would first save a record with
status: 'initiated'
and then update it based on the Plivo API response or subsequent status callbacks. -
Migrations: Use the ORM's migration tools (e.g.,
prisma migrate dev
,sequelize db:migrate
) to manage schema changes safely.
This section is conceptual. Implementing a full database layer is beyond the scope of this specific MMS sending guide but is a common next step for production systems.
7. Adding Security Features
Securing your API endpoint is crucial.
-
Input Validation and Sanitization:
- Validation: We added basic checks. Use robust libraries (
joi
,express-validator
,libphonenumber-js
) to enforce strict rules onrecipientNumber
(valid E.164 format),messageText
(length limits, character types), andmediaUrl
(valid URL format, perhaps restricting domains). - Sanitization: While less critical for API parameters passed directly to Plivo, if you were embedding user input into
messageText
that might be displayed elsewhere, use libraries likedompurify
(for HTML) or ensure proper escaping to prevent cross-site scripting (XSS). Plivo handles the SMS/MMS encoding.
- Validation: We added basic checks. Use robust libraries (
-
Authentication/Authorization:
- Our current API is open. In production, you need to protect it.
- API Keys: Issue unique API keys to trusted clients. Clients include the key in a header (e.g.,
Authorization: Bearer YOUR_API_KEY
orX-API-Key: YOUR_API_KEY
). Your Express app verifies the key against a stored list/database before processing the request. - JWT/OAuth: For user-centric applications, use standard authentication flows like JSON Web Tokens or OAuth.
-
Rate Limiting:
- Prevent abuse and control costs by limiting how many requests a client can make in a given time window.
- Use middleware like
express-rate-limit
. Configure it based on IP address or API key.
Example using
express-rate-limit
:npm install express-rate-limit
// app.js const rateLimit = require('express-rate-limit'); const apiLimiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 100, // Limit each IP to 100 requests per windowMs message: 'Too many requests from this IP, please try again after 15 minutes', standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers legacyHeaders: false, // Disable the `X-RateLimit-*` headers }); // Apply the rate limiting middleware to API routes // Apply it before your main route handler for /send-mms app.use('/send-mms', apiLimiter); // ... rest of your app.js, including the app.post('/send-mms', ...) route ...
-
HTTPS: Always use HTTPS in production to encrypt data in transit. Deployment platforms like Heroku or using a reverse proxy like Nginx typically handle TLS/SSL termination.
-
Environment Variables: Keep sensitive data (API keys, Plivo Auth tokens) out of your code using environment variables. Ensure your
.env
file is in.gitignore
. For production, do not deploy the.env
file. Instead, use your hosting platform's built-in environment variable configuration (e.g., Heroku Config Vars, AWS Parameter Store, Azure App Configuration) or a dedicated secrets management service (e.g., AWS Secrets Manager, HashiCorp Vault).