code examples
code examples
Send MMS Messages with Infobip, Node.js, and Next.js: Complete Guide
Learn how to send MMS messages using Infobip API and Node.js SDK in Next.js applications. Step-by-step guide with code examples, security best practices, and error handling.
Send MMS Messages with Infobip, Node.js, and Next.js
This comprehensive guide shows you how to send MMS (Multimedia Messaging Service) messages using the Infobip API with their official Node.js SDK in a Next.js application. You'll learn to build a serverless API route that securely handles MMS sending with images, videos, or audio alongside text messages.
This approach enables you to add powerful MMS capabilities – like sending images, videos, or audio alongside text – directly from your web application, ideal for notifications, marketing campaigns, or enhanced user communication.
Project Overview and Goals
Goal: To create a Next.js application with a serverless API route that securely sends MMS messages via the Infobip platform.
Problem Solved: Provides a robust, server-side mechanism to send MMS messages without exposing sensitive API credentials on the client-side. Leverages Infobip's infrastructure for reliable message delivery.
Technologies:
- Next.js: React framework for building the frontend UI and API routes (serverless Node.js functions). Chosen for its hybrid rendering capabilities and simplified API creation.
- Node.js: JavaScript runtime environment used by Next.js API routes.
- Infobip: Communications Platform as a Service (CPaaS) provider. We'll use their API and Node.js SDK for sending MMS. Chosen for its specific MMS capabilities and developer tooling.
@infobip-api/sdk: The official Infobip Node.js SDK for interacting with their API.
Architecture Flow:
- User Browser: Initiates an HTTPS Request to the Next.js Frontend.
- Next.js Frontend: Makes an API Call (
/api/send-mms) to the Next.js API Route. - Next.js API Route: Uses the Infobip SDK to call the Infobip MMS API.
- Infobip MMS API: Sends the MMS message to the Recipient's Mobile Device.
- Next.js API Route: Returns an API Response to the Next.js Frontend.
- Next.js Frontend: Updates the UI based on the response for the User Browser.
Prerequisites:
- Node.js v14 or later (v18+ recommended for Next.js 15.x) and npm/yarn installed.
- Next.js 13.4+ for App Router support (this guide uses Next.js 15.x).
- An active Infobip account. Create a free trial account if you don't have one.
- Your Infobip API Key and Base URL (obtained from the Infobip portal dashboard).
- A publicly accessible URL for media files. Supported formats: JPEG, PNG, GIF (images); MP3, MP4 (audio/video). Infobip servers must be able to fetch this URL without authentication.
- Recipient phone numbers in E.164 format (ITU-T standard):
+[country code][subscriber number], maximum 15 digits total (e.g.,+14155552671). - For trial accounts: messages can typically only be sent to your registered phone number.
Outcome: A functional Next.js application where a user can input a recipient phone number, a media URL, and text, then click a button to send an MMS message via Infobip.
1. Setting up the Project
Let's initialize a new Next.js project and install the necessary dependencies.
-
Create a new Next.js App: Open your terminal and run the following command. Choose your preferred settings when prompted (e.g., TypeScript: No, ESLint: Yes, Tailwind CSS: No,
src/directory: No, App Router: Yes, Import alias:@/*).bashnpx create-next-app@latest infobip-mms-nextjs -
Navigate into the Project Directory:
bashcd infobip-mms-nextjs -
Install Infobip Node.js SDK: This package provides a convenient wrapper around the Infobip API.
bashnpm install @infobip-api/sdk -
Set up Environment Variables: Create a file named
.env.localin the root of your project. This file stores sensitive credentials securely and should not be committed to version control.plaintext# .env.local INFOBIP_API_KEY=YOUR_INFOBIP_API_KEY INFOBIP_BASE_URL=YOUR_INFOBIP_BASE_URL INFOBIP_SENDER_NUMBER=YOUR_INFOBIP_VIRTUAL_NUMBER # Optional, if you have a specific number- Replace
YOUR_INFOBIP_API_KEYandYOUR_INFOBIP_BASE_URLwith the actual values from your Infobip account dashboard (see Section 4 for details). - Replace
YOUR_INFOBIP_VIRTUAL_NUMBERwith a number you've acquired through Infobip if you want to specify the sender ID. If omitted or using a trial account, Infobip might assign a sender number. - Why
.env.local? Next.js automatically loads variables from this file intoprocess.envon the server-side (API routes) but not on the client-side, preventing accidental exposure of your API Key.
- Replace
-
Add
.env.localto.gitignore: Ensure your.gitignorefile (in the project root) includes.env.localto prevent committing secrets. It's usually included by default increate-next-app.text# .gitignore # ... other entries .env*.local
2. Implementing the API Route
We'll create a serverless API route within Next.js to handle the logic for sending the MMS message. This keeps your Infobip credentials secure on the server.
-
Create the API Route File: Create the following directory structure and file if it doesn't exist:
app/api/send-mms/route.js. -
Implement the API Logic: Paste the following code into
app/api/send-mms/route.js.javascript// app/api/send-mms/route.js import { NextResponse } from 'next/server'; import { Infobip, AuthType } from '@infobip-api/sdk'; // Initialize Infobip client const infobip = new Infobip({ baseUrl: process.env.INFOBIP_BASE_URL, apiKey: process.env.INFOBIP_API_KEY, authType: AuthType.ApiKey, }); export async function POST(request) { console.log('Received request to /api/send-mms'); try { const body = await request.json(); const { to, mediaUrl, text } = body; // --- Input Validation --- if (!to || !mediaUrl || !text) { console.error('Validation Error: Missing required fields'); return NextResponse.json( { success: false, error: 'Missing required fields: to, mediaUrl, text' }, { status: 400 } ); } // Basic phone validation (can be enhanced) const phoneRegex = /^(\+)?\d{10,15}$/; if (!phoneRegex.test(to)) { console.error('Validation Error: Invalid phone number format'); return NextResponse.json( { success: false, error: 'Invalid phone number format. Use E.164 format (e.g., +14155552671).' }, { status: 400 } ); } // Basic URL validation try { new URL(mediaUrl); // Check if mediaUrl is a valid URL format } catch (_) { console.error('Validation Error: Invalid media URL'); return NextResponse.json( { success: false, error: 'Invalid media URL format.' }, { status: 400 } ); } // --- End Input Validation --- const senderNumber = process.env.INFOBIP_SENDER_NUMBER || 'InfoSMS'; // Use configured number or default alpha sender console.log(`Attempting to send MMS to: ${to} from: ${senderNumber}`); console.log(`Media URL: ${mediaUrl}, Text: ${text}`); // --- Call Infobip API --- const response = await infobip.channels.mms.send({ messages: [ { destinations: [{ to: to }], from: senderNumber, content: { mediaUrl: mediaUrl, text: text, }, }, ], }); console.log('Infobip API Response:', JSON.stringify(response.data, null, 2)); // Check Infobip response status (can be more granular based on Infobip docs) if (response.status >= 200 && response.status < 300 && response.data.messages?.[0]?.status?.groupName !== 'REJECTED') { return NextResponse.json({ success: true, data: response.data }); } else { console.error('Infobip API Error:', response.data); return NextResponse.json( { success: false, error: 'Failed to send MMS via Infobip', details: response.data }, { status: response.status || 500 } // Use Infobip's status or default to 500 ); } } catch (error) { console.error('API Route Error:', error); // Distinguish between Infobip SDK errors and other errors if (error.response) { // Error from Infobip API (e.g., bad request, auth error) console.error('Infobip API Error Details:', error.response.data); return NextResponse.json( { success: false, error: 'Infobip API request failed', details: error.response.data }, { status: error.response.status || 500 } ); } else { // Other server error (e.g., network issue, code bug) return NextResponse.json( { success: false, error: 'Internal Server Error' }, { status: 500 } ); } } }Explanation:
- Import Dependencies:
NextResponsefor sending responses and theInfobipclient andAuthTypefrom the SDK. - Initialize Client: Creates an
Infobipinstance using the API Key and Base URL from your environment variables.AuthType.ApiKeyspecifies the authentication method. POSTHandler: This function handles incoming POST requests to/api/send-mms.- Parse Request Body: Extracts
to,mediaUrl, andtextfrom the incoming JSON request. - Input Validation: Performs basic checks: presence of required fields, plausible E.164 phone format using regex, and valid URL format. Returns a
400 Bad Requestif validation fails. Note: The phone regex is basic; for production, consider a more robust library likelibphonenumber-json the backend as well for stricter E.164 validation. - Set Sender: Uses the number from
.env.localor a default alphanumeric sender ID ('InfoSMS'). Note: Alphanumeric sender IDs might have restrictions depending on the destination country. Using a purchased number is often more reliable for deliverability and branding (see Section 4). - Call Infobip SDK: Uses
infobip.channels.mms.send()to send the message. The payload structure follows the Infobip API requirements for MMS. Note: SDK methods can change; always refer to the current official@infobip-api/sdkdocumentation for the exact method signatures and payload structures. - Log Responses: Logs the request details and the response from the Infobip API for debugging.
- Handle Response: Checks the HTTP status and the message status group from the Infobip response. Returns a success (
200 OK) or error JSON response (4xxor5xx) to the frontend. - Error Handling (
try...catch): Catches potential errors during the process. It differentiates between errors originating from the Infobip API itself (e.g., invalid credentials, malformed request) and other unexpected server errors, returning appropriate status codes and messages.
- Import Dependencies:
3. Building the Frontend Interface
Now, let's create a simple React component on a Next.js page to collect user input and trigger our API route.
-
Modify the Home Page: Replace the contents of
app/page.jswith the following code:jsx// app/page.js 'use client'; // Required for useState and event handlers import { useState } from 'react'; import styles from './page.module.css'; // Optional: for basic styling export default function HomePage() { const [to, setTo] = useState(''); const [mediaUrl, setMediaUrl] = useState(''); const [text, setText] = useState(''); const [statusMessage, setStatusMessage] = useState(''); const [isLoading, setIsLoading] = useState(false); const handleSubmit = async (event) => { event.preventDefault(); setIsLoading(true); setStatusMessage('Sending MMS...'); try { const response = await fetch('/api/send-mms', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ to, mediaUrl, text }), }); const result = await response.json(); if (response.ok && result.success) { setStatusMessage(`MMS sent successfully! Message ID: ${result.data?.messages?.[0]?.messageId || 'N/A'}`); // Clear form on success setTo(''); setMediaUrl(''); setText(''); } else { console.error('API Error Response:', result); setStatusMessage(`Failed to send MMS: ${result.error || 'Unknown error'}. ${result.details ? JSON.stringify(result.details) : ''}`); } } catch (error) { console.error('Frontend Fetch Error:', error); setStatusMessage(`An error occurred: ${error.message}`); } finally { setIsLoading(false); } }; return ( <main className={styles.main}> <h1>Send Infobip MMS</h1> <form onSubmit={handleSubmit} className={styles.form}> <div className={styles.formGroup}> <label htmlFor=""to"">Recipient Number (E.164):</label> <input type=""tel"" id=""to"" value={to} onChange={(e) => setTo(e.target.value)} placeholder=""+14155552671"" required disabled={isLoading} /> </div> <div className={styles.formGroup}> <label htmlFor=""mediaUrl"">Media URL (Publicly Accessible):</label> <input type=""url"" id=""mediaUrl"" value={mediaUrl} onChange={(e) => setMediaUrl(e.target.value)} placeholder=""https://example.com/image.jpg"" required disabled={isLoading} /> </div> <div className={styles.formGroup}> <label htmlFor=""text"">Message Text:</label> <textarea id=""text"" value={text} onChange={(e) => setText(e.target.value)} rows=""3"" required disabled={isLoading} ></textarea> </div> <button type=""submit"" disabled={isLoading}> {isLoading ? 'Sending...' : 'Send MMS'} </button> </form> {statusMessage && ( <p className={styles.statusMessage}>{statusMessage}</p> )} </main> ); } -
(Optional) Add Basic Styling: Create a file
app/page.module.cssfor some basic layout:css/* app/page.module.css */ .main { display: flex; flex-direction: column; align-items: center; padding: 2rem; min-height: 100vh; font-family: sans-serif; } .form { display: flex; flex-direction: column; gap: 1rem; width: 100%; max-width: 400px; margin-top: 1.5rem; } .formGroup { display: flex; flex-direction: column; } .formGroup label { margin-bottom: 0.5rem; font-weight: bold; } .formGroup input, .formGroup textarea { padding: 0.75rem; border: 1px solid #ccc; border-radius: 4px; font-size: 1rem; } .formGroup textarea { resize: vertical; } .form button { padding: 0.75rem 1.5rem; background-color: #0070f3; color: white; border: none; border-radius: 4px; font-size: 1rem; cursor: pointer; transition: background-color 0.2s ease; } .form button:hover:not(:disabled) { background-color: #005bb5; } .form button:disabled { background-color: #ccc; cursor: not-allowed; } .statusMessage { margin-top: 1.5rem; padding: 1rem; border-radius: 4px; background-color: #f0f0f0; border: 1px solid #ddd; width: 100%; max-width: 400px; text-align: center; word-wrap: break-word; }Explanation:
'use client': Marks this component as a Client Component, necessary for using hooks likeuseStateand handling browser events.- State Variables:
useStatemanages the input field values (to,mediaUrl,text), loading state (isLoading), and status messages (statusMessage). handleSubmit:- Prevents default form submission.
- Sets loading state and initial status message.
- Uses
fetchto send aPOSTrequest to our/api/send-mmsendpoint. - Sends the form data as a JSON string in the request body.
- Parses the JSON response from the API route.
- Updates the
statusMessagebased on success or failure, including the Message ID on success or error details on failure. - Clears the form fields on success.
- Includes error handling for the
fetchcall itself (e.g., network errors). - Resets loading state in the
finallyblock.
- Form: Standard HTML form elements bound to the React state variables. The submit button is disabled while the request is in progress.
- Status Display: Renders the
statusMessageparagraph conditionally.
4. Integrating with Infobip – Getting Credentials
To connect your application to Infobip, you need your API Key and Base URL.
- Log in to Infobip: Go to the Infobip Portal and log in.
- Find API Key:
- Navigate to the homepage/dashboard after login.
- Look for a section usually titled ""API Keys"" or similar. You might see a default key or have the option to create a new one.
- Copy the API Key. This is the value for
INFOBIP_API_KEYin your.env.localfile.
- Find Base URL:
- On the same dashboard or in the API documentation section, find your personalized Base URL. It often looks like
xxxxx.api.infobip.com. - Copy this URL. This is the value for
INFOBIP_BASE_URLin your.env.localfile.
- On the same dashboard or in the API documentation section, find your personalized Base URL. It often looks like
- Get a Sender Number (Optional but Recommended):
- Navigate to the ""Numbers"" section in the Infobip portal.
- Acquire a virtual number capable of sending MMS in the regions you target.
- Copy this number (usually in E.164 format, e.g.,
+14155550100). This is the value forINFOBIP_SENDER_NUMBERin your.env.localfile. - Why use a purchased number? Using a dedicated virtual number generally improves message deliverability, helps avoid carrier filtering associated with shared or generic IDs, builds brand recognition, and may be required for certain features or regions.
- Secure Storage: Ensure these values are only placed in your
.env.localfile and that this file is listed in your.gitignore. Never commit these credentials directly into your code.
5. Error Handling and Logging
Our API route includes basic error handling, but here's how to think about it more broadly:
-
API Route (
route.js):- Input Validation: Catches invalid request formats early (missing fields, bad phone/URL format). Returns
400 Bad Request. - Infobip SDK Errors: The
try...catchblock specifically catches errors thrown by the@infobip-api/sdk. These often contain detailed error information from Infobip (like authentication failure, invalid destination number, insufficient funds) inerror.response.dataand a status code inerror.response.status. We log this detail server-side and return a relevant status code (4xxor5xx) with a generic error message plus details to the client. - Infobip Success with Failure Status: We check
response.data.messages[0].status.groupNamebecause Infobip might return a200 OKHTTP status but indicate message rejection within the payload (e.g.,REJECTED). - General Server Errors: Catches any other unexpected errors (network issues connecting to Infobip, internal code bugs) and returns a
500 Internal Server Error. - Logging:
console.logandconsole.errorare used for basic logging. For production, consider structured logging libraries likepinoorwinstonto format logs better and send them to dedicated logging services (e.g., Datadog, Logtail, Sentry).
- Input Validation: Catches invalid request formats early (missing fields, bad phone/URL format). Returns
-
Frontend (
page.js):- Fetch Errors: Catches network errors preventing the request from reaching the API route.
- API Response Handling: Checks
response.okand thesuccessflag in the JSON payload to determine if the API call itself succeeded. Displays user-friendly messages based on the API response, including error details if provided.
-
Retry Mechanisms: For transient errors (e.g., temporary network issues, Infobip rate limits - often indicated by
429or5xxstatus codes), you could implement a retry strategy in the API route. This typically involves catching specific error types/codes and retrying theinfobip.channels.mms.sendcall after a delay, often with exponential backoff (e.g., wait 1s, then 2s, then 4s). Libraries likeasync-retrycan simplify this. However, be cautious: do not retry errors that indicate permanent failure (e.g., invalid number, insufficient funds, message rejected due to content,4xxerrors other than rate limits) to avoid duplicate sends or unnecessary cost. Identify retryable error codes based on Infobip's documentation or API responses.
6. Database Schema and Data Layer (Not Applicable Here)
This specific guide focuses solely on the action of sending an MMS and does not require a database.
If you were building a larger application (e.g., storing message history, user preferences, campaign data), you would:
- Choose a Database: PostgreSQL, MySQL, MongoDB, etc.
- Define Schema: Create tables/collections (e.g.,
messagestable with columns likeinfobip_message_id,recipient_number,sender_number,status,media_url,text_content,sent_at,updated_at). Use an ORM like Prisma or Sequelize for easier database interaction and migrations. - Implement Data Access: Create functions or repository classes in your backend (potentially separate from the API route handler) to insert/update message records before/after calling the Infobip API.
- Migrations: Use the ORM's migration tools (
prisma migrate dev,sequelize db:migrate) to manage schema changes.
7. Adding Security Features
Security is paramount, especially when handling API keys and user data.
- API Key Security:
- Server-Side Only: The API Key is stored in
.env.localand only accessed within the server-side API route. It's never exposed to the client browser. .gitignore: Ensure.env.localis in.gitignore.- Environment Variables in Deployment: Use your hosting provider's mechanism for securely managing environment variables (e.g., Vercel Environment Variables, AWS Secrets Manager).
- Server-Side Only: The API Key is stored in
- Input Validation and Sanitization:
- The API route performs basic validation (required fields, phone number format using regex, URL format check).
- For production, consider more robust validation libraries (e.g.,
zod,joi) to define schemas for expected request bodies. - While not directly applicable here as we aren't storing text long-term or rendering it as HTML, always sanitize user input if it's ever displayed back or stored, to prevent XSS attacks.
- Rate Limiting:
- Protect your API route from abuse. Implement rate limiting based on IP address or user session (if authentication is added).
- Hosting platforms like Vercel offer built-in rate limiting.
- Alternatively, use middleware with libraries like
rate-limiter-flexibleorexpress-rate-limit(if using a custom Node/Express server).
- Authentication/Authorization (Beyond this guide): If only specific logged-in users should send MMS, implement authentication (e.g., NextAuth.js, Clerk) and check user permissions within the API route before proceeding.
- HTTPS: Next.js development server and platforms like Vercel use HTTPS by default, encrypting data in transit. Ensure this is maintained in production.
8. Handling Special Cases
- Phone Number Formatting: Infobip expects numbers in E.164 format (e.g.,
+14155552671). The frontend could include a library likelibphonenumber-jsfor more robust parsing and validation before sending to the backend. The backend validation provides a safety net. - Media URL Accessibility: The
mediaUrlmust be publicly accessible without authentication for Infobip's servers to fetch it. If using private storage (like AWS S3), generate a pre-signed URL with a short expiry time just before calling the Infobip API. - Media File Types/Size: Infobip has limitations on supported media types (e.g., JPEG, PNG, GIF, MP3, MP4) and file sizes. Refer to the official Infobip MMS documentation for specifics. Handle potential errors if an unsupported type or oversized file is provided.
- Character Limits: While MMS is less restrictive than SMS, there might still be practical limits on text length depending on carriers. Keep text concise.
- International Sending: Be aware of country-specific regulations and potential differences in sender ID support (alphanumeric vs. numeric). Test thoroughly if sending internationally.
- Delivery Reports (Webhooks): For production, set up Infobip webhooks to receive real-time delivery status updates (e.g., delivered, failed, rejected) for sent messages. This requires creating another API endpoint in your Next.js app to receive these webhook POST requests from Infobip and update your message status accordingly (likely in a database).
9. Performance Optimizations (Limited Scope Here)
For this specific function, performance is primarily dependent on the Infobip API's response time.
- API Route Performance: Next.js API routes on platforms like Vercel are generally performant serverless functions. Ensure your validation logic is efficient.
- SDK Initialization: The Infobip client is initialized once when the API route module loads, which is efficient.
- Frontend: Standard React/Next.js optimizations apply (memoization, code splitting - handled by Next.js). The main wait time for the user is the network roundtrip to your API route and then to Infobip.
- Caching: Caching is not directly applicable to the sending action itself.
If sending MMS messages becomes a bottleneck in a high-traffic application:
- Asynchronous Processing: Instead of waiting for the Infobip API call in the API route, you could push the send request into a message queue (e.g., Redis Queue, RabbitMQ, AWS SQS) and have a separate background worker process the queue and call Infobip. The API route would return an immediate ""accepted"" response to the user. This adds complexity but improves responsiveness.
10. Monitoring, Observability, and Analytics
- Logging: As mentioned in Section 5, use structured logging and send logs to a central service for analysis and alerting (e.g., alert on a spike in
5xxerrors from the API route). - Error Tracking: Integrate services like Sentry or Bugsnag to capture and aggregate errors occurring in both the frontend and the API route.
- Health Checks: Create a simple health check endpoint (e.g.,
/api/health) that returns200 OKif the basic application is running. Monitoring services can ping this. - Performance Metrics: Hosting platforms (Vercel, Netlify) often provide basic metrics like function duration, invocation count, and error rates for API routes.
- Infobip Analytics: Utilize the analytics and reporting features within the Infobip portal to track message delivery rates, costs, and trends. Correlate
messageIdorbulkIdfrom the API response with Infobip reports. - Custom Dashboards: If using a database to store message status, build dashboards (e.g., using Grafana, Retool, or your logging platform's tools) to visualize send volume, success rates by country/carrier, error types, etc.
11. Troubleshooting and Caveats
- Error: Invalid API Key/Base URL:
- Symptom: API route returns
401 Unauthorizedor similar authentication errors. Logs show Infobip API error related to credentials. - Solution: Double-check
INFOBIP_API_KEYandINFOBIP_BASE_URLin your.env.localand ensure they are correctly configured in your deployment environment. Verify the key is active in the Infobip portal.
- Symptom: API route returns
- Error: Invalid Destination Number:
- Symptom: API route returns an error (
400 Bad Requestor similar), Infobip response details indicate an invalid 'to' number. - Solution: Ensure the number is in the correct E.164 format (including
+and country code). Verify the number is valid and capable of receiving MMS. If using a trial account, ensure it's the registered number.
- Symptom: API route returns an error (
- Error: Media URL Not Accessible / Invalid:
- Symptom: Message fails to send, Infobip logs/webhooks might indicate a media fetching error.
- Solution: Verify the
mediaUrlis publicly accessible (try opening it in an incognito browser window). Ensure it points directly to the media file, not an HTML page. Check Infobip's supported file types and size limits.
- Error: Insufficient Funds (Paid Accounts):
- Symptom: Infobip API returns an error related to account balance.
- Solution: Check your account balance in the Infobip portal.
- Message Sent (API Success) but Not Received:
- Check Infobip Logs/Analytics: Use the
messageIdreturned by the API to track the message status in the Infobip portal. Look for detailed delivery reports or error codes (e.g., carrier rejection, blocked number). - Check Sender ID: Ensure the
fromnumber or sender ID is correctly configured and permitted for the destination country/carrier. - Carrier Issues: Temporary carrier delays or filtering can occur.
- Trial Account Limitation: Remember the restriction of sending only to the registered number on trial accounts.
- Check Infobip Logs/Analytics: Use the
- Environment Variables Not Loaded:
- Symptom:
process.env.INFOBIP_API_KEYisundefinedin the API route. Application crashes or fails authentication. - Solution: Ensure the file is named exactly
.env.local. Restart the Next.js development server (npm run dev) after creating or modifying the file. Verify environment variables are correctly set in your deployment environment.
- Symptom:
- Caveat: MMS Costs: MMS messages are typically more expensive than SMS. Monitor costs in the Infobip portal.
- Caveat: Regional Regulations: MMS sending is subject to local laws and carrier rules (e.g., content restrictions, opt-in requirements). Ensure compliance.
12. Deployment and CI/CD
Deploying a Next.js application is typically straightforward.
Deployment Platforms (e.g., Vercel, Netlify):
- Connect Git Repository: Link your GitHub, GitLab, or Bitbucket repository to the platform.
- Configure Build Settings: Usually auto-detected for Next.js. Default settings are often sufficient.
- Set Environment Variables: Crucially, add
INFOBIP_API_KEY,INFOBIP_BASE_URL, andINFOBIP_SENDER_NUMBER(if used) to the platform's environment variable settings (usually found under Project Settings > Environment Variables). Mark them as sensitive if the option exists. Do not commit.env.local. - Deploy: Trigger a deployment. The platform will build your Next.js app and deploy the frontend and API routes.
CI/CD Pipeline (e.g., GitHub Actions):
- Workflow File: Create a
.github/workflows/deploy.ymlfile. - Trigger: Define triggers (e.g.,
on: push: branches: [ main ]). - Jobs:
- Checkout Code: Use
actions/checkout@v3. - Set up Node.js: Use
actions/setup-node@v3. - Install Dependencies: Run
npm cioryarn install --frozen-lockfile. - Build: Run
npm run build. - Deploy: Use a platform-specific action (e.g., Vercel CLI Action, Netlify CLI Action) or standard deployment tools (e.g.,
rsync,scp, Docker push) depending on your hosting.
- Checkout Code: Use
- Secrets: Store
INFOBIP_API_KEY,INFOBIP_BASE_URL, etc., as encrypted secrets in your GitHub repository settings (Settings > Secrets and variables > Actions) and reference them in your workflow file using${{ secrets.YOUR_SECRET_NAME }}. Inject these into your deployment step as environment variables.
Rollback: Deployment platforms usually offer easy rollback capabilities to previous successful deployments through their UI or CLI. CI/CD pipelines can be configured to trigger rollbacks on failure or manually.
Frequently Asked Questions (FAQ)
Q: What is the difference between SMS and MMS?
A: SMS (Short Message Service) is limited to text-only messages up to 160 characters. MMS (Multimedia Messaging Service) supports rich media including images, videos, audio files, and longer text messages. MMS is ideal when you need to send visual content alongside text for marketing, notifications, or enhanced communication.
Q: What Node.js version is required for the Infobip SDK?
A: The @infobip-api/sdk requires Node.js v14 or later. For Next.js 15.x applications, Node.js v18 or later is recommended for optimal compatibility and performance.
Q: Why must phone numbers be in E.164 format?
A: E.164 is the ITU-T international telephone numbering standard that ensures globally unique phone numbers. The format +[country code][subscriber number] (max 15 digits) allows Infobip to correctly route messages to any carrier worldwide. Without the + prefix and country code, messages may fail or be delivered incorrectly.
Q: What media file formats does Infobip MMS support?
A: Infobip supports JPEG, PNG, and GIF for images; MP3 for audio; and MP4 for video files. The media must be hosted at a publicly accessible URL that Infobip servers can fetch without authentication. Check the official Infobip documentation for current file size limits.
Q: Can I send MMS messages from a trial Infobip account?
A: Yes, but trial accounts typically have restrictions. You can usually only send messages to the phone number you registered with during account creation. To send to multiple recipients, you'll need to upgrade to a paid account.
Q: How do I handle MMS delivery failures?
A: Implement webhook endpoints to receive delivery reports from Infobip in real-time. Check the status.groupName in API responses for immediate feedback. Common failures include invalid phone numbers, inaccessible media URLs, insufficient account balance, or carrier rejections. Use the messageId to track status in the Infobip portal.
Q: What's the cost difference between SMS and MMS?
A: MMS messages are typically 3-10x more expensive than SMS due to the data-intensive nature of multimedia content. Pricing varies by destination country and carrier. Monitor costs in your Infobip portal and set up usage alerts to avoid unexpected charges.
Q: Why should I use Next.js API routes instead of calling Infobip directly from the frontend?
A: Next.js API routes run server-side, keeping your Infobip API credentials secure and never exposing them to client browsers. Direct frontend calls would expose your API key in the browser, allowing anyone to send messages using your account and incurring charges.
Q: Can I use alphanumeric sender IDs for MMS?
A: Alphanumeric sender IDs (e.g., "YourBrand") have varying support depending on the destination country and carrier. Many regions require numeric sender IDs or registered virtual numbers for MMS. Using a dedicated virtual number purchased through Infobip generally provides better deliverability and compliance.
Q: How do I test my MMS implementation without sending real messages?
A: Use Infobip's trial account to send test messages to your registered number. For automated testing, consider mocking the Infobip SDK responses in your test suite. Infobip also provides sandbox environments for some endpoints - check their documentation for availability.
Frequently Asked Questions
How to send MMS messages with Next.js and Infobip?
You can send MMS messages by creating a Next.js app with a serverless API route that uses the Infobip API and Node.js SDK. This setup allows you to securely send multimedia messages like images and videos without exposing your API key on the client side.
What is the Infobip Node.js SDK used for?
The Infobip Node.js SDK (`@infobip-api/sdk`) simplifies interaction with the Infobip API from your Node.js backend. It provides methods for sending various message types, including MMS, handling responses, and managing authentication.
Why use a server-side API route for sending MMS?
Using a server-side API route protects your sensitive API credentials (like your Infobip API key) by keeping them on the server. Client-side JavaScript is easily visible, making it unsuitable for storing secrets.
When should I use a purchased virtual number for sending MMS?
While you might be able to use a default or alphanumeric sender ID, a purchased virtual number is strongly recommended, especially for production. It improves deliverability and branding and is often required for certain features or countries. This gives a more professional touch to your messages and may increase their reach.
Can I send MMS to any number with an Infobip trial account?
Trial accounts on Infobip typically have restrictions, often limiting sending to the phone number used for registration. Check the specific terms of your trial account. Upgrading to a paid account usually removes these limitations.
How to set up environment variables for Infobip in Next.js?
Create a `.env.local` file in your project's root directory and store your `INFOBIP_API_KEY`, `INFOBIP_BASE_URL`, and optionally `INFOBIP_SENDER_NUMBER` there. Next.js loads these into `process.env` on the server side. Add this file to your `.gitignore` to prevent exposing secrets in version control.
What is the correct phone number format for sending MMS via Infobip?
Infobip expects phone numbers in E.164 format, which includes the `+` sign and the country code (e.g., +14155552671). The provided code includes basic validation for phone number format
How to handle errors when sending MMS with Infobip?
The provided example code demonstrates detailed error handling. It catches errors from both the Infobip API and the overall process, returning appropriate status codes and informative messages. Server-side logs are crucial for debugging. Use tools like structured logging libraries for better insights into the issues that occur.
Where can I find my Infobip API Key and Base URL?
Log in to the Infobip portal ([https://portal.infobip.com/](https://portal.infobip.com/)). Your API Key and Base URL are typically available on the main dashboard or in the API Keys section. Your personalized base URL might take a format similar to xxxxx.api.infobip.com
What media types and sizes are supported for MMS messages?
Infobip has limits on file types (e.g., JPEG, PNG, GIF, MP3, MP4) and sizes for MMS. Check the official Infobip MMS documentation ([https://www.infobip.com/docs/api/channels/mms/send-mms-message](https://www.infobip.com/docs/api/channels/mms/send-mms-message)) for the latest details on supported media and any restrictions.
How do I make my media file accessible to Infobip for MMS sending?
The media URL you provide must be publicly accessible by Infobip's servers. If you're using private storage (like Amazon S3), generate a pre-signed URL with a short expiry time before sending it to Infobip, allowing secure and temporary access to the content.
How to troubleshoot if the MMS message is not received despite API success?
Several factors can cause this. Start by using the `messageId` from the Infobip API response to check the message status in the Infobip portal or logs. Look at delivery reports for potential carrier rejections or verify the sender ID is valid. If using a trial account, ensure the number is among your permitted destinations.
How to improve performance of MMS sending?
For this example, the key bottleneck is the Infobip API response time. In more complex, higher-traffic applications, consider using a message queue for asynchronous processing and decoupling the send action from the user request, thereby enhancing the user experience.
What are some best practices for MMS security with Infobip?
Key best practices include storing the API key only server-side, always using HTTPS, implementing robust input validation on the backend, and potentially adding rate limiting and authentication to protect your application.