This guide provides a step-by-step walkthrough for building a Node.js application using the Express framework to send MMS (Multimedia Messaging Service) messages via the Vonage Messages API. We will cover everything from project setup and Vonage configuration to building an API endpoint, handling errors, and considering security best practices.
Project Overview and Goals
What We're Building:
A simple Node.js Express API server with a single endpoint (/send-mms
). This endpoint accepts a destination phone number, an image URL, and an optional caption, then uses the Vonage Messages API to send an MMS message containing the image and caption to the specified recipient.
Problem Solved: This guide enables developers to programmatically send rich media content (images) via MMS to users in the United States, enhancing communication beyond plain text SMS. This is useful for notifications, alerts, marketing campaigns, or any application needing image delivery via messaging.
Technologies Used:
- Node.js: A JavaScript runtime environment chosen for its asynchronous, event-driven nature, making it well-suited for I/O-bound operations like API calls. Its vast ecosystem (npm) simplifies development.
- Express.js: A minimal and flexible Node.js web application framework used to quickly set up the API server and route requests.
- Vonage Messages API: A powerful Vonage API that enables sending messages across various channels, including MMS. We use it for its dedicated MMS capabilities and robust delivery infrastructure.
- dotenv: A utility to load environment variables from a
.env
file intoprocess.env
, keeping sensitive credentials out of the codebase. @vonage/messages
: The official Vonage Node.js SDK package specifically for interacting with the Messages API.
System Architecture:
+-------------+ +-----------------------+ +-----------------+ +-----------------+ +-----------------+
| HTTP Client | ----> | Node.js/Express API | ----> | Vonage Messages | ----> | Carrier Network | ---->| Recipient Phone |
| (Postman/App)| POST | (Your Server @ /send-mms) | | SDK Integration | | (MMS Delivery) | | (Receives MMS) |
+-------------+ +-----------------------+ +-----------------+ +-----------------+ +-----------------+
| Uses API Key, Secret, App ID, Private Key
| Sends To/From Numbers, Image URL, Caption
Prerequisites:
- Node.js and npm: Installed on your development machine. (LTS version recommended). Download Node.js
- Vonage API Account: Sign up for free. Vonage Dashboard
- Vonage API Key and Secret: Found on your Vonage dashboard after signup.
- US Vonage Phone Number: An SMS and MMS capable US number purchased through your Vonage account. MMS sending is currently restricted to US numbers for A2P (Application-to-Person) traffic.
- Vonage Application ID and Private Key File/Content: Generated during the Vonage Application setup (Section 2). You'll need these before running the code.
- Publicly Accessible Image URL: The image you want to send must be hosted at a URL accessible from the internet (e.g., cloud storage, CDN). Supported formats:
.jpg
,.jpeg
,.png
. - Basic understanding of JavaScript, Node.js, REST APIs, and terminal commands.
- (Optional but Recommended)
ngrok
or similar: For exposing local webhook endpoints during development if you plan to handle status updates (though not strictly required for sending only). ngrok
Final Outcome: By the end of this guide, you will have a running Node.js Express application capable of receiving API requests and sending MMS messages containing images using the Vonage Messages 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 vonage-mms-sender cd vonage-mms-sender
-
Initialize npm Project: This creates a
package.json
file to manage your project's dependencies and scripts. The-y
flag accepts default settings.npm init -y
-
Enable ES Modules: We'll use modern
import
/export
syntax. Open the generatedpackage.json
file and add the following line at the top level:// package.json { ""name"": ""vonage-mms-sender"", ""version"": ""1.0.0"", ""description"": """", ""main"": ""server.js"", ""type"": ""module"", // <-- Add this line ""scripts"": { ""start"": ""node server.js""_ ""dev"": ""node --watch server.js"" // Optional: for auto-restarting during development }_ ""keywords"": []_ ""author"": """"_ ""license"": ""ISC""_ ""dependencies"": {} }
Why
type: ""module""
? This tells Node.js to treat.js
files as ES Modules_ enabling theimport
syntax instead of CommonJSrequire()
. -
Install Dependencies: Install Express for the server_
@vonage/messages
for the Vonage SDK_ anddotenv
for environment variables.npm install express @vonage/messages dotenv
Your
package.json
dependencies
section should now look similar to this (versions may vary):// package.json (dependencies section) ""dependencies"": { ""@vonage/messages"": ""^1.10.0""_ // Or newer ""dotenv"": ""^16.4.5""_ // Or newer ""express"": ""^4.19.2"" // Or newer }
-
Create Project Structure: Create the necessary files and directories.
touch server.js .env .env.example .gitignore
server.js
: Our main application file containing the Express server and API logic..env
: Stores sensitive credentials (API keys_ etc.). Never commit this file to version control..env.example
: A template showing required environment variables (safe to commit)..gitignore
: Specifies intentionally untracked files that Git should ignore.
-
Configure
.gitignore
: Addnode_modules
and.env
to your.gitignore
file to prevent committing dependencies and secrets.# .gitignore node_modules/ .env *.log private.key # If storing the key file directly in the project
-
Set up Environment Variable Examples: Populate
.env.example
with the keys needed for the application.# .env.example # Vonage API Credentials (Get from Vonage Dashboard) VONAGE_API_KEY=YOUR_VONAGE_API_KEY VONAGE_API_SECRET=YOUR_VONAGE_API_SECRET # Vonage Application Credentials (Generate in Vonage Dashboard) VONAGE_APPLICATION_ID=YOUR_VONAGE_APPLICATION_ID # Private Key: Provide EITHER the path OR the key content # Option 1: Path to the private key file (ensure Node process can read it) VONAGE_PRIVATE_KEY_PATH=./private.key # Or absolute path # Option 2: Key content directly (often preferred in container/serverless environments) # Ensure newlines are correctly represented if pasting directly into an env var manager. # Example format (may vary based on how/where you set the variable): # VONAGE_PRIVATE_KEY=""-----BEGIN PRIVATE KEY-----\nYOUR_KEY_CONTENT_LINE_1\nYOUR_KEY_CONTENT_LINE_2\n-----END PRIVATE KEY-----"" # Vonage MMS Capable Number (Must be a US number) VONAGE_FROM_NUMBER=YOUR_VONAGE_US_NUMBER # Server Port PORT=3000
-
Create
.env
File: Duplicate.env.example
to.env
and fill in your actual credentials (we'll get these in the next step).cp .env.example .env
Now_ open
.env
and replace the placeholder values with your actual keys_ number_ and either the path to your private key or the key content itself.
2. Configuring Vonage
Before writing code_ we need to configure our Vonage account and application.
-
Sign Up/Log In: Ensure you have a Vonage API account. Log in to the Vonage API Dashboard.
-
Get API Key and Secret: Your API Key and Secret are displayed prominently at the top of the dashboard homepage. Copy these and add them to your
.env
file forVONAGE_API_KEY
andVONAGE_API_SECRET
.VONAGE_API_KEY
: Your public Vonage API key.VONAGE_API_SECRET
: Your private Vonage API secret. Keep this confidential.
-
Buy an MMS-Capable US Number:
- Navigate to ""Numbers"" -> ""Buy numbers"" in the left-hand menu.
- Select ""United States"" as the country.
- Ensure the ""MMS"" feature is selected. You might also want ""SMS"".
- Search for available numbers and purchase one.
- Copy the purchased number (including the country code, e.g.,
12015550123
) and add it to your.env
file forVONAGE_FROM_NUMBER
. - Why a US Number? Vonage currently supports sending MMS primarily from US numbers for Application-to-Person use cases.
-
Create a Vonage Application: Vonage Applications act as containers for your communication configurations, including authentication methods and webhook URLs.
- Navigate to ""Applications"" -> ""Create a new application"".
- Give your application a descriptive name (e.g., ""Node MMS Sender App"").
- Generate Public/Private Key Pair: Click the ""Generate public and private key"" link. This is crucial for authenticating with the Messages API SDK.
- A public key will be added to the form.
- A file named
private.key
will be automatically downloaded. Save this file securely. - You have two primary ways to provide this key to the SDK:
- File Path (Used in this guide's code): Place the
private.key
file in your project directory (or another secure location accessible by your Node.js process). Update theVONAGE_PRIVATE_KEY_PATH
in your.env
file to point to its location (e.g.,./private.key
if it's in the root). Ensure the Node process has read permissions for this file. - Key Content (Recommended for Containers/Serverless): Copy the entire content of the
private.key
file (including-----BEGIN PRIVATE KEY-----
and-----END PRIVATE KEY-----
) and paste it into theVONAGE_PRIVATE_KEY
variable in your.env
file. Make sure to handle line breaks correctly (often represented as\n
within the environment variable string). Our code invonageService.js
will prioritizeVONAGE_PRIVATE_KEY
if set.
- File Path (Used in this guide's code): Place the
- Why Key Pair? The Messages API uses JWT authentication based on your Application ID and this private key, which is more secure than just using the API Key/Secret for certain operations.
- Enable Capabilities: Find the ""Capabilities"" section and toggle on ""Messages"".
- Configure Webhooks (Status URL Required): Even if you aren't receiving MMS, the Messages API requires webhook URLs to send status updates about your sent messages (e.g., delivered, failed).
- Inbound URL: Where Vonage sends incoming messages to your number (not used in this sending-only guide, but required).
- Status URL: Where Vonage sends delivery receipts and status updates for outgoing messages.
- For development/testing without a live server, you can use a service like Mockbin. Create a bin, copy its endpoint URL (e.g.,
https://mockbin.org/bin/xxxxxxxx-xxxx...
), and paste it into both the ""Inbound URL"" and ""Status URL"" fields. SelectPOST
as the HTTP Method for both. - If using
ngrok
: Runngrok http 3000
(assuming your server runs on port 3000). Copy thehttps
Forwarding URL (e.g.,https://your-unique-id.ngrok-free.app
) and usehttps://your-unique-id.ngrok-free.app/webhooks/inbound
andhttps://your-unique-id.ngrok-free.app/webhooks/status
respectively. Remember to create these routes in your Express app later if you want to handle them. For now, Mockbin is sufficient. - Why Status URL? It's essential for production systems to track message delivery success or failure.
- Click ""Generate new application"".
-
Link Your Number: After creating the application, you'll be taken to its overview page.
- Scroll down to the ""Linked numbers"" section.
- Click ""Link"" next to the US MMS-capable number you purchased earlier.
-
Get Application ID: On the application overview page, find the ""Application ID"". Copy this UUID and add it to your
.env
file forVONAGE_APPLICATION_ID
.
Your .env
file should now be populated with your actual credentials.
3. Implementing Core MMS Sending Logic
Let's create a reusable function to handle sending the MMS message using the Vonage SDK.
-
Create a Service File (Optional but Recommended): For better organization, create a file to encapsulate Vonage interactions.
touch vonageService.js
-
Implement the Sending Function: Open
vonageService.js
and add the following code:// vonageService.js import { Messages } from '@vonage/messages'; import { MMSImage } from '@vonage/messages'; // Explicit import for clarity import 'dotenv/config'; // Load environment variables // Initialize Vonage Messages Client // Ensure environment variables are loaded before this runs const vonageCredentials = { apiKey: process.env.VONAGE_API_KEY, apiSecret: process.env.VONAGE_API_SECRET, applicationId: process.env.VONAGE_APPLICATION_ID, // Prefer key content (VONAGE_PRIVATE_KEY) if available, otherwise use path (VONAGE_PRIVATE_KEY_PATH) privateKey: process.env.VONAGE_PRIVATE_KEY || process.env.VONAGE_PRIVATE_KEY_PATH, }; // Basic check to ensure one of the private key methods is configured if (!vonageCredentials.privateKey) { console.error('FATAL ERROR: Neither VONAGE_PRIVATE_KEY nor VONAGE_PRIVATE_KEY_PATH environment variable is set. Vonage authentication will fail.'); // Optionally, throw an error to prevent the app from starting misconfigured: // throw new Error('Vonage private key is not configured in environment variables.'); } else if (process.env.VONAGE_PRIVATE_KEY && process.env.VONAGE_PRIVATE_KEY_PATH) { console.warn('Warning: Both VONAGE_PRIVATE_KEY and VONAGE_PRIVATE_KEY_PATH are set. Using VONAGE_PRIVATE_KEY (key content).'); } else if (process.env.VONAGE_PRIVATE_KEY_PATH) { // Optional: Add a check here if the file path exists, though the SDK might handle it later. console.log(`Using private key from path: ${process.env.VONAGE_PRIVATE_KEY_PATH}`); } else { console.log('Using private key content from VONAGE_PRIVATE_KEY environment variable.'); } const vonageMessages = new Messages(vonageCredentials); /** * Sends an MMS message using the Vonage Messages API. * @param {string} recipientNumber - The destination phone number (E.164 format recommended, e.g., +12125551234). * @param {string} imageUrl - The publicly accessible URL of the image to send. * @param {string} [caption=''] - Optional caption text for the image. * @returns {Promise<object>} - A promise that resolves with the Vonage API response on success. * @throws {Error} - Throws an error if the message sending fails. */ export async function sendMmsMessage(recipientNumber, imageUrl, caption = '') { console.log(`Attempting to send MMS to ${recipientNumber} from ${process.env.VONAGE_FROM_NUMBER}`); console.log(`Image URL: ${imageUrl}, Caption: ${caption}`); try { // Construct the MMS message payload const messageRequest = new MMSImage({ to: recipientNumber, from: process.env.VONAGE_FROM_NUMBER, image: { url: imageUrl, caption: caption, // Optional caption }, channel: 'mms', // Specify MMS channel message_type: 'image' // Specify message type }); // Send the message using the SDK const response = await vonageMessages.send(messageRequest); console.log('Vonage API Response:', response); // Example Success Response: { message_uuid: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' } return response; } catch (error) { console.error('Error sending MMS via Vonage:', error?.response?.data || error.message); // Example Error Structure (if available on error object): // error.response.data = { type: '...', title: '...', detail: '...', instance: '...' } throw new Error(`Failed to send MMS: ${error?.response?.data?.title || error.message}`); } }
- Initialization: We import
Messages
andMMSImage
and initialize the client using credentials loaded viadotenv/config
. TheprivateKey
now prioritizes theVONAGE_PRIVATE_KEY
environment variable (containing the key content) overVONAGE_PRIVATE_KEY_PATH
(containing the file path). A warning is added if neither is set. - Function Definition:
sendMmsMessage
takes the recipient number, image URL, and optional caption. - Payload: We create an
MMSImage
object, specifyingto
,from
, theimage
object (withurl
andcaption
),channel
('mms'), andmessage_type
('image'). - Sending:
vonageMessages.send()
sends the request. It's anasync
function, so weawait
the result. - Response/Error Handling: We log the success response (
message_uuid
) or catch and log detailed errors, re-throwing a user-friendly error.
- Initialization: We import
4. Building the Express API Layer
Now, let's set up the Express server and create the API endpoint.
-
Set up
server.js
: Openserver.js
and add the basic Express server setup.// server.js import express from 'express'; import 'dotenv/config'; // Load .env variables into process.env import { sendMmsMessage } from './vonageService.js'; // Import our sending function // --- Basic Server Setup --- const app = express(); const port = process.env.PORT || 3000; // Use port from .env or default to 3000 // --- Middleware --- // Enable Express to parse JSON request bodies app.use(express.json()); // Enable Express to parse URL-encoded request bodies (optional but common) app.use(express.urlencoded({ extended: true })); // --- API Routes --- // Simple health check route app.get('/', (req, res) => { res.status(200).json({ status: 'OK', message: 'MMS Sender API is running.' }); }); // POST endpoint to send MMS app.post('/send-mms', async (req, res) => { console.log('Received request on /send-mms:', req.body); // 1. Basic Request Validation const { to, imageUrl, caption } = req.body; if (!to || !imageUrl) { console.error('Validation Error: Missing ""to"" or ""imageUrl"" in request body.'); // Use 400 for Bad Request return res.status(400).json({ success: false, message: 'Missing required fields: ""to"" (recipient number) and ""imageUrl"".', }); } // Basic URL validation (can be enhanced) try { new URL(imageUrl); } catch (_) { console.error('Validation Error: Invalid ""imageUrl"".'); return res.status(400).json({ success: false, message: 'Invalid ""imageUrl"" provided. Must be a valid URL.', }); } // 2. Call the Vonage Service try { const result = await sendMmsMessage(to, imageUrl, caption); // Pass caption if provided console.log('MMS sent successfully via Vonage.'); // Use 200 for successful request processing res.status(200).json({ success: true, message: 'MMS sending initiated successfully.', data: result, // Include Vonage response (e.g., message_uuid) }); } catch (error) { console.error('API Error: Failed to send MMS.', error); // Use 500 for Internal Server Error if sending fails res.status(500).json({ success: false, message: error.message || 'An internal server error occurred while trying to send the MMS.', }); } }); // --- Webhook Routes (Optional - For Status Updates) --- // If using ngrok/live server, you can handle status updates here app.post('/webhooks/status', (req, res) => { console.log('Received Status Webhook:', JSON.stringify(req.body, null, 2)); // Process the status update (e.g., update database record) res.status(200).send('OK'); // Important: Respond with 200 OK }); app.post('/webhooks/inbound', (req, res) => { console.log('Received Inbound Webhook:', JSON.stringify(req.body, null, 2)); // Process inbound message (not the focus of this guide) res.status(200).send('OK'); // Important: Respond with 200 OK }); // --- Start Server --- app.listen(port, () => { console.log(`Server listening at http://localhost:${port}`); });
- Imports: We import
express
,dotenv/config
(to load variables early), and oursendMmsMessage
function. - Middleware:
express.json()
is essential to parse JSON payloads sent in the request body. /send-mms
Route:- It's an
async
function because it calls ourasync sendMmsMessage
. - Validation: It performs basic checks for the presence of
to
andimageUrl
. A simple URL validation is included. Robust validation is crucial in production. - Service Call: It calls
sendMmsMessage
within atry...catch
block. - Response: Sends a JSON response indicating success (200) or failure (400 for bad input, 500 for server/Vonage errors).
- It's an
- Webhook Routes: Basic handlers for
/webhooks/status
and/webhooks/inbound
are included. They simply log the received data and respond with200 OK
. Vonage requires a 200 OK response to know the webhook was received successfully. - Server Start:
app.listen
starts the server on the specified port.
- Imports: We import
-
Run the Server: Make sure your
.env
file is correctly populated with your credentials and eitherVONAGE_PRIVATE_KEY_PATH
orVONAGE_PRIVATE_KEY
.node server.js # Or if you added the dev script: npm run dev
You should see
Server listening at http://localhost:3000
. -
Test the Endpoint: Use a tool like
curl
or Postman to send a POST request to your running server.Using
curl
: Replace placeholders with your test recipient number (must be whitelisted if using a trial Vonage account - see Troubleshooting) and a valid, public image URL.curl -X POST http://localhost:3000/send-mms \ -H ""Content-Type: application/json"" \ -d '{ ""to"": ""+12125551234"", ""imageUrl"": ""https://placekitten.com/200/300"", ""caption"": ""Hello from Node.js!"" }'
Expected Success Response (200 OK):
{ ""success"": true, ""message"": ""MMS sending initiated successfully."", ""data"": { ""message_uuid"": ""xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"" } }
Expected Validation Error Response (400 Bad Request): (If
imageUrl
is missing){ ""success"": false, ""message"": ""Missing required fields: \""to\"" (recipient number) and \""imageUrl\""."" }
Expected Server Error Response (500 Internal Server Error): (If Vonage API call fails due to bad credentials, invalid number, etc.)
{ ""success"": false, ""message"": ""Failed to send MMS: Bad Credentials"" }
Check the console where server.js
is running for detailed logs, and check the recipient phone for the MMS message.
5. Error Handling and Logging
Our current setup includes basic console.log
and console.error
. For production, enhance this:
-
Structured Logging: Use a dedicated logging library like
winston
orpino
for structured, leveled logging (info, warn, error, debug) and outputting to files or log management services.# Example: Install Winston npm install winston
Configure the logger to capture timestamps, request IDs (if using middleware), and error stack traces.
// Example: Basic Winston Setup (add to server.js or a dedicated logger module) // import winston from 'winston'; // // const logger = winston.createLogger({ // level: 'info', // Log only info and above // format: winston.format.combine( // winston.format.timestamp(), // winston.format.json() // Log in JSON format // ), // defaultMeta: { service: 'mms-sender' }, // Optional: Add service name // transports: [ // // Write all logs with level `error` and below to `error.log` // new winston.transports.File({ filename: 'error.log', level: 'error' }), // // Write all logs with level `info` and below to `combined.log` // new winston.transports.File({ filename: 'combined.log' }), // ], // }); // // // If not in production then log to the `console` with a simpler format // if (process.env.NODE_ENV !== 'production') { // logger.add(new winston.transports.Console({ // format: winston.format.simple(), // })); // } // // // Usage example (replace console.log/error): // // logger.info('MMS request received', { to: recipientNumber }); // // logger.error('Failed to send MMS', { error: error.message, vonageDetails: error?.response?.data });
-
Vonage Error Details: The
catch
block invonageService.js
attempts to logerror?.response?.data
. This often contains valuable details from the Vonage API (liketitle
,detail
,type
). Ensure these are captured by your structured logger for effective debugging. Common errors include:Bad Credentials
Invalid number
(Formatting or capability issues)Non-Whitelisted Destination
(For trial accounts)Invalid Parameters
(Problem with image URL, caption length, etc.)Partner Quota Exceeded
(Rate limits)
-
API Response Consistency: Standardize error responses from your API. Include a consistent structure (e.g.,
{ success: false, code: 'ERROR_CODE', message: 'User-friendly message', details: 'Optional technical details' }
). -
Retry Mechanisms (Conceptual): For transient network issues or temporary Vonage problems (e.g., 5xx errors), implement a retry strategy with exponential backoff. Libraries like
async-retry
can simplify this. Wrap thevonageMessages.send()
call within the retry logic. Be cautious not to retry on errors indicating permanent failure (like invalid number or bad credentials).
6. Security Considerations
Protecting your credentials and application is vital.
-
Secure Credential Management:
.env
and.gitignore
: We've already configured this. Never commit.env
files or private key files.- Production Environment Variables: In deployment environments (like Heroku, AWS, Google Cloud), use the platform's secure mechanisms for managing environment variables. Do not store
.env
files directly on production servers if avoidable. If using theVONAGE_PRIVATE_KEY
variable, ensure it's stored securely. - Private Key Security: Treat your
private.key
file (if used) or the key content like any other sensitive credential. Ensure file permissions are restricted if using the path method.
-
Input Validation and Sanitization:
- The current validation is basic. Implement more robust validation using libraries like
joi
orexpress-validator
. - Validate phone number formats (e.g., E.164). A simple regex check might be
/^\+[1-9]\d{1,14}$/
, though dedicated libraries likelibphonenumber-js
offer more robust parsing and validation for international numbers. - Validate the
imageUrl
more strictly (e.g., check content-type if possible, restrict domains, check for size). - Sanitize the
caption
input to prevent potential Cross-Site Scripting (XSS) issues if this caption is ever displayed elsewhere in a web context, although less critical for direct MMS sending.
- The current validation is basic. Implement more robust validation using libraries like
-
Rate Limiting: Protect your API from abuse and control costs by implementing rate limiting. Use middleware like
express-rate-limit
.# Example: Install express-rate-limit npm install express-rate-limit
// Example: Basic rate limiting in server.js // import rateLimit from 'express-rate-limit'; // // const limiter = rateLimit({ // windowMs: 15 * 60 * 1000, // 15 minutes // max: 100, // Limit each IP to 100 requests per `windowMs` // standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers // legacyHeaders: false, // Disable the `X-RateLimit-*` headers // }); // // // Apply the rate limiting middleware to API calls // app.use('/send-mms', limiter);
Apply it to your
/send-mms
endpoint to limit requests per IP address over a time window. Adjust limits based on expected usage. -
HTTPS: Always run your API over HTTPS in production using TLS/SSL certificates (often handled by load balancers or hosting platforms like Heroku).
7. Testing and Verification
-
Manual Verification:
- Send test MMS messages using
curl
or Postman as shown previously. - Check the recipient phone to confirm message delivery, image rendering, and caption correctness.
- Check the logs in your Vonage Dashboard (""Logs"" -> ""Messages API"") for status details (
submitted
,delivered
,failed
, etc.). - Check your server logs (
console
output or structured logging service) for request details and errors. - If you configured status webhooks, check the logs for Mockbin or your ngrok inspector (
http://127.0.0.1:4040
) for delivery receipt events.
- Send test MMS messages using
-
Automated Testing (Conceptual):
- Unit Tests: Use frameworks like
jest
ormocha
to test individual functions, especiallysendMmsMessage
. You would mock the@vonage/messages
SDK to simulate successful responses and errors without making actual API calls. - Integration Tests: Test the Express route (
/send-mms
) by making requests to your running server (perhaps in a test environment) and mocking the Vonage SDK interaction. Verify response codes and bodies. - End-to-End Tests (Complex): Could involve sending a real MMS to a test number and programmatically verifying receipt, but this is often complex and costly. Relying on Vonage status webhooks is generally more practical.
- Unit Tests: Use frameworks like
8. Deployment (Conceptual)
Deploying this application involves running the Node.js server in a production environment.
- Choose a Platform: Options include Heroku, AWS (EC2, Lambda, Elastic Beanstalk), Google Cloud (App Engine, Cloud Run), DigitalOcean, etc.
- Environment Variables: Configure all required environment variables (
VONAGE_API_KEY
,VONAGE_API_SECRET
,VONAGE_APPLICATION_ID
,VONAGE_FROM_NUMBER
,PORT
,NODE_ENV=production
, and eitherVONAGE_PRIVATE_KEY_PATH
orVONAGE_PRIVATE_KEY
) using the platform's secure configuration management. Ensure theprivate.key
file is accessible at the specified path (if usingVONAGE_PRIVATE_KEY_PATH
) or its content is correctly provided viaVONAGE_PRIVATE_KEY
. - Build Step (If Applicable): If using TypeScript or a build process, ensure the compiled JavaScript is deployed. For this plain JS example, no build step is needed.
- Start Command: Configure the platform to run your application using
npm start
ornode server.js
. - CI/CD: Set up a Continuous Integration/Continuous Deployment pipeline (e.g., GitHub Actions, GitLab CI, Jenkins) to automate testing and deployment on code changes.
- Webhook URLs: Update the Status and Inbound URLs in your Vonage Application settings to point to your live production server's endpoints (e.g.,
https://your-app-domain.com/webhooks/status
).