This guide provides a complete walkthrough for building a Node.js Express application capable of sending SMS messages using the Vonage Messages API. We'll cover everything from project setup and configuration to implementing the core sending logic, handling errors, and deploying the application.
By the end of this tutorial, you will have a functional API endpoint that accepts a phone number and a message, sending an SMS via Vonage. This serves as a foundational building block for features like notifications, alerts, or two-factor authentication.
Project Overview and Goals
- Goal: Create a secure and reliable backend service to send SMS messages programmatically.
- Problem Solved: Enables applications to communicate with users via SMS for various purposes without needing manual intervention.
- Technologies:
- Node.js: A JavaScript runtime for building server-side applications.
- Express: A minimal and flexible Node.js web application framework for creating the API endpoint.
- Vonage Messages API: A versatile API for sending messages across various channels, including SMS. We use this for its robustness and multi-channel capabilities.
@vonage/server-sdk
: The official Vonage Node.js library for interacting with Vonage APIs.dotenv
: A module to load environment variables from a.env
file, keeping sensitive credentials out of the codebase.
- Architecture:
+-------------+ +---------------------+ +----------------+ +-----------------+ | HTTP Client | ----> | Node.js/Express API | ----> | Vonage SDK/API | ----> | SMS Recipient | | (e.g., curl)| | (/api/send-sms) | | (Messages API) | | (Mobile Phone) | +-------------+ +---------------------+ +----------------+ +-----------------+ | - Validate Request | | - Load Credentials | | - Call Vonage SDK | | - Return Response | +---------------------+
- Outcome: A simple Express application with a single POST endpoint (
/api/send-sms
) that uses Vonage to send an SMS message. - Prerequisites:
- Node.js and npm (or yarn) installed. Download Node.js
- A Vonage API account. Sign up for Vonage
- A Vonage virtual phone number capable of sending SMS.
- Basic understanding of Node.js, Express, and REST APIs.
- (Optional but recommended) Vonage CLI installed (
npm install -g @vonage/cli
). (Useful for tasks like managing Vonage numbers, applications, or checking account balance via the command line.) - (Optional)
ngrok
for testing webhooks if you extend functionality later. Download ngrok
1. Setting up the Project
Let's initialize our Node.js project and install the necessary dependencies.
-
Create Project Directory: Open your terminal and create a new directory for your project, then navigate into it.
mkdir vonage-sms-sender cd vonage-sms-sender
-
Initialize Node.js Project: This command creates a
package.json
file to manage your project's dependencies and scripts.npm init -y
-
Install Dependencies: We need Express for the web server, the Vonage SDK to communicate with the API, and
dotenv
to manage environment variables securely.npm install express @vonage/server-sdk dotenv --save
express
: Web framework.@vonage/server-sdk
: Vonage API client library.dotenv
: Loads environment variables from.env
.
-
Create Project Structure: Create the main application file and a file for environment variables.
touch index.js .env .gitignore
Your basic structure should look like this:
vonage-sms-sender/ node_modules/ .env .gitignore index.js package.json package-lock.json
-
Configure
.gitignore
: It's crucial to prevent sensitive information and unnecessary files from being committed to version control. Add the following lines to your.gitignore
file:# Dependencies node_modules/ # Environment variables .env # Logs logs/ *.log npm-debug.log* yarn-debug.log* yarn-error.log* # OS generated files .DS_Store Thumbs.db
- Why
.env
? This file will contain your secret API keys, private key content, and other configuration details. It must never be committed to Git.
- Why
2. Integrating with Vonage and Core Functionality
Now, let's configure Vonage and write the code to initialize the SDK and send an SMS.
-
Vonage Account Setup:
- If you haven't already, sign up for a Vonage API account.
- Navigate to your Vonage API Dashboard.
-
Create a Vonage Application: The Messages API typically uses Application ID and Private Key authentication for enhanced security.
- Go to ""Your applications"" in the Vonage Dashboard.
- Click ""+ Create a new application"".
- Give it a name (e.g., ""Node SMS Sender App"").
- Click ""Generate public and private key"". Important: This will automatically download a
private.key
file. Save this file securely, as you will need its content. - Note the Application ID displayed on the page -> you'll need this.
- Enable the Messages capability. You'll see fields for ""Inbound URL"" and ""Status URL"". For sending only, these aren't strictly required, but Vonage might prompt you to fill them. You can enter placeholder URLs like
https://example.com/webhooks/inbound
andhttps://example.com/webhooks/status
. If you plan to receive messages or delivery receipts later, you'll need valid, publicly accessible URLs (potentially usingngrok
for local testing). - Click ""Generate new application"".
-
Link Your Vonage Number:
- Scroll down on the application details page to ""Link virtual numbers"".
- Find the Vonage virtual number you want to send SMS from and click ""Link"".
- Note: Ensure this number is SMS-capable in your region.
-
Set Messages API as Default (Crucial Check): Sometimes, accounts can be configured to use the older SMS API by default, which uses different authentication and webhook formats. Ensure the Messages API is the default for sending SMS.
- Go to your Vonage API Dashboard Settings.
- Under ""API keys"" -> ""Default SMS Setting"", ensure Messages API is selected. If not, change it and click ""Save changes"".
-
Configure Environment Variables: Open the
.env
file you created earlier. Copy the entire content of theprivate.key
file you downloaded (including the-----BEGIN PRIVATE KEY-----
and-----END PRIVATE KEY-----
lines) and paste it as the value forVONAGE_PRIVATE_KEY_CONTENT
. Add the other required variables:# Vonage Credentials (Messages API - Recommended) VONAGE_APPLICATION_ID=""YOUR_APPLICATION_ID"" # Paste the entire content of your private.key file below, ensuring newlines are preserved if needed by your OS/editor. # Example: VONAGE_PRIVATE_KEY_CONTENT=""-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"" # On some systems/shells, you might need to handle multi-line variables carefully or encode it. VONAGE_PRIVATE_KEY_CONTENT=""PASTE_YOUR_PRIVATE_KEY_CONTENT_HERE"" # Your Vonage virtual number (linked to the application) VONAGE_NUMBER=""YOUR_VONAGE_VIRTUAL_NUMBER"" # API Key & Secret (Optional for this tutorial's method) # VONAGE_API_KEY=""YOUR_API_KEY"" # VONAGE_API_SECRET=""YOUR_API_SECRET"" # Server Configuration PORT=3000
VONAGE_APPLICATION_ID
: The ID generated when you created the Vonage application.VONAGE_PRIVATE_KEY_CONTENT
: The full text content of theprivate.key
file. Ensure line breaks are handled correctly if pasting into certain environments.VONAGE_NUMBER
: The Vonage virtual phone number (in E.164 format, e.g.,14155550100
) linked to your application. This will be the ""from"" number.VONAGE_API_KEY
/VONAGE_API_SECRET
: Found at the top of your main Vonage Dashboard page. For the specific task of sending SMS via the Messages API using Application ID and Private Key authentication (as shown in this tutorial), the API Key and Secret are not strictly required and can be omitted from your.env
file. However, they might be needed if you use other Vonage APIs or SDK features that rely on key/secret authentication.PORT
: The port your Express server will listen on.
-
Initialize Vonage SDK and Sending Logic: Open
index.js
and add the following code to load environment variables, initialize the Vonage SDK, and create a function to send SMS.// index.js require('dotenv').config(); // Load environment variables from .env file const express = require('express'); const { Vonage } = require('@vonage/server-sdk'); // ---- Vonage Setup ---- // Ensure the private key content is loaded correctly, handling potential newline issues from .env const privateKeyContent = process.env.VONAGE_PRIVATE_KEY_CONTENT.replace(/\\n/g, '\n'); const vonage = new Vonage({ applicationId: process.env.VONAGE_APPLICATION_ID, privateKey: privateKeyContent // Use the key content directly from the environment variable }, { debug: false }); // Set debug: true for detailed SDK logging const vonageNumber = process.env.VONAGE_NUMBER; // ---- SMS Sending Function ---- async function sendSms(toNumber, messageText) { console.log(`Attempting to send SMS from ${vonageNumber} to ${toNumber}`); try { const resp = await vonage.messages.send({ message_type: ""text"", to: toNumber, // E.164 format recipient number (e.g., 14155550101) from: vonageNumber, // Your Vonage number linked to the application channel: ""sms"", text: messageText }); console.log(`SMS submitted successfully with Message UUID: ${resp.messageUuid}`); return { success: true, messageUuid: resp.messageUuid }; } catch (err) { console.error(""Error sending SMS:"", err); // Log the detailed error response if available if (err.response && err.response.data) { console.error(""Vonage Error Details:"", JSON.stringify(err.response.data, null, 2)); } // Rethrow or return a structured error throw new Error(`Failed to send SMS: ${err.message || 'Unknown error'}`); } } // ---- Express App Setup ---- (Continued in next section) // ... Express code will go here ...
require('dotenv').config()
: Loads the variables from.env
intoprocess.env
. Call this early.privateKeyContent
processing: Added.replace(/\\n/g, '\n')
to handle potential literal\n
characters if the private key was pasted into.env
as a single line with escaped newlines. Adjust if your method of storing the multi-line key in.env
differs.new Vonage(...)
: Initializes the SDK using the Application ID and the content of the private key read directly from the environment variable.vonage.messages.send(...)
: The core method for sending messages via the Messages API.message_type: ""text""
: Specifies a plain text SMS.to
: Recipient number (must be in E.164 format).from
: Your Vonage number.channel: ""sms""
: Explicitly routes via SMS.text
: The message content.
- Async/Await: Uses modern JavaScript promises for cleaner asynchronous code.
- Error Handling: Includes a
try...catch
block to handle potential errors during the API call and logs relevant information.
3. Building the API Layer
Let's create the Express server and the API endpoint to trigger the SMS sending function.
-
Set up Express Server: Add the following code to
index.js
below the Vonage setup andsendSms
function.// index.js (continued) // ---- Express App Setup ---- const app = express(); const port = process.env.PORT || 3000; // Use port from .env or default to 3000 // Middleware app.use(express.json()); // Parse JSON request bodies app.use(express.urlencoded({ extended: true })); // Parse URL-encoded request bodies // ---- API Endpoint ---- app.post('/api/send-sms', async (req, res) => { const { to, message } = req.body; // Extract recipient number and message from request body // Basic Input Validation if (!to || !message) { console.warn('Validation Error: Missing "to" or "message" in request body'); return res.status(400).json({ success: false, error: 'Missing required fields: "to" (E.164 phone number) and "message".' }); } // Basic E.164 format check (adjust regex as needed for stricter validation) const phoneRegex = /^\+[1-9]\d{1,14}$/; if (!phoneRegex.test(to)) { console.warn(`Validation Error: Invalid phone number format for ${to}`); return res.status(400).json({ success: false, error: 'Invalid "to" phone number format. Use E.164 format (e.g., +14155550101).' }); } try { const result = await sendSms(to, message); console.log(`API call successful for sending SMS to ${to}`); res.status(200).json({ success: true, messageId: result.messageUuid }); } catch (error) { console.error(`API Error: Failed to process send SMS request for ${to}:`, error.message); // Send a generic server error message to the client res.status(500).json({ success: false, error: 'Failed to send SMS due to an internal server error.' }); } }); // ---- Simple Root Route ---- app.get('/', (req, res) => { res.send('Vonage SMS Sender API is running!'); }); // ---- Start Server ---- app.listen(port, () => { console.log(`Server listening on port ${port}`); console.log(`Vonage Application ID: ${process.env.VONAGE_APPLICATION_ID ? 'Loaded' : 'MISSING!'}`); console.log(`Vonage Private Key: ${process.env.VONAGE_PRIVATE_KEY_CONTENT ? 'Loaded' : 'MISSING!'}`); // Check if key content is loaded console.log(`Vonage Number: ${process.env.VONAGE_NUMBER ? process.env.VONAGE_NUMBER : 'MISSING!'}`); });
- Middleware:
express.json()
andexpress.urlencoded()
parse incoming request bodies. - POST
/api/send-sms
: Defines the endpoint. It expects a JSON body withto
andmessage
fields. - Input Validation: Includes basic checks for the presence and format (simple E.164 regex) of the
to
number and the presence of themessage
. Returns a400 Bad Request
if validation fails. - Error Handling: Wraps the
sendSms
call in atry...catch
block. IfsendSms
throws an error (e.g., Vonage API issues), it logs the error server-side and returns a generic500 Internal Server Error
to the client, preventing potential leakage of sensitive error details. - Success Response: On success, returns a
200 OK
with the VonagemessageUuid
. - Server Start: Starts the Express server and logs confirmation, including checks for essential environment variables.
- Middleware:
4. Error Handling and Logging
We've implemented basic error handling, but let's refine it.
-
Consistent Strategy:
- Use
try...catch
blocks for operations that can fail (API calls, potentially complex logic). - Log errors server-side with details (
console.error
). Include context (e.g., recipient number, action being performed). - Return appropriate HTTP status codes (400 for client errors, 500 for server errors).
- Return user-friendly, non-sensitive error messages in API responses.
- Use
-
Logging:
- Current: Uses
console.log
for informational messages andconsole.error
for errors. - Production Enhancement: Use a dedicated logging library (like
winston
orpino
) for structured logging (JSON format), different log levels (debug, info, warn, error), and routing logs to files or external services (like Datadog, Splunk).
# Example: Install Winston npm install winston
// Example: Basic Winston setup (replace console logging) const winston = require('winston'); const logger = winston.createLogger({ level: 'info', // Log info and above format: winston.format.json(), transports: [ new winston.transports.Console({ format: winston.format.simple() }), // Add file transport for production // new winston.transports.File({ filename: 'error.log', level: 'error' }), // new winston.transports.File({ filename: 'combined.log' }), ], }); // Replace console.log with logger.info, console.warn with logger.warn, console.error with logger.error // Example: logger.error('Error sending SMS:', err);
- Current: Uses
-
Retry Mechanisms:
- For transient network issues or temporary Vonage unavailability, implement retries with exponential backoff. Libraries like
async-retry
can simplify this. - Caution: Be careful not to retry errors caused by invalid input (e.g., bad phone number) or insufficient funds, as retrying won't help and may incur costs. Only retry potentially temporary issues (e.g., network timeouts, 5xx errors from Vonage).
# Example: Install async-retry npm install async-retry
// Example: Wrap sendSms call with retry (in the API endpoint) const retry = require('async-retry'); app.post('/api/send-sms', async (req, res) => { // ... validation ... const { to, message } = req.body; // Ensure to and message are defined here try { const result = await retry(async bail => { // If Vonage returns certain errors (like 4xx), don't retry // Example: if (error.response && error.response.status >= 400 && error.response.status < 500) { // bail(new Error('Non-retryable Vonage error')); // bail stops retrying // return; // } return await sendSms(to_ message); // Attempt to send }_ { retries: 3_ // Number of retries factor: 2_ // Exponential backoff factor minTimeout: 1000_ // Initial timeout onRetry: (error_ attempt) => { // Replace console.warn with logger.warn if using Winston/Pino console.warn(`Retrying SMS send to ${to} (attempt ${attempt}) due to error: ${error.message}`); } }); // Replace console.log with logger.info if using Winston/Pino console.log(`API call successful for sending SMS to ${to}`); res.status(200).json({ success: true, messageId: result.messageUuid }); } catch (error) { // Replace console.error with logger.error if using Winston/Pino console.error(`API Error: Failed to process send SMS request for ${to} after retries:`, error.message); res.status(500).json({ success: false, error: 'Failed to send SMS due to an internal server error.' }); } });
- For transient network issues or temporary Vonage unavailability, implement retries with exponential backoff. Libraries like
5. Database Schema and Data Layer
For this basic SMS sending service, a database is not strictly required. However, if you wanted to log sent messages, track delivery status (requiring webhooks), or manage user data, you would add a database.
- If needed:
- Choose a database (e.g., PostgreSQL, MongoDB).
- Design a schema (e.g., a
messages
table withmessage_uuid
,to_number
,from_number
,body
,status
,submitted_at
,updated_at
). - Use an ORM (like Prisma, Sequelize, Mongoose) or a query builder (like Knex.js) to interact with the database.
- Implement migrations to manage schema changes.
6. Security Features
Security is paramount, especially when dealing with APIs and external services.
- Input Validation and Sanitization:
- We implemented basic validation for
to
andmessage
. - Use robust validation libraries (like
joi
orexpress-validator
) for complex validation rules. - Sanitize input if it's ever stored or reflected back, to prevent XSS (though less relevant for an SMS API body unless storing/displaying).
- We implemented basic validation for
- Protecting Credentials:
- Use
.env
for all secrets (API keys, private key content, database URLs). - Ensure
.env
is in.gitignore
. - Use environment variables directly in deployment environments (do not commit
.env
files). See Deployment section.
- Use
- Common Vulnerabilities:
- Rate Limiting: Protect against abuse and brute-force attempts. Use middleware like
express-rate-limit
.npm install express-rate-limit
// index.js (add near the top middleware) const rateLimit = require('express-rate-limit'); const limiter = 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' }); // Apply limiter specifically to the sensitive endpoint app.use('/api/send-sms', limiter);
- Authentication/Authorization: Currently, the endpoint is open. In a real application, protect it with API keys, JWT tokens, or session authentication to ensure only authorized clients can send SMS.
- HTTPS: Always use HTTPS in production to encrypt data in transit. Deployment platforms often handle this, but ensure it's enforced.
- Dependency Updates: Regularly update dependencies (
npm audit
,npm update
) to patch known vulnerabilities.
- Rate Limiting: Protect against abuse and brute-force attempts. Use middleware like
7. Handling Special Cases
- Phone Number Formats: Strictly enforce E.164 format (
+
followed by country code and number, no spaces or dashes) as required by Vonage. The validation regex can be improved for stricter checks based on country codes if needed. - Character Limits & Encoding: Standard SMS messages have character limits (160 for GSM-7, 70 for UCS-2/Unicode). Longer messages are split into multiple segments (concatenated SMS). Vonage handles segmentation, but be aware of potential costs for multi-part messages. Ensure message content doesn't contain characters incompatible with SMS if strict GSM-7 is needed, otherwise, Vonage will likely use UCS-2.
- Internationalization: The E.164 format handles international numbers. Ensure your Vonage account/number is enabled for sending to the target countries. Be mindful of international messaging costs and regulations (e.g., sender ID restrictions).
- Rate Limits (Vonage): Vonage applies its own rate limits (Messages Per Second). High-volume sending might require coordination with Vonage support or using specific high-throughput numbers. The SDK might return specific rate-limiting errors (often HTTP 429).
8. Performance Optimizations
For a simple service like this, performance bottlenecks are unlikely unless sending extremely high volumes.
- Async Operations: Node.js is inherently non-blocking. Using
async/await
correctly ensures the server remains responsive while waiting for Vonage. - Connection Pooling (if using DB): Ensure your database client/ORM uses connection pooling.
- Caching: Not typically applicable for sending unique SMS messages. If retrieving reusable data (e.g., user preferences before sending), caching might apply.
- Load Testing: Use tools like
k6
,Artillery
, orApacheBench
(ab
) to simulate traffic and identify bottlenecks if high performance is critical. - Profiling: Use Node.js built-in profiler or tools like Clinic.js to analyze CPU usage and event loop delays under load.
9. Monitoring, Observability, and Analytics
Gaining insight into the service's health and behaviour is crucial.
- Health Checks: Add a simple endpoint (e.g.,
/health
) that returns a 200 OK status if the server is running. Monitoring services can ping this.// index.js (add before app.listen) app.get('/health', (req, res) => { res.status(200).send('OK'); });
- Metrics: Track key metrics:
- Request rate (requests per second/minute).
- Request duration (latency).
- Error rates (HTTP 4xx, 5xx).
- Vonage API call latency/errors.
- Node.js process metrics (CPU, memory, event loop lag).
- Use tools like Prometheus with
prom-client
or integrate with APM services (Datadog, New Relic).
- Error Tracking: Use services like Sentry or Bugsnag to capture, aggregate, and alert on application errors in real-time. They provide much more context than simple logging.
- Logging: As mentioned in Section 4, structured logging is essential for effective analysis and dashboarding in tools like Elasticsearch/Kibana (ELK stack), Datadog Logs, or Splunk.
- Vonage Dashboard: Utilize the Vonage Dashboard's analytics section to monitor SMS sending volumes, delivery rates (requires status webhooks), and costs.
10. Troubleshooting and Caveats
- Common Errors:
401 Unauthorized
: Incorrect Application ID or private key content. Ensure theVONAGE_PRIVATE_KEY_CONTENT
environment variable contains the exact, complete key content (including start/end markers and newlines handled correctly). Double-check the private key hasn't expired or been revoked. Ensure the Messages API is the default SMS setting in the Vonage Dashboard.Invalid 'to' number
/Non-Whitelisted Destination
: The recipient number format is incorrect (use E.164) or, if using a trial account, the recipient number must be added to the Vonage test numbers list (Dashboard -> Getting started -> Add test numbers).Invalid 'from' number
/Illegal Sender Address
: TheVONAGE_NUMBER
in your.env
is incorrect, not SMS-capable, or not linked to theVONAGE_APPLICATION_ID
used for initialization.Delivery Failure - Generic
/ Specific Carrier Error: May indicate issues with the recipient's carrier or number. Check Vonage logs for more details.Throughput capacity exceeded
/429 Too Many Requests
: Sending too many messages too quickly. Implement rate limiting on your side or contact Vonage for higher limits.- Private Key Format Error: If the SDK throws errors related to parsing the private key, ensure the
VONAGE_PRIVATE_KEY_CONTENT
variable contains the PEM format correctly, including the-----BEGIN PRIVATE KEY-----
and-----END PRIVATE KEY-----
lines and the base64 encoded content between them, with newlines preserved as needed. Check for extra characters or incorrect encoding. - TypeScript Compatibility: If adapting this guide for TypeScript, ensure you have the necessary
@types
packages installed (e.g.,@types/node
,@types/express
) and yourtsconfig.json
is configured correctly. SDK or dependency updates might introduce type compatibility issues.
- Limitations:
- Trial Accounts: Limited funds and requirement to whitelist recipient numbers.
- Sender ID: May be overridden by carriers, especially internationally. Alphanumeric Sender IDs might require pre-registration.
- Delivery Receipts: Not implemented in this basic guide. Requires setting up a status webhook URL in the Vonage Application config and an endpoint in Express to receive POST requests from Vonage.
- Regional Regulations: Compliance with local laws (e.g., TCPA in the US, GDPR in Europe) regarding consent and opt-outs is the developer's responsibility.
11. Deployment and CI/CD
Deploying the application requires handling environment variables, especially the private key content, securely.
- Environment Configuration:
- DO NOT commit the
.env
file to Git. - Use the hosting platform's mechanism for setting environment variables (e.g., Heroku Config Vars, Vercel Environment Variables, AWS Systems Manager Parameter Store / Secrets Manager).
- Handling the Private Key: Store the entire content of the
private.key
file in a secure environment variable (e.g.,VONAGE_PRIVATE_KEY_CONTENT
) on your deployment platform. Ensure your platform handles multi-line environment variables correctly, or encode the key content if necessary (e.g., base64) and decode it in your application before passing it to the SDK (though direct pasting is often supported). Theindex.js
code already expects the key content directly fromprocess.env.VONAGE_PRIVATE_KEY_CONTENT
.
- DO NOT commit the
- Deployment Platforms:
- PaaS (Heroku, Vercel, Render): Generally easier. Connect Git repository, configure environment variables (including the multi-line
VONAGE_PRIVATE_KEY_CONTENT
) via dashboard/CLI, deploy. - IaaS (AWS EC2, Google Compute Engine): Requires setting up the server environment (Node.js runtime, process manager like
pm2
), managing deployments (e.g., via SSH, Docker, CI/CD pipelines), securely setting environment variables, and configuring reverse proxies (like Nginx).
- PaaS (Heroku, Vercel, Render): Generally easier. Connect Git repository, configure environment variables (including the multi-line
- Process Manager: Use a process manager like
pm2
to keep the Node.js application running, manage logs, and handle restarts.npm install pm2 -g # Install globally or as dev dependency # Start app with pm2 pm2 start index.js --name vonage-sms-api
- CI/CD Pipeline (e.g., GitHub Actions, GitLab CI, Jenkins):
- Automate testing, building (if needed), and deployment.
- Store secrets (like
VONAGE_APPLICATION_ID
,VONAGE_NUMBER
, andVONAGE_PRIVATE_KEY_CONTENT
) securely within the CI/CD platform's secrets management system and inject them as environment variables during the deployment step. - Example steps: Checkout code -> Install dependencies -> Run tests -> Build (if applicable) -> Deploy to target environment (using platform CLI or other deployment tools).
- Rollback: Have a plan to revert to a previous stable version if a deployment introduces issues (e.g., redeploying the previous Git tag/commit, using platform rollback features).
12. Verification and Testing
Ensure the service works as expected.
-
Run Locally:
- Make sure your
.env
file is correctly populated with your Application ID, your Vonage number, and the full content of your private key. - Start the server:
node index.js
- You should see ""Server listening on port 3000"" and confirmation that environment variables are loaded.
- Make sure your
-
Test with cURL or Postman:
- Open a new terminal window (or use Postman).
- Send a POST request to your endpoint. Replace
+14155550101
with a valid test number (whitelisted if on a trial account).
cURL Example:
curl -X POST http://localhost:3000/api/send-sms \ -H ""Content-Type: application/json"" \ -d '{ ""to"": ""+14155550101"", ""message"": ""Hello from Node.js and Vonage! This is a test message."" }'
Expected Success Response (JSON):
{ ""success"": true, ""messageId"": ""aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"" }
Expected Failure Response (e.g., missing field):
{ ""success"": false, ""error"": ""Missing required fields: \""to\"" (E.164 phone number) and \""message\""."" }
-
Check Phone: Verify that the SMS message is received on the target phone number.
-
Check Server Logs: Look at the terminal where
node index.js
is running. You should see logs indicating the attempt, success (with UUID), or any errors encountered. -
Check Vonage Dashboard: Log in to the Vonage Dashboard and check the logs/analytics section for records of the sent message and its status.