code examples
code examples
Send MMS with Node.js, Express, and MessageBird: Complete Tutorial
Build a Node.js Express application to send MMS messages via MessageBird API. Complete guide with code examples, error handling, security best practices, and deployment instructions.
Send MMS with Node.js, Express, and MessageBird: Complete Tutorial
This guide provides a step-by-step walkthrough for building a Node.js application using the Express framework to send Multimedia Messaging Service (MMS) messages via the MessageBird API. You'll learn everything from project setup to deployment considerations, enabling you to integrate MMS capabilities into your applications effectively.
By the end of this tutorial, you'll have a functional Express API endpoint capable of accepting requests to send MMS messages – including text and media attachments – to recipients in the US and Canada, leveraging MessageBird's reliable infrastructure.
Project Overview and Goals
What You're Building:
Create a simple Node.js Express server with a single API endpoint (POST /send-mms). This endpoint receives a recipient's phone number, a message subject, a message body, and a URL pointing to a media file. It then uses the MessageBird API to send an MMS message containing this information to the specified recipient.
Problem Solved:
This project addresses the need to programmatically send rich media messages (images, videos, etc.) alongside text to users' mobile devices, enhancing communication beyond plain SMS. This is crucial for use cases like sending visual confirmations, promotional content, alerts with images, or multimedia notifications.
Technologies Used:
- Node.js: A JavaScript runtime environment for building server-side applications.
- Express.js: A minimal and flexible Node.js web application framework used to create the API endpoint.
- MessageBird: A communication Platform as a Service (CPaaS) provider whose API you'll use for sending the MMS messages.
- MessageBird Node.js SDK: Simplifies interaction with the MessageBird API.
- dotenv: A module to load environment variables from a
.envfile intoprocess.env.
System Architecture:
+-------------+ +-----------------------+ +-----------------+ +-------------------+
| User/Client | ----> | Your Node.js/Express | ----> | MessageBird API | ----> | Recipient's Phone |
| (e.g., curl,| | API Endpoint | | (MMS Service) | | (US/CA) |
| Postman) | | (POST /send-mms) | +-----------------+ +-------------------+
+-------------+ +-----------------------+
|
| Uses MessageBird SDK
| Reads API Key from .env
| Sends MMS RequestPrerequisites:
- Node.js and npm (or yarn) installed.
- A MessageBird account with API credentials (Access Key). Sign up at MessageBird.com.
- A dedicated virtual mobile number (VMN) purchased from MessageBird that is MMS-enabled for the US or Canada (this will be your
originator). - A publicly accessible URL for the media file you want to send (e.g., hosted on S3, Cloudinary, or a public web server). MessageBird needs to fetch the media from this URL.
- Basic understanding of Node.js, Express, and REST APIs.
Note on MessageBird SDK Version: This guide uses the MessageBird Node.js SDK (latest stable version 4.0.1 as of 2024). The SDK is available via npm: npm install messagebird.
Final Outcome:
A running Express application with an endpoint that, when called, sends an MMS message via MessageBird.
1. Setting Up the Project
Initialize your 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.
bashmkdir node-messagebird-mms cd node-messagebird-mms -
Initialize npm: Initialize the project using npm. The
-yflag accepts the default settings.bashnpm init -y -
Install Dependencies: Install
expressfor the web server,dotenvfor managing environment variables, and themessagebirdSDK.bashnpm install express dotenv messagebirdPackage Versions: This installs the latest versions of
express(web framework),dotenv(environment variable management), andmessagebird(SDK v4.0.1+). -
Create Project Structure: Create the basic files and folders you'll need.
bashtouch server.js .env .gitignore mkdir services touch services/messagebirdService.jsserver.js: The main entry point for your Express application.services/messagebirdService.js: A module to encapsulate the logic for interacting with the MessageBird API..env: Stores sensitive configuration like API keys (Git will ignore this file)..gitignore: Specifies files and directories that Git should ignore.
-
Configure
.gitignore: Addnode_modulesand.envto your.gitignorefile to prevent committing dependencies and sensitive credentials.text# .gitignore node_modules .env -
Configure
.env: Open the.envfile and add placeholders for your MessageBird API key and your MMS-enabled originator number. You'll obtain these values from your MessageBird dashboard.dotenv# .env # Obtain from MessageBird Dashboard: Developers -> API access # IMPORTANT: Replace this placeholder with your actual LIVE API key MESSAGEBIRD_API_KEY=YOUR_MESSAGEBIRD_LIVE_API_KEY # Your MessageBird MMS-enabled virtual number (E.164 format) # IMPORTANT: Replace this placeholder with your actual MMS-enabled number from MessageBird MESSAGEBIRD_ORIGINATOR=+120XXXXXXXX- Why
.env? Storing configuration like API keys directly in code is insecure and makes it hard to manage different environments (development, production)..envfiles allow you to keep sensitive data separate and load it into environment variables.
- Why
2. Implementing Core Functionality (MMS Sending Service)
Create a dedicated service function to handle the logic of sending the MMS message using the MessageBird SDK. This promotes separation of concerns.
-
Edit
services/messagebirdService.js: Open this file and add the following code:javascript// services/messagebirdService.js const messagebird = require('messagebird'); // SDK client instance passed in /** * Sends an MMS message using the MessageBird API. * * @param {object} mbClient - Initialized MessageBird client instance. * @param {string} recipient - The recipient's phone number in E.164 format. * @param {string} subject - The subject line for the MMS. * @param {string} body - The text body of the MMS. * @param {string} mediaUrl - The public URL of the media attachment. * @param {string} originator - The sender ID (MMS-enabled number). * @returns {Promise<object>} - A promise that resolves with the MessageBird API response. * @throws {Error} - Throws an error if the API call fails. */ async function sendMms(mbClient, recipient, subject, body, mediaUrl, originator) { // Basic validation (more robust validation should happen at the API layer) if (!recipient || !originator) { throw new Error('Missing required parameters: recipient and originator are required.'); } // Note: MessageBird API requires EITHER body OR mediaUrls (or both), not necessarily both if (!body && !mediaUrl) { throw new Error('Either body or mediaUrl (or both) must be provided.'); } const params = { originator: originator, recipients: [recipient], // Must be an array subject: subject, body: body, mediaUrls: mediaUrl ? [mediaUrl] : [] // Must be an array; can be empty if body provided // reference: 'your-internal-reference-optional' // Optional client reference // scheduledDatetime: '2025-12-31T10:30:00+00:00' // Optional scheduling (RFC3339 format) }; console.log(`Attempting to send MMS to ${recipient} from ${originator} via MessageBird...`); console.log('Payload:', params); try { // The MessageBird SDK uses the 'messages.create' method for both SMS and MMS. // It determines the type based on the parameters provided (e.g., presence of mediaUrls/subject). const result = await mbClient.messages.create(params); console.log('MessageBird API Success:', result); return result; } catch (error) { console.error('MessageBird API Error:', error); // Extract more specific error details if available if (error.errors) { console.error('Detailed Errors:', JSON.stringify(error.errors, null, 2)); // Rethrow with a more informative message throw new Error(`MessageBird API failed: ${error.errors[0].description || error.message}`); } throw error; // Rethrow the original error if no detailed errors array } } module.exports = { sendMms };- Why a Service Function? Isolating the MessageBird interaction makes the code modular, easier to test, and reusable if you need to send MMS from other parts of your application.
messages.create: The official MessageBird Node.js SDK uses themessages.createfunction for sending various message types, including SMS and MMS. The presence of parameters likemediaUrlsandsubjectsignals to the API that it's an MMS request.- Parameters: Map the function arguments directly to the
paramsobject required by the SDK, ensuringrecipientsandmediaUrlsare arrays. - Error Handling: The
try...catchblock handles potential errors during the API call, logging them and re-throwing for the calling function (your API endpoint) to manage. Check specifically forerror.errorswhich MessageBird often uses for detailed validation issues.
3. Building the API Layer
Set up the Express server and create the /send-mms endpoint.
-
Edit
server.js: Add the following code to set up the Express app, load environment variables, initialize the MessageBird client, and define the API route.javascript// server.js require('dotenv').config(); // Load environment variables from .env file const express = require('express'); const { sendMms } = require('./services/messagebirdService'); const app = express(); const PORT = process.env.PORT || 3000; // --- Input Validation (Basic Example) --- // For production, use a robust library like express-validator const validateSendMmsRequest = (req, res, next) => { const { recipient, subject, body, mediaUrl } = req.body; const errors = []; if (!recipient || typeof recipient !== 'string' || !/^\+\d{10,15}$/.test(recipient)) { errors.push('Invalid or missing "recipient" (must be E.164 format, e.g., +12223334444)'); } if (!subject || typeof subject !== 'string' || subject.length === 0 || subject.length > 256) { errors.push('Invalid or missing "subject" (string, 1 – 256 characters)'); } if (!body || typeof body !== 'string' || body.length === 0 || body.length > 2000) { errors.push('Invalid or missing "body" (string, 1 – 2,000 characters)'); } if (!mediaUrl || typeof mediaUrl !== 'string' || !/^https?:\/\/.+/.test(mediaUrl)) { errors.push('Invalid or missing "mediaUrl" (must be a valid public URL)'); } // Add checks for mediaUrl accessibility or file type/size if possible here, // though MessageBird performs its own checks. if (errors.length > 0) { return res.status(400).json({ message: "Bad Request", errors }); } next(); // Proceed to the route handler if validation passes }; // --- MessageBird Client Initialization --- const apiKey = process.env.MESSAGEBIRD_API_KEY; if (!apiKey) { console.error("FATAL ERROR: MESSAGEBIRD_API_KEY environment variable not set."); process.exit(1); // Exit if the API key is missing } const messagebird = require('messagebird').initClient(apiKey); console.log("MessageBird client initialized."); // --- Middleware --- app.use(express.json()); // Middleware to parse JSON request bodies // --- Routes --- app.get('/health', (req, res) => { res.status(200).json({ status: 'UP', timestamp: new Date().toISOString() }); }); app.post('/send-mms', validateSendMmsRequest, async (req, res) => { const { recipient, subject, body, mediaUrl } = req.body; const originator = process.env.MESSAGEBIRD_ORIGINATOR; if (!originator) { console.error("Configuration Error: MESSAGEBIRD_ORIGINATOR environment variable not set."); return res.status(500).json({ message: "Server configuration error." }); } try { const result = await sendMms( messagebird, recipient, subject, body, mediaUrl, originator ); // The API returns a message object upon successful submission res.status(200).json({ message: "MMS submitted successfully to MessageBird.", details: { id: result.id, href: result.href, recipientStatus: result.recipients.items, } }); } catch (error) { console.error(`Error processing /send-mms request: ${error.message}`, error); // Determine status code based on error type if possible // For now, use 500 for any service-level or unexpected error res.status(500).json({ message: "Failed to send MMS.", error: error.message || "An unexpected error occurred." }); } }); // --- Start Server --- app.listen(PORT, () => { console.log(`Server listening on port ${PORT}`); });dotenv.config(): Loads variables from.envat the start.express.json(): Middleware needed to parse incoming JSON request bodies (req.body).- MessageBird Initialization: The SDK client is initialized once using the API key from the environment variables. A check ensures the key is present.
/healthEndpoint: A simple route to check if the server is running./send-mmsRoute:- Uses the
POSTmethod as it creates a resource (an MMS message request). - Applies basic
validateSendMmsRequestmiddleware first. - Retrieves data from
req.body. - Retrieves the
originatornumber from environment variables. - Calls the
sendMmsservice function. - Responds with
200 OKand MessageBird's response details on success. - Responds with
400 Bad Requestif validation fails (handled by middleware). - Responds with
500 Internal Server Errorif thesendMmsfunction throws an error.
- Uses the
app.listen: Starts the server on the specified port.
4. Integrating with MessageBird (Configuration Details)
Proper configuration is key to connecting your application with MessageBird.
-
Obtain API Key:
- Log in to your MessageBird Dashboard.
- Navigate to Developers in the left-hand sidebar.
- Click on API access.
- If you don't have a key, click Add access key. Choose Live key.
- Copy the generated Access Key. Treat this key like a password – do not share it or commit it to version control.
- Paste this key into your
.envfile as the value forMESSAGEBIRD_API_KEY. Remember to replace the placeholderYOUR_MESSAGEBIRD_LIVE_API_KEY.
-
Obtain MMS-Enabled Originator Number:
- In the MessageBird Dashboard, navigate to Numbers.
- Purchase a US or Canadian number if you don't have one. Ensure it explicitly supports MMS capability. Not all numbers do.
- Copy the number in E.164 format (e.g.,
+1xxxxxxxxxx). - Paste this number into your
.envfile as the value forMESSAGEBIRD_ORIGINATOR. Remember to replace the placeholder+120XXXXXXXX.
-
Environment Variables Explained:
MESSAGEBIRD_API_KEY: (Required) Your secret key to authenticate requests with the MessageBird API. Found under Developers -> API access. Must be replaced by user.MESSAGEBIRD_ORIGINATOR: (Required) The MMS-enabled phone number (in E.164 format) that will appear as the sender of the MMS. Found under Numbers. Must be replaced by user.PORT: (Optional) The port your Express server will listen on. Defaults to 3000 if not set.
5. Error Handling, Logging, and Retry Mechanisms
Robust error handling and logging are crucial for production applications.
-
Error Handling Strategy:
- Validation Layer: Catch invalid input early using middleware (
validateSendMmsRequest) before hitting the service layer. Return400 Bad Requestwith clear error messages. - Service Layer (
sendMms): Catch errors specifically from the MessageBird API call within the service function. Log detailed errors provided by the SDK (error.errors). Re-throw a standardized or the original error. - API Route Layer (
/send-mms): Use atry...catchblock around the call to the service function. Catch errors thrown by the service. Return500 Internal Server Errorfor unexpected issues or specific MessageBird API failures. Log the error server-side. - Initialization Errors: Check for essential configuration (like API keys) on startup and exit gracefully if missing (
process.exit(1)).
- Validation Layer: Catch invalid input early using middleware (
-
Logging:
- We are using basic
console.logandconsole.errorfor demonstration. - Production Recommendation: Use a dedicated logging library like
WinstonorPino. These offer structured logging (JSON format is common), different log levels (debug, info, warn, error), and configurable outputs (console, file, external logging services). - What to Log:
- Incoming requests (method, path, relevant parameters – sanitize sensitive data).
- Payload sent to MessageBird.
- Successful responses from MessageBird (e.g., message ID).
- Errors encountered (validation errors, API errors, unexpected exceptions) with stack traces.
- We are using basic
-
Retry Mechanisms:
-
Network issues or temporary MessageBird glitches can cause requests to fail intermittently. Implementing retries can improve reliability.
-
Strategy: Use exponential backoff. Wait a short period before the first retry, then double the wait time for each subsequent retry, up to a maximum number of attempts. Add slight jitter (randomness) to wait times to avoid coordinated retries from multiple instances.
-
Implementation: While you could implement this manually, libraries like
async-retrysimplify this process significantly. -
Retry Best Practice (2024): Only retry on potentially transient errors (5xx server errors, network timeouts). Do NOT retry on client errors (4xx) such as invalid API key (401), invalid parameters (400), or rate limits (429). MessageBird's API uses standard HTTP status codes.
-
Example Concept (using
async-retry- requiresnpm install async-retry):javascript// Inside services/messagebirdService.js (conceptual) const retry = require('async-retry'); async function sendMmsWithRetry(mbClient, recipient, subject, body, mediaUrl, originator) { const params = { /* ... construct params object ... */ }; return await retry( async bail => { // bail(new Error('Stop retrying')) is used for non-recoverable errors try { console.log(`Attempting to send MMS (retry attempt)...`); const result = await mbClient.messages.create(params); console.log('MessageBird API Success (after retry logic).'); return result; } catch (error) { console.warn(`Attempt failed: ${error.message}. Evaluating retry...`); // Only retry on potentially transient errors (5xx, network issues) // Bail on client errors (4xx) like invalid recipient/key/rate limits const statusCode = error.statusCode || (error.errors && error.errors[0] && error.errors[0].code); // Don't retry on 4xx errors (client errors) or specific known non-retryable errors if (statusCode && statusCode >= 400 && statusCode < 500) { bail(new Error(`Non-retryable client error (${statusCode}): ${error.message}`)); } // For 5xx errors or network issues, throw to trigger retry throw error; } }, { retries: 3, // Number of retries factor: 2, // Exponential factor minTimeout: 1000, // Initial delay (ms) randomize: true, // Add jitter onRetry: (error, attempt) => { console.warn(`Retrying MMS send: attempt ${attempt} due to error: ${error.message}`); } } ); } -
Caution: Only retry idempotent operations (sending the same MMS multiple times should ideally have the same effect as sending it once, though billing might occur per attempt). Be cautious retrying operations that could cause duplicate actions if the initial request did succeed but the response was lost. MessageBird's API is generally safe for retrying sends if you use a unique
reference.
-
6. Database Schema and Data Layer (Optional for this Guide)
For this specific guide focused only on sending a single MMS via API, a database is not strictly required. However, in a real-world application, you would likely need a database to:
- Track Message Status: Store the
idreturned by MessageBird and use webhooks (see MessageBird docs) to receive status updates (sent, delivered, failed) and update your database accordingly. - Store User Data: Link sent messages to users in your system.
- Manage Media: Store information about media files used.
- Audit Logs: Keep a persistent record of messages sent.
If adding a database:
- Schema: You might have tables like
MmsMessages(message_id(PK),messagebird_id(unique),recipient,originator,subject,body,media_url,status,submitted_at,last_updated_at,reference,user_id(FK)). - Technology: Choose a database (e.g., PostgreSQL, MySQL, MongoDB) and an ORM/Query Builder (e.g., Sequelize, Prisma, TypeORM, Knex.js) to interact with it from Node.js.
- Data Layer: Implement repository or data access object (DAO) patterns to abstract database operations.
- Migrations: Use tools like
Sequelize CLIorPrisma Migrateto manage database schema changes over time.
7. Security Features
Securing your API endpoint and credentials is vital.
-
Input Validation and Sanitization:
- Validation: We implemented basic validation (
validateSendMmsRequest). Crucially, use a dedicated library likeexpress-validatorfor production. It provides robust validators (e.g.,isMobilePhone(locale, { strictMode: true }),isURL(),isLength()) and sanitizers. - Sanitization: While less critical for data being sent to an external API like MessageBird (as they handle their own processing), always sanitize any user-provided input that might be stored in your database or reflected back in responses to prevent XSS or other injection attacks if you extend the application. Libraries like
express-validatoralso offer sanitizers (trim(),escape()).
- Validation: We implemented basic validation (
-
Protect API Keys:
- Already addressed using
.envand.gitignore. - Production: Use your hosting provider's mechanism for managing secrets (e.g., Heroku Config Vars, AWS Secrets Manager, Docker secrets). Never hardcode keys.
- Already addressed using
-
Rate Limiting:
-
Prevent abuse and brute-force attacks by limiting the number of requests a client can make to your API endpoint within a certain time frame.
-
Implementation: Use middleware like
express-rate-limit.bashnpm install express-rate-limitjavascript// In server.js const rateLimit = require('express-rate-limit'); const apiLimiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 100, // Limit each IP to 100 requests per windowMs standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers legacyHeaders: false, // Disable the `X-RateLimit-*` headers message: 'Too many requests from this IP, please try again after 15 minutes', }); // Apply the rate limiting middleware to API routes // Apply specifically to /send-mms or globally if preferred app.use('/send-mms', apiLimiter);
-
-
Authentication/Authorization (Beyond this Guide):
- Currently, the
/send-mmsendpoint is open. In a real application, you would protect it. - Strategies: API Keys for server-to-server communication, JWT (JSON Web Tokens) for user-authenticated sessions, OAuth for third-party access. Implement middleware to verify credentials before allowing access to the endpoint.
- Currently, the
-
HTTPS:
- Always run your Express application behind a reverse proxy (like Nginx or Caddy) or use a hosting provider (like Heroku, Vercel) that terminates SSL/TLS, ensuring all communication is encrypted via HTTPS.
8. Handling Special Cases (MessageBird MMS Specifics)
Be aware of MessageBird's constraints and requirements for MMS. Source: MessageBird MMS API Documentation (verified 2024).
- Country Restrictions: Currently, MessageBird only supports sending MMS within the US and Canada. The
originatornumber must be a US or Canadian MMS-enabled VMN (Virtual Mobile Number). Sending to numbers outside these countries will fail. - Required Parameters: Per the API specification, you must provide EITHER
body(text) ORmediaUrls(array of media URLs), or both. At least one must be present for a valid MMS request. Theoriginatorandrecipientsare always required. - Maximum Recipients: Per request, a maximum of 50 recipients can be entered in the recipients array.
- Media URL Accessibility: The
mediaUrlsprovided must point to publicly accessible resources. MessageBird's servers need to fetch the content from these URLs. Private URLs or those behind firewalls will not work. - Media Fetch Timeout: MessageBird attempts to fetch media within approximately 5 seconds. Slow-responding URLs may cause the media attachment to fail.
- File Size Limit: Each media attachment must be 1MB (1,024 KB) or less. This is a per-file limit, not a cumulative limit. Larger files will result in an error.
- Number of Attachments: You can include up to 10 media attachments in the
mediaUrlsarray per message. - Supported Media Types: The following MIME types are officially supported as MMS attachments (verified from MessageBird API documentation):
- Audio:
audio/basic,audio/L24,audio/mp4,audio/mpeg,audio/ogg,audio/vorbis,audio/vnd.rn-realaudio,audio/vnd.wave,audio/3gpp,audio/3gpp2,audio/ac3,audio/webm,audio/amr-nb,audio/amr - Video:
video/mpeg,video/mp4,video/quicktime,video/webm,video/3gpp,video/3gpp2,video/3gpp-tt,video/H261,video/H263,video/H263-1998,video/H263-2000,video/H264 - Image:
image/jpeg,image/gif,image/png,image/bmp - Text:
text/vcard,text/csv,text/rtf,text/richtext,text/calendar - Application:
application/pdf
- Audio:
- Character Limits:
subject: Maximum 256 characters (UTF-8).body: Maximum 2,000 characters (UTF-8).
- Originator Requirements: Must be an MMS-enabled Virtual Mobile Number (VMN) from MessageBird in E.164 format (e.g.,
+12025551234). Alphanumeric sender IDs are not supported for MMS. - Recipient Format: Must be a valid mobile number in E.164 format (e.g.,
+16505551234). - VMN Requirement: Sending and receiving MMS is only possible if the VMN (Virtual Mobile Number) is explicitly MMS-enabled. Verify this in your MessageBird Numbers dashboard.
9. Performance Optimizations
For this specific task (a single API call), major performance tuning is less critical than reliability, but consider these points for scaling:
- Asynchronous Operations: Node.js is asynchronous by nature. Our use of
async/awaitensures that the server isn't blocked while waiting for the MessageBird API response, allowing it to handle other requests concurrently. - SDK Client Initialization: Initialize the MessageBird client once when the application starts, rather than on every request, to avoid unnecessary overhead.
- Payload Size: Keep request/response payloads reasonably sized. Avoid sending excessively large data in requests or responses if not needed.
- Logging Performance: In high-traffic scenarios, excessive synchronous logging (
console.log) can impact performance. Use asynchronous loggers (provided by libraries like Pino/Winston). - Load Testing: Use tools like
k6,Artillery, orApacheBench (ab)to simulate traffic to your/send-mmsendpoint and identify bottlenecks under load. Monitor CPU, memory, and response times. - Node.js Clustering: For CPU-bound tasks or to better utilize multi-core processors, use Node.js's built-in
clustermodule or a process manager likePM2in cluster mode to run multiple instances of your application.
10. Monitoring, Observability, and Analytics
Understanding how your service performs and identifying issues requires monitoring.
- Health Checks: The
/healthendpoint provides a basic mechanism for load balancers or monitoring services (like UptimeRobot, Pingdom) to check if the application instance is running. - Logging: Centralized logging (e.g., using ELK stack, Datadog Logs, Loggly) allows you to aggregate, search, and analyze logs from all instances of your application.
- Performance Metrics (APM): Application Performance Monitoring tools (e.g., Datadog APM, New Relic, Dynatrace) provide deep insights into request latency, throughput, error rates, and transaction traces, helping pinpoint performance issues within your Node.js code and interactions with external services like MessageBird.
- Error Tracking: Services like Sentry, Bugsnag, or Rollbar capture unhandled exceptions and errors in real-time, providing stack traces, context, and alerting, which is invaluable for debugging production issues.
- MessageBird Dashboard: Monitor your MessageBird usage, delivery rates, and costs directly within the MessageBird dashboard. Utilize their reporting and analytics features.
- Alerting: Configure alerts based on metrics (e.g., high error rate on
/send-mms, high API latency, low health check success rate) or logs (e.g., specific error messages) using your monitoring or error tracking tools.
11. Troubleshooting and Caveats
Common issues you might encounter:
-
Error:
Authentication failed(MessageBird API)- Cause: Invalid or incorrect
MESSAGEBIRD_API_KEY. - Solution: Verify the API key in your
.envfile matches the Live access key in your MessageBird dashboard (Developers -> API access). Ensure there are no typos or extra spaces and that you replaced the placeholder.
- Cause: Invalid or incorrect
-
Error:
recipient is invalidorInvalid parameters(pointing to recipient)- Cause: The recipient number is not in the correct E.164 format (e.g., missing
+or country code) or is not a valid mobile number. - Solution: Ensure recipient numbers are passed with a leading
+and country code (e.g.,+16505551234). Use validation (express-validator'sisMobilePhone) to check the format before sending.
- Cause: The recipient number is not in the correct E.164 format (e.g., missing
-
Error:
originator is invalidorOriginator not allowed for this country- Cause: The
MESSAGEBIRD_ORIGINATORnumber in your.envfile is incorrect, not MMS-enabled, not a valid US/Canadian number for MMS sending, or the placeholder was not replaced. - Solution: Double-check the originator number in your MessageBird dashboard (Numbers). Ensure it's MMS-enabled and correctly formatted (E.164). Verify it matches the value in
.env.
- Cause: The
-
Error:
media_url is invalid or inaccessibleorMedia download failed- Cause: The
mediaUrlprovided is not public, incorrect, timed out during fetch (longer than ~5s), or points to a resource MessageBird couldn't access. - Solution: Verify the URL is correct and publicly accessible (try opening it in an incognito browser window). Ensure the hosting server is responsive.
- Cause: The
-
Error:
File size exceeds limitor similar related to media size/type- Cause: The file at
mediaUrlis larger than 1MB or is not a supported media type. - Solution: Ensure the media file meets MessageBird's size and type requirements (see Section 8).
- Cause: The file at
-
MMS Not Received:
- Cause: Could be carrier filtering, incorrect recipient number, temporary network issues, or MessageBird delays.
- Solution:
- Verify the recipient number is correct and active.
- Check the MessageBird dashboard logs for the specific message status (
idreturned in the API response). Look forsent,buffered,delivered, ordelivery_failedstatuses. - Wait a few minutes, as delivery can sometimes be delayed.
- Ensure your
originatornumber is correctly configured for MMS and replaced in.env. - Test with a different recipient number or carrier if possible.
-
Caveats:
- MMS is US/Canada only via MessageBird at this time.
- Delivery is not guaranteed and depends on downstream carriers.
- Costs: Sending MMS messages incurs costs. Check MessageBird's pricing.
- Content: Carrier filtering can block messages based on content or perceived spam. Avoid overly promotional language or suspicious links.
12. Deployment and CI/CD
Deploy your Node.js application to production.
-
Environment Configuration:
- Crucial: Never commit your
.envfile. Production environments require setting environment variables (MESSAGEBIRD_API_KEY,MESSAGEBIRD_ORIGINATOR,NODE_ENV=production,PORT) through the hosting provider's interface or system environment variables. Ensure the actual keys/numbers are used, not placeholders. - Set
NODE_ENV=productionto enable Express optimizations and potentially disable verbose logging or development features.
- Crucial: Never commit your
-
Hosting Options:
- PaaS (Platform as a Service): Heroku, Vercel (for serverless functions), Render, Google App Engine, AWS Elastic Beanstalk. These simplify deployment by managing infrastructure.
- IaaS (Infrastructure as a Service): AWS EC2, Google Compute Engine, DigitalOcean Droplets. Require more manual setup (OS, Node.js, reverse proxy like Nginx/Caddy, process manager).
- Containers: Dockerize your application and deploy using services like Docker Hub, AWS ECS/EKS, Google Kubernetes Engine (GKE).
-
Process Manager:
- Use a process manager like
PM2orNodemon(for development) to keep your application running, manage restarts on crashes, handle clustering, and facilitate zero-downtime reloads. - Example (
PM2):bashnpm install pm2 -g # Start the app pm2 start server.js --name messagebird-mms-api # Monitor pm2 monit # List processes pm2 list
- Use a process manager like
-
Build Step (If Applicable):
- If using TypeScript or a build tool, ensure your deployment process includes the build step (
npm run build) before starting the application.
- If using TypeScript or a build tool, ensure your deployment process includes the build step (
-
CI/CD Pipeline:
- Automate testing, building, and deployment using tools like GitHub Actions, GitLab CI/CD, Jenkins, CircleCI.
- Typical Steps:
- Push code to repository.
- CI server triggers: Installs dependencies (
npm ci), runs linters/formatters, runs tests (npm test). - If tests pass: Build the application (if needed).
- Deploy: Push the build artifact or code to the hosting provider, restart the application using the process manager.
-
Reverse Proxy (Recommended for IaaS/Containers):
- Set up Nginx or Caddy in front of your Node.js application to:
- Handle SSL/TLS termination (HTTPS).
- Perform load balancing if running multiple instances.
- Serve static assets efficiently.
- Implement caching or basic security rules.
- Set up Nginx or Caddy in front of your Node.js application to:
Frequently Asked Questions
What is MMS and how is it different from SMS?
MMS (Multimedia Messaging Service) allows you to send messages with media attachments (images, videos, audio, PDFs) alongside text, while SMS (Short Message Service) is limited to plain text only. MMS provides richer communication capabilities for marketing campaigns, notifications with images, and multimedia content delivery.
Which countries does MessageBird support for MMS?
MessageBird currently supports MMS sending only in the United States and Canada. Your originator number must be a US or Canadian MMS-enabled Virtual Mobile Number (VMN) purchased from MessageBird.
What file types can I send via MessageBird MMS?
MessageBird supports 34+ MIME types including:
- Images: JPEG, GIF, PNG, BMP
- Videos: MP4, QuickTime, WebM, MPEG, H.264
- Audio: MP3, MP4, OGG, WAV, AMR
- Documents: PDF, vCard, CSV
Each attachment must be 1 MB or less, and you can include up to 10 attachments per message.
How do I get a MessageBird API key?
Log in to your MessageBird Dashboard, navigate to Developers → API access, and click Add access key. Choose a Live key for production use. Store this key securely in your .env file and never commit it to version control.
What's the maximum message size for MMS via MessageBird?
The character limits are:
- Subject line: 256 characters (UTF-8)
- Message body: 2,000 characters (UTF-8)
- Media files: 1 MB per attachment (up to 10 attachments)
How do I handle MMS delivery failures?
Implement error handling in your code to catch MessageBird API errors. Check the error.errors array for detailed error descriptions. Common failures include invalid phone numbers (use E.164 format), inaccessible media URLs, files exceeding 1 MB, or unsupported media types. Use the message ID returned by the API to track delivery status via MessageBird's dashboard or webhooks.
Can I schedule MMS messages for later delivery?
Yes, use the scheduledDatetime parameter in RFC3339 format (e.g., 2025-12-31T10:30:00+00:00) when calling the MessageBird API. This allows you to queue messages for future delivery.
What Node.js version should I use with MessageBird SDK?
The MessageBird Node.js SDK (v4.0.1) is compatible with Node.js 12.x and higher. For production applications, use the latest LTS (Long Term Support) version of Node.js for optimal security and performance.
How do I test MMS sending without incurring costs?
MessageBird does not offer a free sandbox for MMS testing – all MMS messages sent incur charges. Consider:
- Testing with a small number of messages to your own phone
- Using SMS for initial development (cheaper)
- Implementing thorough unit tests for your code logic without actual API calls
What's the difference between body and mediaUrls parameters?
Per MessageBird's API specification, you must provide either body (text content) or mediaUrls (array of media file URLs), or both. At minimum, one must be present. An MMS with only media and no text is valid, as is one with only text (though that's essentially an SMS).
Summary
You've built a complete Node.js Express application for sending MMS messages via MessageBird's API. This implementation includes:
- Modular architecture with separated service and API layers
- Input validation and comprehensive error handling
- Security best practices including environment variable management and rate limiting
- Production-ready features like retry mechanisms, logging, and monitoring guidelines
- MessageBird MMS specifications including supported media types, file size limits, and country restrictions
The application is ready for deployment and can be extended with features like database integration, webhook handling for delivery status updates, and authentication/authorization for production use.
For additional resources, consult the MessageBird API Documentation and the MessageBird Node.js SDK repository.