This guide provides a complete walkthrough for building a Node.js application using the Express framework to send SMS messages via the MessageBird API. We'll cover everything from project setup to deployment considerations, enabling you to integrate reliable SMS functionality into your applications.
By the end of this guide, you'll have a simple but functional Express API endpoint capable of accepting a recipient phone number and a message body, and then using MessageBird to deliver that message as an SMS.
Project Goals:
- Create a Node.js Express server.
- Integrate the MessageBird Node.js SDK.
- Securely manage API credentials.
- Build an API endpoint to trigger SMS sending.
- Implement basic validation and error handling.
- Provide guidance on testing and deployment.
Technology Stack:
- Node.js: A JavaScript runtime environment for server-side development.
- Express.js: A minimal and flexible Node.js web application framework.
- MessageBird: A unified messaging platform providing APIs for SMS, WhatsApp, Voice, and more. We'll use their REST API via the official Node.js SDK.
- dotenv: A module to load environment variables from a
.env
file intoprocess.env
.
System Architecture:
The system consists of a User/Client (e.g., using cURL or a frontend application) making an HTTP request to the Node.js/Express App's API endpoint (e.g., /send-sms
). The Express application receives the request, validates the input (recipient number, message body), and then uses the MessageBird Node.js SDK. The SDK, configured with the API key securely loaded from an .env
file, handles authentication and communicates with the MessageBird API over the internet. Finally, the MessageBird API processes the request and sends the SMS message to the recipient's mobile phone.
Prerequisites:
- Node.js and npm (or yarn): Installed on your development machine. (Download Node.js)
- MessageBird Account: Sign up for a free account at MessageBird.com.
- MessageBird API Key: Obtain an API key from your MessageBird Dashboard.
- Note: MessageBird provides both live and test API keys. Test keys are useful for validating your API integration (checking authentication, request structure) without sending actual SMS messages or incurring costs, but they won't result in a message arriving on a phone. This guide uses a live key to demonstrate the full sending process and assumes you will manage costs accordingly.
- MessageBird Virtual Number: Purchase or use a trial virtual mobile number (VMN) capable of sending SMS from the MessageBird Dashboard. This will be your
originator
number. - Basic Terminal/Command Line Knowledge: Familiarity with navigating directories and running commands.
- Code Editor: Such as VS Code, Sublime Text, or Atom.
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 node-messagebird-sms cd node-messagebird-sms
-
Initialize Node.js Project: This command creates a
package.json
file, which keeps track of your project's metadata and dependencies.npm init -y
(The
-y
flag accepts the default settings) -
Install Dependencies: We need Express for the web server, the MessageBird SDK, and
dotenv
for managing environment variables.npm install express messagebird dotenv
-
Create Project Files: Create the main application file and files for environment variables and Git ignore rules.
touch index.js .env .gitignore
index.js
: Our main application code..env
: Stores sensitive information like API keys (will be configured later)..gitignore
: Specifies files that Git should ignore (like.env
andnode_modules
).
-
Configure
.gitignore
: Open.gitignore
and add the following lines to prevent committing sensitive data and local dependencies:# Dependencies node_modules/ # Environment variables .env # Logs npm-debug.log* yarn-debug.log* yarn-error.log* *.log # Optional Editor directories .vscode .idea
-
Set up Basic Express Server (
index.js
): Openindex.js
and add the basic structure for an Express application.// index.js require('dotenv').config(); // Load environment variables from .env file FIRST const express = require('express'); const app = express(); const PORT = process.env.PORT || 3000; // Use port from env var or default to 3000 // Middleware to parse JSON request bodies app.use(express.json()); // Simple root route app.get('/', (req, res) => { res.send('MessageBird SMS Sender API is running!'); }); // Start the server app.listen(PORT, () => { console.log(`Server listening on port ${PORT}`); // Using console.log for initial setup simplicity });
- Why
dotenv
first? We callrequire('dotenv').config()
at the very top to ensure environment variables are loaded before any other code tries to access them. - Why
express.json()
? This middleware is crucial for parsing incoming requests with JSON payloads (which we'll use for our API endpoint).
- Why
-
Run the Basic Server: Test if the basic setup works.
node index.js
You should see
Server listening on port 3000
in your console. You can openhttp://localhost:3000
in your browser to see the welcome message. PressCtrl+C
to stop the server for now.
2. Integrating with MessageBird
Now, let's configure the MessageBird SDK and obtain the necessary credentials.
-
Obtain MessageBird API Key:
- Log in to your MessageBird Dashboard.
- Navigate to the
Developers
section in the left-hand sidebar. - Click on the
API access (REST)
tab. - If you don't have a key, click
Add access key
. Make sure you are creating or using a Live API Key if you intend to send real messages (refer to the Prerequisites note about test vs. live keys). - Copy the generated Live API Key. Treat this key like a password — keep it secret!
-
Obtain MessageBird Virtual Number (Originator):
- In the MessageBird Dashboard, navigate to
Numbers
in the sidebar. - If you don't have a number, click
Buy a number
. - Select your country and ensure the
SMS
capability is enabled. - Choose a number and complete the purchase (or use a trial number if available).
- Copy the full number in E.164 format (e.g.,
+12025550149
,+442071838750
). This will be your sender ID (originator
).
- In the MessageBird Dashboard, navigate to
-
Configure Environment Variables (
.env
): Open the.env
file and add your API key and originator number. Replace the placeholder values with your actual credentials.# .env # Your LIVE MessageBird API Key MESSAGEBIRD_API_KEY=YOUR_LIVE_API_KEY_HERE # Your purchased MessageBird Virtual Number (in E.164 format) MESSAGEBIRD_ORIGINATOR_NUMBER=+12345678900
MESSAGEBIRD_API_KEY
: The live access key copied from the MessageBird dashboard. It authenticates your requests.MESSAGEBIRD_ORIGINATOR_NUMBER
: The virtual number you purchased or obtained. This is the 'sender' number that recipients will see (subject to country regulations). Note: In some countries, using an alphanumeric sender ID (likeMyCompany
) is possible, but it often requires pre-registration and isn't universally supported. Using a virtual number is generally more reliable for programmatic sending.
-
Initialize MessageBird Client (
index.js
): Modifyindex.js
to initialize the MessageBird client using the API key from the environment variables.// index.js require('dotenv').config(); const express = require('express'); // --- Add MessageBird initialization --- const messagebirdApiKey = process.env.MESSAGEBIRD_API_KEY; if (!messagebirdApiKey) { console.error('FATAL ERROR: MESSAGEBIRD_API_KEY environment variable not set.'); process.exit(1); // Exit if the key is missing } const messagebird = require('messagebird')(messagebirdApiKey); // --- End initialization --- const app = express(); const PORT = process.env.PORT || 3000; app.use(express.json()); // --- Add Originator check --- if (!process.env.MESSAGEBIRD_ORIGINATOR_NUMBER) { console.warn('WARNING: MESSAGEBIRD_ORIGINATOR_NUMBER environment variable not set. Sending might fail or use default \'MessageBird\'.'); // You might want to exit here too depending on requirements: // process.exit(1); } // --- End check --- app.get('/', (req, res) => { res.send('MessageBird SMS Sender API is running!'); }); // Placeholder for the SMS sending route (coming next) app.listen(PORT, () => { console.log(`Server listening on port ${PORT}`); });
- Why check environment variables? This simple check prevents the application from starting without essential configuration, making debugging easier.
3. Implementing Core SMS Sending Functionality
Let's create the API endpoint that will handle requests to send SMS messages.
-
Create the API Endpoint (
/send-sms
): Add a newPOST
route toindex.js
to handle SMS sending requests.// index.js // ... (previous code: require statements, app init, middleware, checks) ... app.get('/', (req, res) => { res.send('MessageBird SMS Sender API is running!'); }); // --- Add SMS Sending Route --- app.post('/send-sms', (req, res) => { const { recipient, message } = req.body; // Extract recipient and message from request body // 1. Input Validation if (!recipient || !message) { console.warn('Send SMS failed: Missing recipient or message', { body: req.body }); return res.status(400).json({ error: 'Missing required fields: recipient and message' }); } // Basic E.164 validation: Checks for '+' followed by digits. // This is a simplified check; a more specific length check will be added later. // Real-world validation can be more complex (e.g., using libraries like google-libphonenumber). if (!/^\+\d+$/.test(recipient)) { console.warn('Send SMS failed: Invalid recipient format', { recipient }); return res.status(400).json({ error: 'Invalid recipient format. Use E.164 format (e.g., +12345678900).' }); } // Note: Message length validation is added in the final code (Section 13). const originator = process.env.MESSAGEBIRD_ORIGINATOR_NUMBER || 'MessageBird'; // Use configured number or default // 2. Prepare Message Parameters const params = { originator: originator, recipients: [recipient], // Must be an array body: message, }; // 3. Send Message via MessageBird SDK console.log(`Attempting to send SMS to ${recipient} from ${originator}`); // Simple logging for now messagebird.messages.create(params, (err, response) => { if (err) { // 4. Handle Errors console.error('MessageBird API Error:', err); // Using console.error here; more robust logging introduced later. let statusCode = 500; let errorMessage = 'Failed to send SMS due to an internal server error.'; let errorCode = null; if (err.errors && err.errors.length > 0) { // Try to get specific error details from MessageBird response const firstError = err.errors[0]; errorCode = firstError.code; errorMessage = `MessageBird Error ${errorCode}: ${firstError.description}`; // Map common MessageBird error codes to HTTP status codes (selective mapping) if ([2, 9, 21, 22].includes(errorCode)) statusCode = 400; // Bad request if (errorCode === 7) statusCode = 402; // Payment Required if (errorCode === 10) statusCode = 401; // Unauthorized // Note: This mapping is selective; a production app might need more comprehensive mapping. } else if (err.statusCode) { statusCode = err.statusCode; errorMessage = `Network or Client Error: ${err.message || 'Failed to communicate with MessageBird API'}`; } return res.status(statusCode).json({ error: errorMessage, errorCode: errorCode, details: err.errors || err.message }); } // 5. Handle Success console.log('MessageBird API Success:', response); // Simple logging const recipientInfo = response.recipients.items[0] || {}; res.status(200).json({ message: 'SMS submitted successfully!', // Changed from 'sent' as it's just submitted initially details: { id: response.id, status: recipientInfo.status, // e.g., 'sent', 'scheduled' statusDatetime: recipientInfo.statusDatetime, recipient: recipientInfo.recipient, } }); }); }); // --- End SMS Sending Route --- app.listen(PORT, () => { console.log(`Server listening on port ${PORT}`); });
- Request Body: We expect a JSON body with
recipient
(E.164 format phone number) andmessage
(the text content). - Input Validation: Basic checks ensure required fields are present and the recipient number has a plausible format. Crucial for security and preventing errors.
- Parameters: The
params
object maps directly to the requirements of the MessageBirdmessages.create
function.recipients
must be an array, even for a single number. messagebird.messages.create
: This is the core SDK function. It takes the parameters and a callback function.- Callback Function: The callback receives
err
(if an error occurred during the API call) orresponse
(on success). - Error Handling: If
err
exists, we log it (usingconsole.error
for now) and return a relevant HTTP status code (e.g., 400 for bad input, 402 for balance issues, 500 for server/API errors) and error message. We attempt to parse specific errors from the MessageBird response. - Success Handling: If successful, we log the response and return a 200 status with details like the MessageBird message ID and initial status.
- Request Body: We expect a JSON body with
4. Verification and Testing
Let's test the endpoint using a tool like curl
or Postman.
-
Start the Server: Make sure your
.env
file is correctly configured with your live API key and originator number.node index.js
-
Send a Test Request (using
curl
): Open a new terminal window (leave the server running in the first one). Replace+1YOUR_PHONE_NUMBER
with your actual mobile number in E.164 format.curl -X POST http://localhost:3000/send-sms \ -H ""Content-Type: application/json"" \ -d '{ ""recipient"": ""+1YOUR_PHONE_NUMBER"", ""message"": ""Hello from Node.js and MessageBird!"" }'
-
Check the Response:
- Success: You should receive a JSON response similar to this in your
curl
terminal, and the SMS should arrive on your phone shortly (standard SMS charges may apply).Your server console (where{ ""message"": ""SMS submitted successfully!"", ""details"": { ""id"": ""mb-message-id-string"", ""status"": ""sent"", ""statusDatetime"": ""2023-10-27T10:30:00Z"", ""recipient"": ""+1YOUR_PHONE_NUMBER"" } }
node index.js
is running) should also show the success logs (console.log
). - Error: If something is wrong (e.g., invalid API key, incorrect recipient format, insufficient funds), you'll get an error response:
// Example: Invalid recipient format { ""error"": ""Invalid recipient format. Use E.164 format (e.g., +12345678900)."" }
Check the server console logs for more detailed error information from the// Example: MessageBird API error (e.g., bad key or insufficient balance) { ""error"": ""MessageBird Error 7: No balance"", ""errorCode"": 7, ""details"": [ /* ... detailed error object from MessageBird ... */ ] }
console.error
calls.
- Success: You should receive a JSON response similar to this in your
-
Testing with Postman:
- Open Postman.
- Create a new request.
- Set the method to
POST
. - Enter the URL:
http://localhost:3000/send-sms
. - Go to the ""Body"" tab, select ""raw"", and choose ""JSON"" from the dropdown.
- Enter the JSON payload:
{ ""recipient"": ""+1YOUR_PHONE_NUMBER"", ""message"": ""Testing SMS via Postman!"" }
- Click ""Send"". Observe the response in Postman and the logs in your server console.
5. Error Handling and Logging Improvements
While we have basic error handling using console.log
/console.error
, production systems need more robustness. This section introduces improvements that are incorporated into the final code (Section 13).
- Consistent Error Format: Ensure all error responses follow a consistent JSON structure (e.g.,
{ ""error"": ""message"", ""errorCode"": 123, ""details"": { ... } }
). - Structured Logging: Switch from
console.log
to a dedicated logging library likewinston
orpino
. This provides significant advantages:- Different Log Levels: Distinguish between informational messages (
info
), warnings (warn
), and critical errors (error
). - Structured Output: Logging in JSON format makes logs easier to parse, query, and analyze by log management systems (like Datadog, Splunk, ELK stack).
- Configurable Transports: Send logs to different destinations (console, files, external services) based on environment or severity.
- Example
winston
setup (as used in Section 13):npm install winston
// Example setup with Winston (replaces console.log/error) const winston = require('winston'); const logger = winston.createLogger({ level: 'info', // Log only info, warn, error by default format: winston.format.json(), // Log as JSON defaultMeta: { service: 'sms-sender' }, // Add service context transports: [ // Write errors to error.log new winston.transports.File({ filename: 'error.log', level: 'error' }), // Write all logs (info and above) to combined.log new winston.transports.File({ filename: 'combined.log' }), ], }); // Also log to the console in non-production environments if (process.env.NODE_ENV !== 'production') { logger.add(new winston.transports.Console({ format: winston.format.simple(), // Use simpler format for console })); } // Usage (replaces console.log/error): // logger.error('MessageBird API Error:', { error: err }); // Log error objects // logger.info('SMS submitted successfully', { recipient: recipient, messageId: response.id }); // Log info with context
- Different Log Levels: Distinguish between informational messages (
- Retry Mechanisms: For critical messages where transient network errors are unacceptable, consider implementing a retry strategy (e.g., using libraries like
async-retry
) with exponential backoff. This adds complexity but improves reliability.
6. Database Schema and Data Layer
For this basic SMS sending API endpoint, a database is not strictly required. Messages are sent based on direct API requests.
However, if you were building a more comprehensive application (e.g., tracking message history, handling replies, managing user preferences), you would need a database (like PostgreSQL, MongoDB, MySQL). This would involve:
- Defining Schemas/Models: Structure for storing message details (ID, recipient, sender, body, status, timestamps), user data, etc.
- Data Access Layer: Using an ORM/ODM (like Sequelize for SQL, Mongoose for MongoDB) or plain database drivers to interact with the database.
- Storing Message Status: Updating message status based on delivery reports received via MessageBird webhooks (a more advanced topic).
7. Security Features
Security is critical when dealing with APIs and potentially sensitive information.
- Environment Variables: Never commit your
.env
file or hardcode API keys/credentials in your source code. Usedotenv
for local development and your deployment platform's secure environment variable management in production. Ensure.env
is listed in your.gitignore
. - Input Validation: Rigorously validate all input from external sources (the request body in this case).
- Recipient: Ensure it adheres to the expected E.164 format. The improved regex
/^\+\d{10,15}$/
(used in Section 13) provides a better check than the initial one. For maximum accuracy, consider libraries likegoogle-libphonenumber
(though potentially overkill for a basic service). - Message Body: Check for reasonable length. SMS messages have character limits (typically 160 GSM-7 chars, 70 Unicode chars per part). Very long messages are split and cost more. Reject empty or excessively long messages. For example, checking message length (as implemented in the final code in Section 13) prevents sending excessively long or empty messages. Sanitize content if it could contain malicious input, especially if derived from user-generated content elsewhere in your system.
- Recipient: Ensure it adheres to the expected E.164 format. The improved regex
- Rate Limiting: Protect your API endpoint (and your MessageBird budget) from abuse (accidental or malicious). Use middleware like
express-rate-limit
to limit the number of requests from a single IP address within a time window. This is implemented in the final code (Section 13).npm install express-rate-limit
// Example implementation (see Section 13 for full context) const rateLimit = require('express-rate-limit'); const smsLimiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 10, // Limit each IP to 10 requests per window message: { error: 'Too many SMS requests created from this IP, please try again after 15 minutes' } }); app.post('/send-sms', smsLimiter, /* route handler */ );
- Authentication/Authorization (If Applicable): If this API is not intended for public use, secure it. Ensure only authenticated and authorized clients (users, other services) can call the
/send-sms
endpoint. Methods include API keys specific to your service, JWT tokens, session authentication, OAuth, etc. - HTTPS: Always deploy your application behind a proxy that terminates SSL/TLS, ensuring traffic between clients and your server is encrypted (HTTPS). Most modern hosting platforms handle this automatically.
8. Handling Special Cases
- Originator Restrictions: Alphanumeric sender IDs (e.g., ""MyCompany"") are not supported in all countries (like the US & Canada) and often require pre-registration. Using a purchased virtual number (in E.164 format) as the
originator
is generally the most reliable approach for global sending. Always check MessageBird's country restrictions documentation. - Character Limits & Encoding: Standard SMS (using GSM-7 encoding) allows 160 characters. Using characters outside this set (like many emojis or non-Latin scripts) forces Unicode (UCS-2) encoding, reducing the limit to 70 characters per SMS part. MessageBird automatically handles splitting longer messages into multiple parts (concatenated SMS), but you are billed for each part. Inform users or truncate messages appropriately if length/cost is a concern.
- Invalid or Non-Mobile Numbers: The E.164 validation helps, but MessageBird's API will also perform checks. An invalid or non-existent number will result in an API error (often
code: 2
- invalid parameter) or a failed delivery status later. - Blocked Numbers/Opt-outs: Implement mechanisms to handle user opt-outs (e.g., responding to ""STOP"" messages, maintaining a suppression list). Sending to users who have opted out can violate regulations (like TCPA in the US). MessageBird offers features to help manage opt-outs.
9. Performance Optimizations
For this specific function (a single API call per request), performance bottlenecks within the Node.js code itself are less likely than external factors.
- Asynchronous Nature: Node.js is non-blocking. The
messagebird.messages.create
call is asynchronous, meaning your server isn't stalled waiting for MessageBird's response and can handle other requests concurrently. This is inherently performant for I/O-bound tasks. - External API Latency: The primary performance factor will be the network latency and processing time of the MessageBird API itself.
- Load Testing: If high throughput is expected, use load testing tools (e.g.,
k6
,artillery
,autocannon
) to simulate traffic. This helps identify potential limits (CPU, memory, network bandwidth) or issues with dependencies (like rate limits). - Caching: Not typically applicable for sending unique SMS messages. Caching might be relevant if you were frequently fetching message statuses via API calls, but using MessageBird's webhooks for status updates is generally more efficient.
10. Monitoring, Observability, and Analytics
To ensure your service runs reliably in production:
- Health Checks: Implement a simple
/health
endpoint that returns a200 OK
status. Monitoring systems (like uptime checkers, Kubernetes liveness probes) can ping this endpoint to verify the service is operational. (Added in Section 13).// Example health check endpoint app.get('/health', (req, res) => { res.status(200).json({ status: 'UP', timestamp: new Date().toISOString() }); });
- Application Performance Monitoring (APM): Use APM tools (e.g., Datadog, New Relic, Dynatrace, Sentry APM, OpenTelemetry) to monitor key metrics like request latency, throughput (requests per minute), error rates, CPU/memory usage. These tools help diagnose performance issues and bottlenecks.
- Structured Logging: As discussed in Section 5, use structured logging (e.g., Winston sending JSON to a log aggregator) for effective analysis and troubleshooting.
- Error Tracking: Integrate dedicated error tracking services (Sentry, Bugsnag, Rollbar) to capture, aggregate, alert on, and provide context for runtime exceptions in your Node.js application.
- MessageBird Dashboard: Regularly utilize the MessageBird Dashboard (""Messaging -> Logs""). It provides invaluable insights into the status of each message (e.g.,
sent
,delivered
,failed
), delivery timestamps, error codes if failures occur, and associated costs. This is crucial for debugging specific SMS delivery problems.
11. Troubleshooting and Caveats
Common issues and things to be aware of:
- Error:
Authentication failed
orRequest not allowed (incorrect login details...)
(Code 2, 10, 21):- Cause: Invalid
MESSAGEBIRD_API_KEY
in your environment variables. It might be mistyped, have extra whitespace, be a test key when a live one is needed, or belong to a different account. - Solution: Double-check the API key in your
.env
file (or production environment variables) against the key shown in the MessageBird Dashboard (Developers
->API access
). Ensure you are using the correct key type (live/test). Restart your application after making changes.
- Cause: Invalid
- Error:
recipient is invalid
or similar parameter errors (Code 2, 22):- Cause: The phone number provided in the
recipient
field is not in the valid E.164 format (+
sign followed by country code and number, no spaces or dashes). - Solution: Verify the input number format. Ensure your validation logic (regex or library) correctly enforces E.164. Check the data being sent in the request body.
- Cause: The phone number provided in the
- Error:
originator is invalid
(Code 2, 21):- Cause: The
MESSAGEBIRD_ORIGINATOR_NUMBER
in your environment variables is incorrect, not associated with your MessageBird account, formatted incorrectly, or disallowed as a sender ID in the destination country. - Solution: Confirm the number matches a number listed under
Numbers
in your MessageBird Dashboard and is in E.164 format. If using an alphanumeric ID, check country regulations and registration status.
- Cause: The
- Error:
No balance
(Code 7):- Cause: Your MessageBird account lacks sufficient credits to cover the cost of the SMS message.
- Solution: Add funds to your account through the MessageBird Dashboard (
Billing
section).
- SMS Not Received by Recipient:
- Cause: Can be varied: transient carrier delays, recipient's phone is off/out of service, incorrect number provided, carrier spam filtering, number is blocked, MessageBird platform issues (rare).
- Solution:
- Verify the recipient number is absolutely correct.
- Check the MessageBird Dashboard logs (
Messaging
->Logs
) for that specific message. Look at its status (delivered
,failed
,expired
) and any error details provided. - Wait a few minutes — delivery isn't always instantaneous.
- Test sending to a different number or carrier if possible to isolate the issue.
- If logs show
delivered
but the user insists they didn't receive it, the issue likely lies with the recipient's device or carrier. - If logs show
failed
with an error code, investigate that specific code. - Contact MessageBird support if issues persist despite logs showing
sent
or if you suspect a platform problem.
- Caveat: Cost: Sending SMS messages incurs costs based on the destination country and message volume. Monitor your MessageBird balance and be aware of pricing. Test keys are free but don't send real messages.
- Caveat: Delivery Status: The API response provides an initial status (like
sent
orscheduled
). The final delivery confirmation (delivered
orfailed
) happens asynchronously. To get these final statuses reliably, you need to implement webhooks to receive Delivery Reports from MessageBird (see ""Next Steps""). The code examples provided map common API call errors, but a production system might need more detailed mapping or handling logic based on MessageBird's documentation.
12. Deployment and CI/CD
To deploy your Node.js Express application:
- Choose a Hosting Platform: Many options exist, including:
- PaaS (Platform-as-a-Service): Heroku, Render, Fly.io (easy deployment from Git).
- Serverless: AWS Lambda, Google Cloud Functions, Vercel (often require framework adaptations).
- Containers: AWS Fargate/ECS, Google Cloud Run, Azure Container Apps (using Docker).
- VPS/Servers: AWS EC2, Google Compute Engine, DigitalOcean Droplets (require more manual setup).
- Prepare
package.json
: Ensure yourscripts
include astart
command.// package.json excerpt { ""scripts"": { ""start"": ""node index.js"", ""test"": ""echo \""Error: no test specified\"" && exit 1"" } }
- Environment Variables: Configure
MESSAGEBIRD_API_KEY
andMESSAGEBIRD_ORIGINATOR_NUMBER
securely within your chosen platform's settings. Never commit the.env
file to Git. Also setNODE_ENV=production
for performance and security benefits.