This guide provides a step-by-step walkthrough for building a Node.js application using the Express framework to send SMS messages via the Vonage Messages API. We'll cover everything from project setup to deployment considerations, ensuring you have a robust foundation for integrating SMS capabilities into your applications.
By the end of this tutorial, you will have a simple Express API endpoint that accepts a recipient phone number and a message, then uses the Vonage Node.js SDK to send an SMS message. This solves the common need to programmatically send notifications, alerts, or messages to users via SMS.
Project Overview and Goals
- Goal: Create a secure and reliable Node.js service that exposes an API endpoint to send SMS messages using Vonage.
- Technologies:
- Node.js: A JavaScript runtime for building server-side applications.
- Express: A minimal and flexible Node.js web application framework used to create the API endpoint.
- Vonage Messages API: A powerful API for sending and receiving messages across various channels (SMS, MMS, WhatsApp, etc.). We will use it specifically for SMS.
- Vonage Node.js SDK (
@vonage/server-sdk
): Simplifies interaction with the Vonage APIs. dotenv
: A module to load environment variables from a.env
file intoprocess.env
.
- Outcome: A functional Express application with a
/send-sms
endpoint capable of sending SMS messages when provided with a recipient number and text. - Prerequisites:
- Node.js and npm (or yarn) installed. Download Node.js
- A Vonage API account. Sign up for free.
- A Vonage virtual phone number capable of sending SMS. You can acquire one through the Vonage Dashboard.
- Basic understanding of Node.js, Express, and REST APIs.
- A tool for making HTTP requests (like
curl
, Postman, or Insomnia).
System Architecture
The basic flow is as follows:
- A client (e.g., your frontend application, another service, or a testing tool like Postman) sends a POST request to your Express API endpoint (
/send-sms
) with the recipient's phone number and the message text. - The Express application receives the request, validates the input, and retrieves Vonage credentials (Application ID, Private Key, Vonage Number) from environment variables.
- The application uses the Vonage Node.js SDK to make an authenticated request to the Vonage Messages API, instructing it to send the SMS.
- The Vonage platform handles the delivery of the SMS message to the recipient's phone.
- Vonage sends a response back to your Express application (indicating success or failure of the API call), which then relays an appropriate response back to the original client.
sequenceDiagram
participant Client
participant ExpressApp as Node.js/Express API
participant VonageSDK as @vonage/server-sdk
participant VonageAPI as Vonage Messages API
participant Recipient
Client->>+ExpressApp: POST /send-sms (to, text)
ExpressApp->>+VonageSDK: Initialize (App ID, Private Key)
ExpressApp->>+VonageSDK: send({ channel: 'sms', message_type: 'text', to, from, text })
VonageSDK->>+VonageAPI: Send SMS Request
VonageAPI-->>-Recipient: Deliver SMS
VonageAPI-->>-VonageSDK: API Response (e.g., message_uuid)
VonageSDK-->>-ExpressApp: Return Promise (resolve/reject)
ExpressApp-->>-Client: API Response (Success/Error)
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 npm: Create a
package.json
file to manage your project's dependencies and scripts.npm init -y
-
Install Dependencies: Install Express, the Vonage Server SDK, and
dotenv
.npm install express @vonage/server-sdk dotenv
express
: The web framework.@vonage/server-sdk
: The official Vonage SDK for Node.js.dotenv
: To manage environment variables securely.
-
Create Project Structure: Create the main application file and files for managing sensitive credentials.
touch index.js .env .gitignore
index.js
: This will contain our Express application code..env
: This file will store our Vonage API credentials and other configuration variables. Never commit this file to version control..gitignore
: Specifies intentionally untracked files that Git should ignore.
-
Configure
.gitignore
: Addnode_modules
and.env
to your.gitignore
file to prevent committing dependencies and sensitive credentials.# Dependencies node_modules/ # Environment variables .env # Vonage private key file (if stored in project) private.key
-
Optional: Add Start Script & Configure for ES Modules: Modify your
package.json
to include a convenient start script and specify that the project uses ES Modules (required forimport
syntax inindex.js
).// package.json (partial) { ""name"": ""vonage-sms-sender"", ""version"": ""1.0.0"", ""description"": ""Sends SMS using Node.js, Express, and Vonage"", ""main"": ""index.js"", ""type"": ""module"", ""scripts"": { ""start"": ""node index.js"", ""test"": ""echo \""Error: no test specified\"" && exit 1"" }, ""keywords"": [ ""vonage"", ""sms"", ""express"", ""node"" ], ""license"": ""ISC"", ""dependencies"": { ""@vonage/server-sdk"": ""^3.12.1"", ""dotenv"": ""^16.4.5"", ""express"": ""^4.19.2"" } }
You can now start your server using
npm start
.
2. Integrating with Vonage
To use the Vonage Messages API, you need to create a Vonage Application and securely configure your credentials.
-
Create a Vonage Application:
- Log in to your Vonage API Dashboard.
- Navigate to ""Applications"" > ""Create a new application"".
- Give your application a name (e.g., ""Node SMS Sender"").
- Click ""Generate public and private key"". This will automatically download a
private.key
file. Save this file securely. For this guide, we'll assume you save it in the root of your project directory (vonage-sms-sender/private.key
). Remember to addprivate.key
to your.gitignore
file. - Enable the ""Messages"" capability. You'll see fields for ""Inbound URL"" and ""Status URL"". For sending SMS, these aren't strictly required immediately, but Vonage requires them to be filled. 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 functional endpoints here (likely usingngrok
for local development). - Click ""Generate new application"".
- On the next screen, you'll see your Application ID. Keep this page open or copy the ID.
-
Link Your Vonage Number:
- While still viewing your newly created application details, go to the ""Linked numbers"" section.
- Find the Vonage virtual number you want to send SMS from and click ""Link"". If you don't have one, go to ""Numbers"" > ""Buy numbers"" to purchase one first.
-
Configure Environment Variables: Open the
.env
file you created earlier and add your Vonage credentials and number.# Vonage Credentials VONAGE_APPLICATION_ID=YOUR_APPLICATION_ID_HERE VONAGE_PRIVATE_KEY_PATH=./private.key VONAGE_VIRTUAL_NUMBER=YOUR_VONAGE_VIRTUAL_NUMBER_HERE # Server Configuration PORT=3000
- Replace
YOUR_APPLICATION_ID_HERE
with the Application ID from the Vonage dashboard. - Ensure
VONAGE_PRIVATE_KEY_PATH
points to the correct location of your downloadedprivate.key
file relative toindex.js
. - Replace
YOUR_VONAGE_VIRTUAL_NUMBER_HERE
with the Vonage phone number you linked to the application (use E.164 format, e.g.,14155550100
). PORT=3000
: Sets the port your Express server will listen on.
Security Note: The
.env
file and theprivate.key
file contain sensitive credentials. Ensure they are never committed to your Git repository. Use environment variable management tools provided by your hosting platform for production deployments. Note: For local development, providing the file path is convenient. For production deployments (see Section 12), you'll typically provide the content of the key via an environment variable. - Replace
3. Implementing Core Functionality (Sending SMS)
Now, let's write the Express code to initialize the Vonage SDK and create the API endpoint.
// index.js
import express from 'express';
import { Vonage } from '@vonage/server-sdk';
import dotenv from 'dotenv';
// Load environment variables from .env file
dotenv.config();
// --- Configuration ---
const PORT = process.env.PORT || 3000; // Use port from .env or default to 3000
const VONAGE_APPLICATION_ID = process.env.VONAGE_APPLICATION_ID;
const VONAGE_PRIVATE_KEY_PATH = process.env.VONAGE_PRIVATE_KEY_PATH;
const VONAGE_VIRTUAL_NUMBER = process.env.VONAGE_VIRTUAL_NUMBER;
// Basic validation for required environment variables
if (!VONAGE_APPLICATION_ID || !VONAGE_PRIVATE_KEY_PATH || !VONAGE_VIRTUAL_NUMBER) {
console.error(`
-------------------------------------------------
ERROR: Missing required Vonage environment variables.
Please check your .env file and ensure the following are set:
- VONAGE_APPLICATION_ID
- VONAGE_PRIVATE_KEY_PATH
- VONAGE_VIRTUAL_NUMBER
-------------------------------------------------
`);
process.exit(1); // Exit if configuration is missing
}
// --- Initialize Vonage SDK ---
// The SDK uses the Application ID and Private Key for authentication with the Messages API
// For production, you might load the key content directly, e.g., from process.env.VONAGE_PRIVATE_KEY_CONTENT
const vonage = new Vonage({
applicationId: VONAGE_APPLICATION_ID,
privateKey: VONAGE_PRIVATE_KEY_PATH,
});
// --- Initialize Express App ---
const app = express();
// Middleware to parse JSON request bodies
app.use(express.json());
// --- API Endpoint to Send SMS ---
app.post('/send-sms', async (req, res) => {
console.log(`Received request to /send-sms:`, req.body);
// 1. Input Validation (Basic)
const { to, text } = req.body;
if (!to || !text) {
console.error('Validation Error: Missing ""to"" or ""text"" in request body');
return res.status(400).json({
success: false,
message: 'Missing required fields: ""to"" (recipient phone number) and ""text"" (message content).',
});
}
// Basic E.164-like format check (allows '+' and digits, 7-15 digits long)
if (!/^\+?\d{7,15}$/.test(to)) {
console.error(`Validation Error: Invalid format for ""to"" number: ${to}`);
return res.status(400).json({
success: false,
message: 'Invalid format for ""to"" number. Use E.164 format (e.g., +14155550100) with 7-15 digits.',
});
}
// 2. Prepare Vonage API Request
const messageRequest = {
channel: 'sms',
message_type: 'text',
to: to, // Recipient phone number from request body
from: VONAGE_VIRTUAL_NUMBER, // Your Vonage virtual number from .env
text: text, // Message content from request body
};
// 3. Send SMS using Vonage SDK
try {
console.log('Attempting to send SMS via Vonage:', messageRequest);
// Use vonage.messages.send() which returns a promise
const response = await vonage.messages.send(messageRequest);
console.log('Vonage API Success Response:', response);
// Successful API call (doesn't guarantee delivery yet)
res.status(200).json({
success: true,
message: 'SMS send request accepted by Vonage.',
message_uuid: response.message_uuid, // Include the unique message ID from Vonage
});
} catch (error) {
// Handle errors from the Vonage SDK / API
console.error('Vonage API Error:', error.response ? error.response.data : error.message);
// Provide more specific feedback if possible
let errorMessage = 'Failed to send SMS due to a server or Vonage API error.';
let statusCode = 500;
if (error.response && error.response.data) {
// Try to extract Vonage specific error details
const { type, title, detail, invalid_parameters } = error.response.data;
errorMessage = `Vonage API Error: ${title || 'Unknown Error'} - ${detail || error.message}`;
if (invalid_parameters) {
errorMessage += ` Invalid parameters: ${JSON.stringify(invalid_parameters)}`;
statusCode = 400; // Often indicates bad input
} else if (type && type.includes('authentication')) {
statusCode = 401; // Authentication issues
} else {
statusCode = error.response.status || 500;
}
} else if (error.message.includes('authenticate')) {
errorMessage = 'Authentication failed. Check Vonage Application ID and Private Key path.';
statusCode = 401;
}
res.status(statusCode).json({
success: false,
message: errorMessage,
errorDetails: error.response ? error.response.data : { code: error.code, message: error.message },
});
}
});
// --- Simple 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(`Server running on port ${PORT}`);
console.log(`Vonage App ID: ${VONAGE_APPLICATION_ID}`);
console.log(`Vonage Number: ${VONAGE_VIRTUAL_NUMBER}`);
console.log(`Private Key Path: ${VONAGE_PRIVATE_KEY_PATH}`);
console.log(`\nSend POST requests to http://localhost:${PORT}/send-sms`);
console.log(`Health check available at http://localhost:${PORT}/health`);
console.log(`\n--- ${new Date().toISOString()} ---`);
});
Code Explanation:
- Imports: We import
express
, theVonage
class from the SDK, anddotenv
. - Configuration: We load environment variables using
dotenv.config()
and store them in constants. Added basic validation to ensure critical Vonage variables are set. - Vonage SDK Initialization: We create an instance of the
Vonage
client, passing theapplicationId
and theprivateKey
path. This configuration is specific to APIs like Messages that use JWT authentication based on the application keys. A comment notes how this might change for production key handling. - Express Initialization: We create an Express app instance and use
express.json()
middleware to automatically parse incoming JSON request bodies. /send-sms
Endpoint (POST):- Defined as an
async
function to useawait
for the asynchronousvonage.messages.send
call. - Input Validation: It checks if
to
andtext
properties exist in thereq.body
. A basic E.164-like format check for theto
number is included using a regular expression. Returns a400 Bad Request
if validation fails. - Prepare Request: It constructs the payload object required by
vonage.messages.send
for an SMS message, using the validated input and the Vonage number from.env
. - Send SMS: It calls
vonage.messages.send(messageRequest)
within atry...catch
block. - Success Handling: If the promise resolves, it means Vonage accepted the request. We log the response (which contains the
message_uuid
) and send a200 OK
response back to the client. - Error Handling: If the promise rejects (an error occurs), the
catch
block executes. We log the detailed error (checking forerror.response.data
which often contains specific Vonage error details). We attempt to provide a more informative error message and status code (e.g., 400 for invalid parameters, 401 for auth issues, 500 for generic errors) back to the client.
- Defined as an
/health
Endpoint (GET): A simple endpoint to verify the server is running.- Start Server:
app.listen
starts the Express server on the configuredPORT
.
4. Building a Complete API Layer (Refinements)
The current /send-sms
endpoint is functional but can be improved:
-
Authentication/Authorization: For a production API, you would need to protect this endpoint. Common methods include:
- API Keys: Require clients to send a secret API key in a header (e.g.,
X-API-Key
). Your middleware would validate this key. - JWT (JSON Web Tokens): Implement user authentication and require a valid JWT for accessing the endpoint.
- IP Whitelisting: Restrict access to specific IP addresses if applicable.
- Implementing full auth is beyond this basic guide, but crucial for production.
- API Keys: Require clients to send a secret API key in a header (e.g.,
-
Request Validation: The current validation is basic. Use a dedicated validation library like
Joi
orexpress-validator
for more robust checks (e.g., checking phone number formats more strictly, enforcing message length limits).// Example using basic checks (expand with a library for production) if (text.length > 1600) { // SMS character limits vary, check Vonage docs return res.status(400).json({ /* ... error message ... */ }); } // Add more specific E.164 validation if needed
-
API Documentation: Use tools like Swagger/OpenAPI to document your endpoint, including request/response formats and authentication requirements.
5. Error Handling, Logging, and Retry Mechanisms
- Consistent Error Strategy: We've implemented basic
try...catch
and return structured JSON errors. Standardize error responses across your API. - Logging: The current
console.log
andconsole.error
are suitable for development. For production, use a dedicated logging library (likeWinston
orPino
) to:- Log to files or external logging services (e.g., Datadog, Loggly).
- Control log levels (info, warn, error, debug).
- Include timestamps and request context in logs.
- Retry Mechanisms: Network issues or temporary Vonage problems might cause requests to fail.
- Client-Side Retries: The client calling your
/send-sms
endpoint could implement retries with exponential backoff. - Server-Side Retries (Caution): Implementing retries within your
/send-sms
endpoint for Vonage calls can be risky – you might accidentally send duplicate messages if the initial request succeeded but the response failed. It's generally safer to rely on Vonage's internal retries and potentially implement an idempotent design (e.g., using a unique request ID provided by the client) if you need server-side retries. Vonage itself has retry mechanisms for message delivery.
- Client-Side Retries: The client calling your
6. Database Schema and Data Layer (Not Applicable Here)
For this specific task of only sending an SMS via an API call, a database is not required. If you were building features like tracking message history, managing user preferences, or queuing messages, you would need a database (e.g., PostgreSQL, MongoDB) with appropriate schemas and data access patterns (like using an ORM like Prisma or Sequelize).
7. Security Features
-
Input Validation: Already mentioned – crucial to prevent malformed requests and potential minor vulnerabilities (though less critical for basic SMS text). Sanitize input if incorporating it into dynamic responses or logs elsewhere.
-
API Key Security: Protect your Vonage credentials (
.env
,private.key
) rigorously. Use environment variables in deployment, not hardcoded values. -
Rate Limiting: Protect your API (and your Vonage account balance) from abuse or accidental loops by implementing rate limiting. Libraries like
express-rate-limit
make this easy.npm install express-rate-limit
// index.js (add near the top) import rateLimit from 'express-rate-limit'; // ... (after app initialization) 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', 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 // Apply specifically to /send-sms or globally if needed app.use('/send-sms', limiter); // ... (rest of your code)
-
HTTPS: Always use HTTPS for your API in production to encrypt data in transit. Use a reverse proxy like Nginx or Caddy, or hosting platform features (like Heroku, Vercel) to handle SSL termination.
-
Helmet: Use the
helmet
middleware for Express to set various security-related HTTP headers.npm install helmet
// index.js import helmet from 'helmet'; // ... app.use(helmet()); // ...
8. Handling Special Cases (SMS Specific)
- Character Encoding & Limits: SMS messages have character limits (typically 160 for standard GSM-7, fewer for UCS-2 used for non-Latin characters). Longer messages are split into multiple segments, billed separately. The Messages API handles segmentation automatically, but be mindful of costs. Vonage docs specify supported encodings.
- International Numbers: Use the E.164 format (e.g.,
+447700900000
,+14155550100
) for international numbers. Ensure your Vonage account/number is enabled for sending to the desired countries. - Sender ID: The
from
number is typically your Vonage virtual number. In some countries, you can use an Alphanumeric Sender ID (e.g., ""MyBrand""), but this requires pre-registration and support varies by country. Check Vonage documentation. - Restricted Content: Carriers may filter messages containing certain keywords (especially related to spam or prohibited content).
9. Performance Optimizations (Less Critical Here)
For a simple endpoint like this, complex optimizations are usually unnecessary.
- Async Operations: Node.js is inherently non-blocking. Using
async/await
ensures your server isn't blocked while waiting for the Vonage API response. - Load Testing: For high-throughput scenarios, use tools like
k6
,Artillery
, orApacheBench
to test how many requests per second your endpoint can handle. Monitor CPU/Memory usage. - Caching: Not directly applicable for sending unique SMS messages.
10. Monitoring, Observability, and Analytics
- Health Checks: The
/health
endpoint is a basic health check. Monitoring services (like UptimeRobot, Pingdom, or AWS CloudWatch) can ping this endpoint to ensure your service is running. - Logging: Centralized logging (as mentioned before) is key for observability.
- Error Tracking: Use services like Sentry or Bugsnag to automatically capture and report errors that occur in your application.
- Vonage Dashboard: Monitor SMS delivery status, usage, and costs directly in the Vonage API Dashboard under ""Logs"" > ""Messages API logs"".
- Metrics: Track metrics like request latency, error rates (4xx, 5xx), and the number of SMS sent. Tools like Prometheus/Grafana or Datadog APM can help.
11. Troubleshooting and Caveats
- Trial Account Limitations: Most common issue. New Vonage accounts are often in a trial/demo mode. You must add recipient phone numbers to a whitelist in the Vonage Dashboard (usually under your Account Settings or a dedicated ""Test Numbers"" section) before you can send SMS to them. If you get errors like ""Non-Whitelisted Destination,"" this is the cause. Upgrade your account by adding payment details to remove this restriction.
- Incorrect Credentials: Double-check
VONAGE_APPLICATION_ID
,VONAGE_PRIVATE_KEY_PATH
(ensure the file exists and is readable at that path), andVONAGE_VIRTUAL_NUMBER
in your.env
file. Ensure theprivate.key
file content is exactly what was downloaded. - Invalid
from
Number: Ensure theVONAGE_VIRTUAL_NUMBER
is correctly formatted (E.164) and is linked to theVONAGE_APPLICATION_ID
in the Vonage dashboard. - Invalid
to
Number: Ensure the recipient number is valid and in a supported format (E.164 recommended). Check the slightly stricter validation inindex.js
. - Firewall Issues: Ensure your server can make outbound HTTPS requests to Vonage API endpoints (typically
*.vonage.com
or*.nexmo.com
on port 443). - SDK/API Errors: Check the
errorDetails
in the JSON response from your API for specific error messages from Vonage (e.g., ""Invalid Credentials,"" ""Parameter missing,"" ""Throughput capacity exceeded""). Consult the Vonage API Error Codes documentation. - Private Key Permissions: Ensure the Node.js process has read permissions for the
private.key
file if using the file path method. - Port Conflicts: If you get an
EADDRINUSE
error, another application is already using the specifiedPORT
. Stop the other application or change thePORT
in your.env
file. - ES Module vs CommonJS: Ensure
""type"": ""module""
is present in yourpackage.json
if usingimport
syntax as shown inindex.js
. If you need to use CommonJS (require
), remove""type"": ""module""
and convertimport
statements torequire
.
12. Deployment and CI/CD
- Environment Configuration: Do not deploy your
.env
file orprivate.key
directly. Use your hosting provider's mechanism for setting environment variables securely (e.g., Heroku Config Vars, AWS Parameter Store/Secrets Manager, Docker secrets). - Private Key Handling in Production: The current code reads the key from a file path (
VONAGE_PRIVATE_KEY_PATH
). For production, you will typically provide the content of the private key via a secure environment variable (e.g.,VONAGE_PRIVATE_KEY_CONTENT
). You will need to adapt theVonage
SDK initialization inindex.js
to read this content instead of the file path:// Example adaptation for reading key content from env var const vonage = new Vonage({ applicationId: process.env.VONAGE_APPLICATION_ID, privateKey: process.env.VONAGE_PRIVATE_KEY_CONTENT // Read key content directly });
- Platform Choice: Deploy to platforms like Heroku, Vercel, AWS (EC2, Lambda, Fargate, Beanstalk), Google Cloud (App Engine, Cloud Run), Azure App Service, or use Docker containers.
- CI/CD Pipeline: Set up a pipeline (e.g., GitHub Actions, GitLab CI, Jenkins) to automate:
- Running linters/formatters (
eslint
,prettier
). - Running tests (Unit, Integration).
- Building the application (if necessary, e.g., for TypeScript).
- Deploying to staging/production environments, injecting the correct environment variables.
- Running linters/formatters (
- Process Management: Use a process manager like
pm2
in production to keep your Node.js application running, handle restarts on crashes, and manage logs.
13. Verification and Testing
-
Start the Server:
npm start
You should see output indicating the server is running on the configured port (default 3000).
-
Manual Verification (using
curl
): Open another terminal window. Run the followingcurl
command, replacing the placeholder value:curl -X POST \ http://localhost:3000/send-sms \ -H 'Content-Type: application/json' \ -d '{ ""to"": ""YOUR_PERSONAL_PHONE_NUMBER"", ""text"": ""Hello from Node.js and Vonage! Sent at: '""$(date)""'"" }'
Before running, make sure to replace:
YOUR_PERSONAL_PHONE_NUMBER
with your actual mobile number (use E.164 format like14155550123
). Ensure this number is whitelisted in your Vonage dashboard if using a trial account.- Verify
http://localhost:3000
matches your server's host and port if you changed the defaultPORT
in.env
.
-
Check Expected Output:
- Terminal (curl): You should receive a JSON response like:
Or an error response if something went wrong:
{ ""success"": true, ""message"": ""SMS send request accepted by Vonage."", ""message_uuid"": ""xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"" }
{ ""success"": false, ""message"": ""Vonage API Error: Authentication Failed - Invalid Credentials..."", ""errorDetails"": { /* ... Vonage error object ... */ } }
- Terminal (Server Logs): Check the logs where
npm start
is running. You should see the incoming request, the attempt to send, and the success or error details logged. - Your Phone: You should receive the SMS message on the
to
number shortly after a successful API response. - Vonage Dashboard: Check the Messages API logs in the Vonage dashboard to see the record of the sent message and its status.
- Terminal (curl): You should receive a JSON response like:
-
Test Edge Cases:
- Send without
to
ortext
field -> Expect 400 Bad Request. - Send with an invalid
to
number format (e.g.,123
,abc
) -> Expect 400 Bad Request. - Temporarily invalidate credentials in
.env
-> Expect 401/500 error. - Send a very long message.
- Send without
-
Automated Testing (Conceptual):
- Unit Tests: Use frameworks like Jest or Mocha/Chai to test individual functions/modules in isolation. You would mock the Vonage SDK (
@vonage/server-sdk
) to avoid making actual API calls during unit tests. Test input validation logic. - Integration Tests: Use tools like
supertest
to make actual HTTP requests to your running application (potentially mocking the Vonage SDK call at the boundary) to test the endpoint logic, request/response flow, and middleware.
- Unit Tests: Use frameworks like Jest or Mocha/Chai to test individual functions/modules in isolation. You would mock the Vonage SDK (