Sending SMS with Node.js, Express, and Vonage
This guide provides a step-by-step walkthrough for building a simple but robust Node.js application using the Express framework to send SMS messages via the Vonage SMS API. We'll cover everything from project setup and configuration to sending messages and handling common issues.
By the end of this tutorial, you will have a functional Express API endpoint capable of accepting a phone number and message text, and using Vonage to deliver that message as an SMS.
Project Overview and Goals
Goal: Create a backend service that exposes an API endpoint to send SMS messages reliably using Vonage.
Problem Solved: This provides a foundational component for applications needing programmatic SMS capabilities, such as sending notifications, verification codes, or alerts.
Technologies Used:
- Node.js: A JavaScript runtime environment ideal for building scalable network applications.
- Express: A minimal and flexible Node.js web application framework, perfect for creating APIs.
- Vonage SMS API: A powerful API for sending and receiving SMS messages globally. We'll use the
@vonage/server-sdk
for Node.js. - dotenv: A module to load environment variables from a
.env
file intoprocess.env
, keeping sensitive credentials out of source code.
System Architecture:
A client sends a POST request with recipient (to
) and message (text
) to the Express API /send-sms
endpoint. The Express app validates the input and uses the Vonage Node SDK (initialized with API credentials) to make an API call to the Vonage Cloud SMS API. Vonage then attempts to deliver the SMS to the recipient's phone. The Express app returns a success or error JSON response to the client based on the outcome of the Vonage API call.
Prerequisites:
- Node.js and npm (or yarn): Installed on your development machine. (Download Node.js)
- Vonage API Account: A free trial account is sufficient to start. You'll need your API Key and API Secret. (Sign up for Vonage)
- Vonage Phone Number: A virtual number rented from Vonage or the ability to register and verify test numbers (required for trial accounts).
- Basic understanding of JavaScript and Node.js concepts.
- A tool for making API requests: Such as
curl
, Postman, or Insomnia.
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: Use npm to create a
package.json
file. The-y
flag accepts the default settings.npm init -y
-
Install Dependencies: We need Express for the web server, the Vonage SDK to interact with the API, and
dotenv
for managing environment variables.npm install express @vonage/server-sdk dotenv --save
express
: The web framework.@vonage/server-sdk
: The official Vonage Node.js library.dotenv
: To load environment variables from a.env
file.
-
Enable ES Modules: For using modern
import
/export
syntax, open yourpackage.json
file and add the following line at the top level:// package.json { ""name"": ""vonage-sms-sender"", ""version"": ""1.0.0"", ""description"": """", ""main"": ""index.js"", ""type"": ""module"", ""scripts"": { ""start"": ""node index.js"", ""test"": ""echo \""Error: no test specified\"" && exit 1"" }, ""keywords"": [], ""author"": """", ""license"": ""ISC"", ""dependencies"": { ""@vonage/server-sdk"": ""^3.11.0"", ""dotenv"": ""^16.3.1"", ""express"": ""^4.18.2"" } }
""type"": ""module""
enables ES Module syntax.- The
""start""
script provides a standard way to run the application.
-
Create
.gitignore
: Prevent sensitive files and unnecessary directories from being committed to version control. Create a file named.gitignore
in the project root:# .gitignore # Dependencies node_modules/ # Environment variables .env # Logs logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* lerna-debug.log* # OS generated files .DS_Store Thumbs.db
-
Create Environment File (
.env
): This file will store your Vonage credentials and sender number. Never commit this file to Git. Create a file named.env
in the project root:# .env - Store your Vonage Credentials Here # DO NOT COMMIT THIS FILE # Vonage API Credentials (Get from Vonage Dashboard -> API Settings) VONAGE_API_KEY=YOUR_API_KEY VONAGE_API_SECRET=YOUR_API_SECRET # Vonage Virtual Number or Sender ID (Must be owned or registered) VONAGE_SENDER_NUMBER=YOUR_VONAGE_NUMBER_OR_ID # Server Port PORT=3000
- Replace placeholders with your actual credentials later.
-
Project Structure: Our basic structure will look like this:
vonage-sms-sender/ ├── node_modules/ ├── .env ├── .gitignore ├── index.js # Main application file (Express server, API endpoint) ├── vonageClient.js # Initializes the Vonage SDK client ├── smsService.js # Contains the function to send SMS ├── package.json └── package-lock.json
2. Implementing Core Functionality (Vonage Integration)
We'll create separate modules for initializing the Vonage client and for the SMS sending logic. This promotes better organization and testability.
-
Initialize Vonage Client (
vonageClient.js
): Create a file namedvonageClient.js
. This module initializes the Vonage SDK using credentials from environment variables.// vonageClient.js import { Vonage } from '@vonage/server-sdk'; import 'dotenv/config'; // Load .env variables into process.env // Ensure required environment variables are set if (!process.env.VONAGE_API_KEY || !process.env.VONAGE_API_SECRET) { console.error('Error: VONAGE_API_KEY and VONAGE_API_SECRET must be set in .env file.'); process.exit(1); // Exit if credentials are missing } const vonage = new Vonage({ apiKey: process.env.VONAGE_API_KEY, apiSecret: process.env.VONAGE_API_SECRET }); console.log('Vonage client initialized successfully.'); export default vonage; // Export the initialized client instance
- We import
Vonage
from the SDK anddotenv/config
to load the.env
file immediately. - We add a check to ensure the API key and secret are present, exiting if not.
- We instantiate
Vonage
with the credentials. - We export the
vonage
instance for use in other modules.
- We import
-
Create SMS Sending Service (
smsService.js
): Create a file namedsmsService.js
. This module defines the function responsible for actually sending the SMS using the initialized Vonage client.// smsService.js import vonage from './vonageClient.js'; // Import the initialized client import 'dotenv/config'; // Ensure sender number is set if (!process.env.VONAGE_SENDER_NUMBER) { console.error('Error: VONAGE_SENDER_NUMBER must be set in .env file.'); process.exit(1); } const from = process.env.VONAGE_SENDER_NUMBER; /** * Sends an SMS message using the Vonage API. * @param {string} recipient - The recipient's phone number (E.164 format recommended, e.g., +15551234567). * @param {string} messageText - The text content of the SMS message. * @returns {Promise<object>} - A promise that resolves with the Vonage API response data on success. * @throws {Error} - Throws an error if the SMS sending fails. */ export async function sendSms(recipient, messageText) { console.log(`Attempting to send SMS from ${from} to ${recipient}`); try { // Note: We use vonage.sms.send (part of the older SMS API binding within the SDK) // as it directly maps to the simple Key/Secret authentication used here. // The vonage.messages.send method often requires Application ID/Private Key auth. const responseData = await vonage.sms.send({ to: recipient, from: from, text: messageText }); // Check the status of the first (and usually only) message response if (responseData.messages[0]['status'] === '0') { console.log(`Message sent successfully to ${recipient}. Message ID: ${responseData.messages[0]['message-id']}`); return responseData; // Resolve with the full response } else { const errorCode = responseData.messages[0]['status']; const errorText = responseData.messages[0]['error-text']; console.error(`Message failed with error code ${errorCode}: ${errorText}`); // Throw a specific error for easier catching throw new Error(`Vonage API Error ${errorCode}: ${errorText}`); } } catch (err) { // Handle SDK-level errors (e.g., network issues, invalid credentials before API call) console.error('Error sending SMS:', err); // Re-throw the error to be handled by the caller (API route) throw err; } }
- We import the initialized
vonage
client. - We retrieve the
VONAGE_SENDER_NUMBER
from.env
. - The
sendSms
function takes the recipient number (to
) andmessageText
as arguments. - It calls
vonage.sms.send()
, which is suitable for API Key/Secret authentication for basic SMS. - It checks the
status
field in the Vonage response. Status'0'
means success. - If successful, it logs the success and returns the response.
- If unsuccessful, it logs the error details provided by Vonage and throws a new
Error
containing the Vonage error message. - A
try...catch
block handles potential errors during the SDK call itself (like network errors).
- We import the initialized
3. Building the API Layer
Now, let's create the Express server and the API endpoint that will use our smsService
.
-
Create Express Server (
index.js
): Create the main application file,index.js
.// index.js import express from 'express'; import 'dotenv/config'; import { sendSms } from './smsService.js'; // Import our SMS sending function const app = express(); const port = process.env.PORT || 3000; // Use port from .env or default to 3000 // Middleware to parse JSON request bodies app.use(express.json()); // Middleware to parse URL-encoded request bodies app.use(express.urlencoded({ extended: true })); // Simple Root Route for Health Check / Basic Info app.get('/', (req, res) => { res.status(200).send('Vonage SMS Sender API is running!'); }); // --- API Endpoint to Send SMS --- app.post('/send-sms', async (req, res) => { // 1. Input Validation const { to, text } = req.body; if (!to || !text) { console.log('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 check for phone number format (can be enhanced) // E.164 format (e.g., +15551234567) is generally recommended for Vonage if (!/^\+?[1-9]\d{1,14}$/.test(to)) { console.log(`Validation Error: Invalid phone number format for ""to"": ${to}`); return res.status(400).json({ success: false, message: 'Invalid phone number format. Please use E.164 format (e.g., +15551234567).', }); } try { // 2. Call the SMS Service console.log(`Received request to send SMS to: ${to}`); const result = await sendSms(to, text); // 3. Send Success Response // Optionally, filter the result to return only essential info like message ID const messageId = result.messages[0]['message-id']; res.status(200).json({ success: true, message: 'SMS sent successfully.', messageId: messageId, // You might include remaining balance if needed, from result.messages[0]['remaining-balance'] }); } catch (error) { // 4. Send Error Response console.error(`Failed to send SMS via API endpoint: ${error.message}`); // Check for specific Vonage errors if needed, e.g., non-whitelisted number // The error message from smsService already contains Vonage details let statusCode = 500; // Default to Internal Server Error if (error.message.includes(""Non-Whitelisted Destination"")) { statusCode = 403; // Forbidden - specific issue } else if (error.message.includes(""Invalid Credentials"")) { statusCode = 401; // Unauthorized } // Add more specific error code mappings as needed res.status(statusCode).json({ success: false, message: `Failed to send SMS: ${error.message}`, }); } }); // --- Start the Server --- app.listen(port, () => { console.log(`Server listening on http://localhost:${port}`); console.log(`SMS Send Endpoint: POST http://localhost:${port}/send-sms`); });
- We import
express
and oursendSms
function. - We set up the Express app and configure middleware (
express.json
,express.urlencoded
) to handle incoming request bodies. - A basic
/
route is added for simple health checks. - The
POST /send-sms
route is defined asasync
to useawait
. - Input Validation: It first checks if
to
andtext
are present in the request body (req.body
). If not, it returns a400 Bad Request
error. A basic phone number format check is also included. - Service Call: It calls
await sendSms(to, text)
inside atry...catch
block. - Success Response: If
sendSms
resolves successfully, it sends a200 OK
JSON response indicating success and includes themessageId
from the Vonage result. - Error Handling: If
sendSms
throws an error (either from the SDK or our explicit checks), thecatch
block executes. It logs the error and sends an appropriate error status code (e.g., 400, 403, 500) with a JSON response detailing the failure. We map specific error messages to HTTP status codes. - Finally,
app.listen
starts the server on the configured port.
- We import
4. Integrating with Vonage (Configuration)
This section details how to get the necessary credentials and configure your Vonage account.
-
Sign Up/Log In: Go to the Vonage API Dashboard and sign up or log in.
-
Find API Key and Secret:
- Navigate to your Dashboard homepage.
- Your API key and API secret are displayed prominently near the top under the ""API keys"" section.
- Dashboard Path:
Vonage Dashboard
->API Settings
(usually visible on the main dashboard page). - Action: Copy these values.
-
Update
.env
File: Paste your copied API Key and Secret into your.env
file:# .env VONAGE_API_KEY=YOUR_ACTUAL_API_KEY_HERE VONAGE_API_SECRET=YOUR_ACTUAL_API_SECRET_HERE # ... other variables
-
Get a Vonage Sender Number/ID:
- Paid Accounts: You can purchase virtual numbers. Navigate to
Numbers
->Buy numbers
. Search for and buy a number with SMS capability. Copy the full number (including country code, e.g.,12015550123
). - Trial Accounts (IMPORTANT): Trial accounts often cannot send SMS messages to any number initially. You must:
- Register Test Numbers: Navigate to
Numbers
->Test numbers
. Add the phone number(s) you intend to send test SMS messages to. You will need to verify ownership via an SMS or voice call code sent by Vonage. - Use Your Vonage Number (if provided): Sometimes trial accounts come with a pre-assigned number. Check under
Numbers
->Your numbers
. - Use an Alphanumeric Sender ID (Limited): In some countries, you can use a custom string (like your brand name, e.g., ""MyApp"") as the sender ID instead of a number. This usually requires registration and may have limitations (e.g., recipients cannot reply). Check Vonage documentation for supported countries and regulations. For simplicity, using a purchased or test-verified number is recommended initially.
- Register Test Numbers: Navigate to
- Dashboard Path:
Vonage Dashboard
->Numbers
-> (Buy numbers
|Your numbers
|Test numbers
). - Action: Obtain your Vonage virtual number or approved Sender ID.
- Paid Accounts: You can purchase virtual numbers. Navigate to
-
Update
.env
File: Add your Vonage sender number/ID to your.env
file:# .env VONAGE_API_KEY=YOUR_ACTUAL_API_KEY_HERE VONAGE_API_SECRET=YOUR_ACTUAL_API_SECRET_HERE VONAGE_SENDER_NUMBER=YOUR_VONAGE_NUMBER_OR_ID_HERE # e.g., 12015550123 or MyAppName PORT=3000
Environment Variables Summary:
VONAGE_API_KEY
: Your unique key for authenticating API requests. Found on the Vonage dashboard.VONAGE_API_SECRET
: Your secret key for authentication. Found on the Vonage dashboard. Treat this like a password.VONAGE_SENDER_NUMBER
: The phone number (in E.164 format like15551234567
) or registered Alphanumeric Sender ID that will appear as the sender of the SMS. Must be associated with your Vonage account.PORT
: The port your Express application will listen on (e.g.,3000
).
5. Error Handling and Logging
Our current implementation includes basic error handling and logging:
- Initialization Checks:
vonageClient.js
andsmsService.js
check for essential environment variables on startup and exit if they are missing. - API Input Validation: The
/send-sms
endpoint validates the presence and basic format ofto
andtext
fields, returning400 Bad Request
if invalid. - Vonage API Error Handling:
smsService.js
checks thestatus
code from the Vonage API response. If it's not'0'
, it throws an error including the Vonage error code and message. - Catch Block in API: The
try...catch
block in the/send-sms
endpoint catches errors thrown bysmsService.js
(including Vonage API errors) or other unexpected issues. It logs the error and returns a structured JSON error response with an appropriate HTTP status code (e.g., 500, 403, 401). - Logging: We use
console.log
for informational messages (server start, request received, SMS sent attempt, success) andconsole.error
for errors (missing env vars, validation failures, SMS send failures, API errors).
Further Enhancements (Beyond Basic):
- Structured Logging: Implement a dedicated logging library (like
winston
orpino
) for structured logging (e.g., JSON format), different log levels (debug, info, warn, error), and routing logs to files or external services. - Centralized Error Handling Middleware: Create Express middleware to handle errors consistently across all routes, reducing code duplication in individual route handlers.
- Retry Mechanisms: For transient network errors or specific Vonage rate limit responses, implement a retry strategy (e.g., exponential backoff) using libraries like
async-retry
. This is more relevant for critical notifications.
6. Database Schema and Data Layer
Not Applicable for this Basic Guide.
This specific example focuses solely on sending an SMS via an API call and does not require a database to store state, user data, or message history.
For more complex applications (e.g., tracking message delivery status via webhooks, storing user preferences), you would typically integrate a database (like PostgreSQL, MongoDB) and use an ORM (like Prisma, Sequelize) or a database client library.
7. Security Features
While basic, our implementation includes some security considerations:
- Secrets Management: API keys and secrets are stored in environment variables (
.env
) and excluded from version control (.gitignore
). This is crucial. - Input Validation: The
/send-sms
endpoint performs basic validation on theto
andtext
inputs to prevent obviously malformed requests and potentially mitigate simple injection attempts (though more robust sanitization might be needed depending on howtext
is used later). The phone number format check adds another layer.
Further Enhancements (Recommended for Production):
- Rate Limiting: Implement rate limiting on the
/send-sms
endpoint using middleware likeexpress-rate-limit
to prevent abuse and excessive costs. - Authentication/Authorization: Secure the API endpoint itself. If this API is not meant to be public, add authentication (e.g., API keys, JWT tokens) to ensure only authorized clients can trigger SMS sending.
- Input Sanitization: If the
text
field could ever contain user-generated content that is processed further, use libraries likeDOMPurify
(if rendering as HTML) or appropriate validation/escaping based on the context to prevent Cross-Site Scripting (XSS) or other injection attacks. - Helmet Middleware: Use the
helmet
middleware for Express to set various HTTP headers that improve security (e.g.,X-Content-Type-Options
,Referrer-Policy
,Strict-Transport-Security
). - Dependency Scanning: Regularly scan project dependencies for known vulnerabilities using
npm audit
or tools like Snyk.
8. Handling Special Cases
- Phone Number Formatting: The Vonage API generally expects phone numbers in E.164 format (e.g.,
+15551234567
). While our basic validation checks for a plausible format, you might need more sophisticated parsing/validation using libraries likelibphonenumber-js
if dealing with varied user inputs. Our code currently recommends E.164 in the error message. - Character Limits & Encoding: Standard SMS messages have character limits (160 for GSM-7, 70 for UCS-2/Unicode). Longer messages are split (concatenated SMS). Vonage handles concatenation automatically, but be mindful of billing (you pay per segment). Unicode characters (like emojis) will reduce the limit per segment significantly. The SDK handles encoding.
- Sender ID Restrictions: Alphanumeric Sender IDs are not supported in all countries (e.g., the US often requires standard numbers) and may have registration requirements. Using a Vonage virtual number is generally more reliable globally.
- Delivery Status: This guide only covers sending. To confirm delivery, you need to configure Delivery Receipts (DLRs) by setting up a webhook endpoint in your Vonage application settings and processing the callbacks Vonage sends to it. This is beyond the scope of this basic guide.
9. Performance Optimizations
For this simple application, performance is largely dependent on the Vonage API's response time. However:
- SDK Client Initialization: We initialize the Vonage SDK client once when the application starts (
vonageClient.js
) and reuse that instance. Creating a new client for every request would add unnecessary overhead. - Asynchronous Operations: The use of
async/await
ensures that the Node.js event loop is not blocked while waiting for the Vonage API response, allowing the server to handle other requests concurrently.
Further Enhancements (For Higher Scale):
- Caching: Not directly applicable for sending unique SMS, but if you frequently look up user data before sending, caching that data could improve performance.
- Load Balancing: For very high throughput, deploy multiple instances of the application behind a load balancer.
- Connection Pooling: While the SDK manages underlying HTTP connections, ensure your server has sufficient resources (CPU, memory, network) to handle the desired load.
10. Monitoring, Observability, and Analytics
Basic monitoring is achieved through console
logging.
Further Enhancements:
- Health Check Endpoint: The
/
route serves as a very basic health check. More robust checks could verify connectivity to Vonage (e.g., by making a low-cost API call like checking account balance). - Application Performance Monitoring (APM): Integrate APM tools (like Datadog, New Relic, Dynatrace) to get detailed insights into request latency, error rates, resource usage, and distributed tracing.
- Metrics: Track key metrics like the number of SMS sent successfully, number of failures, API latency, and error types. Expose these via a
/metrics
endpoint for scraping by systems like Prometheus, or send them directly to a monitoring service. - Error Tracking Services: Use services like Sentry or Bugsnag to automatically capture, aggregate, and alert on application errors in real-time.
11. Troubleshooting and Caveats
Non-Whitelisted Destination
Error (403 Forbidden):- Meaning: You are using a Vonage trial account and tried to send an SMS to a phone number that has not been added and verified in your ""Test numbers"" list.
- Solution: Go to your Vonage Dashboard ->
Numbers
->Test numbers
. Add the recipient's phone number and verify it using the code Vonage sends.
Invalid Credentials
Error (401 Unauthorized):- Meaning: The
VONAGE_API_KEY
orVONAGE_API_SECRET
in your.env
file is incorrect or does not match the account associated with theVONAGE_SENDER_NUMBER
. - Solution: Double-check your API Key and Secret in the Vonage Dashboard (
API Settings
) and ensure they are correctly copied into your.env
file. Make sure there are no extra spaces or characters.
- Meaning: The
Invalid Sender Address
/Illegal Sender Address
Error:- Meaning: The
VONAGE_SENDER_NUMBER
in your.env
file is not a valid number associated with your account, is not SMS-capable, or is an Alphanumeric Sender ID that is not permitted or registered for the destination country. - Solution: Verify the sender number in your Vonage Dashboard (
Numbers
->Your numbers
). Ensure it has SMS capabilities enabled. If using an Alphanumeric Sender ID, check regulations and registration status.
- Meaning: The
- Missing Environment Variables:
- Meaning: The application terminated on startup with an error message indicating a required
VONAGE_...
variable was not found. - Solution: Ensure your
.env
file exists in the project root, is correctly formatted, and contains all required variables (VONAGE_API_KEY
,VONAGE_API_SECRET
,VONAGE_SENDER_NUMBER
). Ensuredotenv/config
is imported early invonageClient.js
andsmsService.js
.
- Meaning: The application terminated on startup with an error message indicating a required
- Incorrect
Content-Type
for POST Request:- Meaning: Your API client (curl, Postman) sent the request without the
Content-Type: application/json
header, or sent data in the wrong format.express.json()
middleware won't parse the body correctly. - Solution: Ensure your API client is sending a
POST
request with the headerContent-Type: application/json
and the body is valid JSON (e.g.,{ ""to"": ""+15551234567"", ""text"": ""Hello"" }
).
- Meaning: Your API client (curl, Postman) sent the request without the
- SMS Not Received:
- Check the API response/logs for success (
status: '0'
). - Verify the recipient number (
to
) is correct. - Check if the recipient device has signal/is not blocked.
- Check Vonage Dashboard (
Logs
->Messaging
) for detailed logs of the message attempt. - Consider potential carrier filtering on the recipient's end.
- Check the API response/logs for success (
12. Deployment and CI/CD
Deployment:
- Environment Variables: Deployment platforms (like Heroku, Vercel, AWS Elastic Beanstalk, Docker containers) have specific ways to set environment variables securely. Do not deploy your
.env
file. ConfigureVONAGE_API_KEY
,VONAGE_API_SECRET
,VONAGE_SENDER_NUMBER
, andPORT
in the platform's settings. - Build Step: Not strictly required for this simple Node.js app unless using TypeScript or a bundler.
- Running the App: Ensure the platform runs your application using the start command defined in
package.json
.package.json
script:""start"": ""node index.js""
- Command to run:
npm start
Example (Conceptual Heroku Deployment):
# Login to Heroku CLI
heroku login
# Create Heroku app
heroku create your-app-name
# Set environment variables
heroku config:set VONAGE_API_KEY=YOUR_ACTUAL_API_KEY_HERE
heroku config:set VONAGE_API_SECRET=YOUR_ACTUAL_API_SECRET_HERE
heroku config:set VONAGE_SENDER_NUMBER=YOUR_VONAGE_NUMBER_OR_ID_HERE
# PORT is usually set automatically by Heroku
# Deploy using Git
git add .
git commit -m ""Prepare for Heroku deployment""
git push heroku main # Or your default branch
CI/CD (Conceptual):
A typical CI/CD pipeline (using GitHub Actions, GitLab CI, Jenkins) would:
- Trigger: On push to
main
branch or creation of a Pull Request. - Checkout Code: Get the source code.
- Setup Node.js: Specify the Node.js version.
- Install Dependencies: Run
npm ci
(preferred overinstall
in CI for consistency). - Linting/Formatting: Run tools like ESLint or Prettier.
- Testing: Run unit and integration tests (see Section 13). Requires setting mock environment variables for tests.
- Build (if needed): Run build steps.
- Deploy: If tests pass and on the main branch, deploy to the target environment (e.g., using the platform's CLI like
heroku deploy
).
13. Verification and Testing
Manual Verification:
-
Run the Application:
npm start
You should see output like:
Vonage client initialized successfully. Server listening on http://localhost:3000 SMS Send Endpoint: POST http://localhost:3000/send-sms
-
Send a Test Request (using
curl
): Open a new terminal window. Replace+15551234567
with a verified test number (if using a trial account) or a valid recipient number, and use your actualVONAGE_SENDER_NUMBER
.curl -X POST http://localhost:3000/send-sms \ -H ""Content-Type: application/json"" \ -d '{ ""to"": ""+15551234567"", ""text"": ""Hello from Node.js and Vonage! Test at '""$(date)""'"" }'
-
Check Application Logs: Look at the terminal where
npm start
is running. You should see logs indicating the request was received and the attempt to send the SMS.- Success:
Attempting to send SMS...
,Message sent successfully...
- Failure:
Attempting to send SMS...
,Message failed with error...
,Failed to send SMS via API endpoint...
- Success:
-
Check API Response: The
curl
command should output a JSON response.- Success:
{ ""success"": true, ""message"": ""SMS sent successfully."", ""messageId"": ""..."" }
- Failure:
{ ""success"": false, ""message"": ""Failed to send SMS: Vonage API Error..."" }
or{ ""success"": false, ""message"": ""Missing required fields..."" }
- Success:
-
Check Recipient Phone: The phone number specified in the
to
field should receive the SMS message shortly. -
Check Vonage Dashboard: Log in to the Vonage Dashboard and navigate to
Logs
->Messaging
. You should see a record of the attempted SMS, including its status (e.g.,delivered
,failed
,rejected
).
Automated Testing (Conceptual):
- Unit Tests: Test individual functions in isolation.
- Test
smsService.js
: Use a testing framework likejest
ormocha
. Mock the@vonage/server-sdk
to simulate successful and failed API responses fromvonage.sms.send
without actually calling the API. Verify thatsendSms
handles responses correctly and throws errors appropriately. - Test input validation logic separately.
- Test
- Integration Tests: Test the interaction between components.
- Use a library like
supertest
to make HTTP requests to your running Express application (/send-sms
endpoint). - Mock the
smsService.js
module to control its behavior during the test (e.g., make it simulate success or failure) and assert that the API endpoint returns the correct HTTP status code and JSON response based on the mocked service behavior. This avoids hitting the actual Vonage API during tests.
- Use a library like