code examples
code examples
WhatsApp Business API Integration with Next.js and Infobip: Complete Guide
Build a Next.js application with Infobip WhatsApp Business API integration. Learn to send/receive messages, configure webhooks, and implement security best practices for WhatsApp messaging.
WhatsApp Business API Integration with Next.js and Infobip
Integrate Infobip's WhatsApp Business API into a Next.js application. This guide covers environment setup, API endpoints for sending WhatsApp messages using the Infobip Node.js SDK, frontend implementation, and webhook configuration for receiving incoming messages.
Build a functional Next.js application that sends text messages via WhatsApp through Infobip and handles inbound messages, creating the foundation for conversational applications.
Project Overview and Goals
What We're Building:
A Next.js application that includes:
- An API route (
/api/send-whatsapp) that accepts a phone number and message text, then uses the Infobip SDK to send a WhatsApp message. - A simple frontend page with a form to trigger the API route.
- An API route (
/api/whatsapp-webhook) to receive incoming message notifications from Infobip.
Problem Solved:
Enables developers to programmatically send and receive WhatsApp messages, automating notifications, customer support interactions, alerts, and communication workflows directly from Next.js applications.
Technologies Used:
- Next.js: React framework for full-stack web applications (v13+ with App Router required). Uses API routes for backend logic.
- Node.js: Runtime environment (v18.x or v20.x LTS required).
- TypeScript: For static typing and improved developer experience.
- Infobip: Communications Platform as a Service (CPaaS) offering WhatsApp Business API.
@infobip-api/sdk: Official Infobip Node.js SDK for API interaction.dotenv: For secure environment variable management.
System Architecture:
<!-- Mermaid diagram visualizing system architecture was removed for standard Markdown compatibility -->(Ensure your rendering environment supports Mermaid diagrams for the above visualization)
Prerequisites:
- Node.js v18.x or v20.x LTS and npm/yarn installed.
- Active Infobip account (create free trial).
- Approved WhatsApp Sender number configured in your Infobip account (verification can take 1-3 business days).
- Basic React, Next.js, and REST API knowledge.
ngrokor similar tunneling service (localtunnel, Cloudflare Tunnels) for local webhook testing, or staging environment with public URL.- WhatsApp Business Account: Must complete Infobip's WhatsApp Business verification process before sending messages.
Setting Up the Project
Initialize a new Next.js project and install dependencies.
-
Create a Next.js App: Run this command to create a Next.js project with TypeScript:
bashnpx create-next-app@latest infobip-whatsapp-nextjs --typescriptAccept defaults or configure ESLint, Tailwind CSS,
src/directory, and App Router. This guide assumessrc/directory and App Router (Next.js 13+). -
Navigate to Project Directory:
bashcd infobip-whatsapp-nextjs -
Install Dependencies: Install the Infobip SDK and
dotenvfor environment variables.bashnpm install @infobip-api/sdk dotenvor using yarn:
bashyarn add @infobip-api/sdk dotenv -
Configure Environment Variables: Create
.env.localin the project root. This file stores Infobip credentials securely. Never commit this file to version control.dotenv# .env.local # Get from Infobip Portal -> API Keys Management INFOBIP_API_KEY=YOUR_INFOBIP_API_KEY # Get from Infobip Portal -> API Keys Management (or main dashboard) INFOBIP_BASE_URL=YOUR_INFOBIP_BASE_URL # Your registered WhatsApp sender number from Infobip (e.g., 447860099299) INFOBIP_WHATSAPP_SENDER=YOUR_WHATSAPP_SENDER_NUMBER # A secret token you define for verifying incoming webhooks (CRITICAL for production) INFOBIP_WEBHOOK_SECRET=YOUR_CUSTOM_SECRET_STRING- Finding
INFOBIP_API_KEYandINFOBIP_BASE_URL: Log in to Infobip. Navigate to API Keys (usually in developer settings or dashboard). Generate a new API key if needed. Your Base URL appears here (typicallyxxxxx.api.infobip.com). - Finding
INFOBIP_WHATSAPP_SENDER: This is the phone number registered and connected to WhatsApp Business API through Infobip. Find it under "Channels and Numbers" or "WhatsApp" section. Note: WhatsApp Business Account verification typically takes 1-3 business days. INFOBIP_WEBHOOK_SECRET: Choose a strong, random string. Use this when configuring webhooks in Infobip portal and implement signature verification in your webhook handler (Sections 4 & 7) to ensure requests are genuinely from Infobip.
- Finding
-
Update
.gitignore: Ensure.env.localis in.gitignoreto prevent committing secrets. Default Next.js.gitignoreusually includes it.text# .gitignore # ... other entries .env*.local
Implementing Core Functionality: Sending Messages
Create an API route that handles sending WhatsApp messages via the Infobip SDK.
-
Create the API Route File: Create a new file at
src/app/api/send-whatsapp/route.ts. -
Implement the Sending Logic: Paste this code into
src/app/api/send-whatsapp/route.ts:typescript// src/app/api/send-whatsapp/route.ts import { NextRequest, NextResponse } from 'next/server'; import { Infobip, AuthType } from '@infobip-api/sdk'; // Load environment variables const INFOBIP_API_KEY = process.env.INFOBIP_API_KEY; const INFOBIP_BASE_URL = process.env.INFOBIP_BASE_URL; const INFOBIP_WHATSAPP_SENDER = process.env.INFOBIP_WHATSAPP_SENDER; // Basic check for environment variables if (!INFOBIP_API_KEY || !INFOBIP_BASE_URL || !INFOBIP_WHATSAPP_SENDER) { console.error("Infobip environment variables are missing!"); // In a real app, you might want more robust handling or prevent startup } // Instantiate Infobip client (consider memoization in high-traffic/serverless environments // to avoid redundant initializations on subsequent requests and improve performance) let infobip: Infobip | null = null; if (INFOBIP_API_KEY && INFOBIP_BASE_URL) { infobip = new Infobip({ baseUrl: INFOBIP_BASE_URL, apiKey: INFOBIP_API_KEY, authType: AuthType.ApiKey, }); } export async function POST(request: NextRequest) { if (!infobip) { return NextResponse.json( { success: false, error: "Infobip client not initialized. Check environment variables." }, { status: 500 } ); } try { const body = await request.json(); const { to, message } = body; // Basic input validation if (!to || !message) { return NextResponse.json( { success: false, error: 'Missing "to" or "message" in request body' }, { status: 400 } ); } // Validate E.164 format: Optional '+', then 1-15 digits total (country code + number) // E.164 standard: country code (1-3 digits) + subscriber number, max 15 digits total // Examples: +14155552671, 447123456789 const e164Regex = /^\+?\d{1,15}$/; if (!e164Regex.test(to)) { return NextResponse.json( { success: false, error: 'Invalid "to" phone number format. Use E.164 format (1-15 digits total, e.g., +14155552671 or 447123456789).' }, { status: 400 } ); } console.log(`Sending WhatsApp message to: ${to} from: ${INFOBIP_WHATSAPP_SENDER}`); const response = await infobip.channels.whatsapp.send({ type: 'text', from: INFOBIP_WHATSAPP_SENDER, // Your registered Infobip WhatsApp sender to: to, // Recipient phone number (E.164 format) content: { text: message, // The message text }, // Optional: Add messageId for tracking, callbackData, etc. // messageId: `my-unique-msg-id-${Date.now()}`, // notifyUrl: 'YOUR_DELIVERY_REPORT_WEBHOOK_URL' // For delivery reports }); console.log('Infobip API Response:', response); return NextResponse.json({ success: true, data: response }); } catch (error: any) { console.error('Error sending WhatsApp message:', error); // Provide more specific error feedback if possible const errorMessage = error.response?.data?.requestError?.serviceException?.text || error.message || 'Failed to send message'; const statusCode = error.response?.status || 500; return NextResponse.json( { success: false, error: errorMessage }, { status: statusCode } ); } } // Optional: Add a GET handler or other methods if needed export async function GET() { return NextResponse.json({ message: "Send POST request to /api/send-whatsapp with { to: 'phoneNumber', message: 'your message' }" }); }Explanation:
- Imports necessary modules from
next/serverand@infobip-api/sdk. - Loads environment variables using
process.envwith basic presence checks. - Creates
Infobipclient instance using API Key and Base URL. Memoization comment explains potential optimization. POSThandler receivesNextRequest.- Parses JSON body for
tophone number andmessagetext. - Validates required fields.
- Corrected E.164 validation: Regex now checks for 1-15 digits total (not 11-15), matching actual E.164 standard where country code is 1-3 digits and total number length is maximum 15 digits.
- Calls
infobip.channels.whatsapp.send()with required parameters. - Logs and returns Infobip API response.
try...catchhandles errors, logging and returning appropriate status codes.
- Imports necessary modules from
Building a Simple Frontend
Create a basic React component to interact with the API endpoint.
-
Modify the Homepage: Open
src/app/page.tsxand replace content with:tsx// src/app/page.tsx 'use client'; // Required for components with hooks like useState, useEffect import React, { useState } from 'react'; export default function HomePage() { const [phoneNumber, setPhoneNumber] = useState(''); const [message, setMessage] = useState(''); const [status, setStatus] = useState(''); // To display success/error messages const [isLoading, setIsLoading] = useState(false); const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => { event.preventDefault(); setIsLoading(true); setStatus(''); // Clear previous status try { const response = await fetch('/api/send-whatsapp', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ to: phoneNumber, // Send raw phone number, backend will validate E.164 message: message, }), }); const result = await response.json(); if (response.ok && result.success) { const messageId = result.data?.messages?.[0]?.messageId || 'N/A'; setStatus(`Message sent successfully! Message ID: ${messageId}`); setPhoneNumber(''); // Clear fields on success setMessage(''); } else { setStatus(`Error: ${result.error || 'Failed to send message'}`); } } catch (error: any) { console.error('Frontend fetch error:', error); setStatus(`Error: ${error.message || 'An unexpected error occurred.'}`); } finally { setIsLoading(false); } }; return ( <div style={{ maxWidth: '500px', margin: '50px auto', padding: '20px', border: '1px solid #ccc', borderRadius: '8px' }}> <h1>Send WhatsApp Message via Infobip</h1> <form onSubmit={handleSubmit}> <div style={{ marginBottom: '15px' }}> <label htmlFor="phoneNumber" style={{ display: 'block', marginBottom: '5px' }}> Recipient Phone Number (E.164 format): </label> <input type="tel" id="phoneNumber" value={phoneNumber} onChange={(e) => setPhoneNumber(e.target.value)} required placeholder="e.g., +14155552671 or 447123456789" style={{ width: '100%', padding: '8px', boxSizing: 'border-box' }} /> </div> <div style={{ marginBottom: '15px' }}> <label htmlFor="message" style={{ display: 'block', marginBottom: '5px' }}> Message: </label> <textarea id="message" value={message} onChange={(e) => setMessage(e.target.value)} required rows={4} style={{ width: '100%', padding: '8px', boxSizing: 'border-box' }} /> </div> <button type="submit" disabled={isLoading} style={{ padding: '10px 20px', cursor: isLoading ? 'not-allowed' : 'pointer' }} > {isLoading ? 'Sending...' : 'Send Message'} </button> </form> {status && ( <p style={{ marginTop: '20px', color: status.startsWith('Error') ? 'red' : 'green' }}> {status} </p> )} </div> ); }Explanation:
'use client'marks this as Client Component for using hooks.- State variables manage form inputs and feedback.
handleSubmitprevents default form action, sets loading state, makesfetchrequest to/api/send-whatsapp.- Raw phone number sent; backend handles E.164 validation.
htmlForattributes match corresponding inputidattributes.try...catchhandles errors, logging and returning appropriate status codes.
Integrating with Infobip: Receiving Messages (Webhook)
Configure a webhook to receive incoming WhatsApp messages. Infobip sends HTTP POST requests to your URL when messages arrive.
-
Create the Webhook API Route File: Create a new file at
src/app/api/whatsapp-webhook/route.ts. -
Implement the Webhook Handler: Paste this code into
src/app/api/whatsapp-webhook/route.ts:typescript// src/app/api/whatsapp-webhook/route.ts import { NextRequest, NextResponse } from 'next/server'; import crypto from 'crypto'; const INFOBIP_WEBHOOK_SECRET = process.env.INFOBIP_WEBHOOK_SECRET; // --- IMPORTANT: Webhook Signature Verification Function --- // Verify with Infobip documentation for exact implementation details: // - Header name (commonly X-Hub-Signature-256 or X-Infobip-Signature) // - Algorithm (SHA256, SHA1, etc.) // - Encoding (hex, base64) // Consult: https://www.infobip.com/docs/api (search "webhook security") async function verifyInfobipSignature(request: NextRequest, secret: string): Promise<boolean> { // Check Infobip docs for correct header name const signatureHeader = request.headers.get('X-Infobip-Signature'); if (!signatureHeader) { console.warn('Missing signature header from Infobip webhook.'); return false; } try { const requestBody = await request.text(); // Check Infobip docs for correct algorithm (sha256? sha1?) const hash = crypto .createHmac('sha256', secret) .update(requestBody) .digest('hex'); // Check Infobip docs for correct encoding // Use timing-safe comparison const isValid = crypto.timingSafeEqual(Buffer.from(hash), Buffer.from(signatureHeader)); if (!isValid) { console.warn('Invalid webhook signature.'); } return isValid; } catch (error) { console.error('Error during signature verification:', error); return false; } } // --- End Verification Function --- export async function POST(request: NextRequest) { console.log('Received Infobip WhatsApp Webhook POST request'); // --- CRITICAL: Webhook Signature Verification --- // MUST implement for production security if (INFOBIP_WEBHOOK_SECRET) { const clonedRequest = request.clone(); const isValid = await verifyInfobipSignature(clonedRequest, INFOBIP_WEBHOOK_SECRET); if (!isValid) { console.error('Webhook signature verification failed!'); return NextResponse.json({ error: 'Invalid signature' }, { status: 403 }); } console.log('Webhook signature verified successfully.'); } else { console.warn('INFOBIP_WEBHOOK_SECRET not set. Skipping signature verification. INSECURE FOR PRODUCTION.'); } // --- End Verification --- try { const payload = await request.json(); console.log('Webhook Payload:', JSON.stringify(payload, null, 2)); // --- Process the Message --- // Payload structure depends on message type (text, media, location, etc.) // Messages typically under `payload.results` array if (payload.results && Array.isArray(payload.results)) { for (const message of payload.results) { if (message.from && message.message?.content?.text) { console.log(`Message from ${message.from}: ${message.message.content.text}`); // Add your logic: save to DB, trigger replies, etc. } // TODO: Handle other message types (media, location, etc.) // TODO: Implement idempotency checks (store message IDs) } } // --- End Processing --- // Return 200 OK quickly to acknowledge receipt // Infobip retries if no timely 200 response return NextResponse.json({ success: true, message: "Webhook received" }); } catch (error: any) { console.error('Error processing webhook:', error); return NextResponse.json({ success: false, error: 'Internal Server Error' }, { status: 500 }); } } // Infobip might send GET for validation (rare) export async function GET(request: NextRequest) { console.log('Received Infobip WhatsApp Webhook GET request (Validation?)'); return NextResponse.json({ message: "Webhook endpoint is active. Use POST for messages." }); }Explanation:
POSThandler receives incoming requests from Infobip.- Includes
verifyInfobipSignaturefunction for HMAC SHA256 signature verification using Node.jscrypto. This MUST be adapted based on Infobip's specific documentation for exact header name, algorithm, and encoding. - Verification is mandatory for production. Code warns if secret missing or verification fails.
- Reads request body after verification (using
request.json()). Verification reads from cloned request to avoid consuming stream. - Logs entire payload for inspection.
- Basic example iterates through
payload.resultsto extract sender and text content. Adapt based on Infobip's documented payload structure. - Critical: Return
200 OKpromptly to acknowledge receipt. Failure causes Infobip retries and potential duplicates. Implement idempotency by checking message IDs. - Error handling logs issues, returns generic 500 error.
-
Expose Local Endpoint (e.g., with
ngrok): Test webhook locally with public URL.-
Start Next.js dev server:
npm run dev(typically port 3000). -
In new terminal, run
ngrok:bashngrok http 3000 -
Copy public HTTPS URL (e.g.,
https://<random>.ngrok-free.app). -
Production Note: Use deployed URL (Vercel, Netlify) or permanent tunneling solution for staging.
-
-
Configure Webhook in Infobip Portal:
- Log in to Infobip.
- Navigate to "Channels and Numbers", find your WhatsApp sender, look for "Inbound Messages" or "Webhook Settings".
- Paste public HTTPS URL with API route path:
https://<your-public-url>/api/whatsapp-webhook. - Find "Secret" or "Signature Key" field. Paste exact
INFOBIP_WEBHOOK_SECRETvalue from.env.local. Required for signature verification. - Save configuration.
Verification and Testing
Now, let's test both sending and receiving messages.
-
Start the Application: If it's not already running, start your Next.js app:
bashnpm run dev -
Test Sending:
- Open your browser to
http://localhost:3000. - Enter a valid WhatsApp phone number (in E.164 format, e.g.,
+14155552671or447123456789) in the ""Recipient Phone Number"" field. You can use your own number for testing. - Enter a message in the ""Message"" field.
- Click ""Send Message"".
- Check the status message on the webpage.
- Verify that the message arrives on the recipient's WhatsApp account.
- Check your terminal running
npm run devfor logs from the/api/send-whatsapproute.
- Open your browser to
-
Test Receiving (Webhook):
- Using the WhatsApp account associated with the number you sent to in the previous step, reply to the message you received from your Infobip sender number.
- Watch the terminal window where
npm run devis running. You should see logs from the/api/whatsapp-webhookroute:- ""Received Infobip WhatsApp Webhook POST request""
- Potentially ""Webhook signature verified successfully."" (if secret is set and verification passes) or warnings/errors related to signature.
- The JSON payload of the incoming message.
- The log ""Message from [sender_number]: [message_text]"".
- You can also check the
ngrokweb interface (usuallyhttp://localhost:4040) or your tunneling tool's interface to inspect the incoming HTTP request details, including headers likeX-Infobip-Signature.
Error Handling, Logging, and Retries
- Error Handling: The provided API routes include basic
try...catchblocks. For production:- Implement more specific error handling based on Infobip's error codes/responses.
- Use a dedicated error tracking service (e.g., Sentry, Datadog).
- Validate inputs more robustly using libraries like
zodfor schema validation.
- Logging:
console.logis used for simplicity. For production:- Use a structured logging library (e.g., Pino, Winston) to output logs in JSON format.
- Adjust log levels (debug, info, warn, error).
- Ensure sensitive data (like full message content, if subject to privacy rules) is potentially masked or omitted from logs depending on requirements.
- Retries:
- Sending: The Infobip SDK might handle some transient network errors. For critical messages, consider implementing an application-level retry mechanism with exponential backoff, possibly using a job queue (e.g., BullMQ, or external queue systems) to handle failures gracefully without blocking the API response.
- Receiving (Webhook): Ensure your webhook handler is idempotent (processing the same message multiple times doesn't cause negative side effects), as Infobip will retry delivery if it doesn't receive a timely
200 OKor encounters network issues. Store message IDs (message.messageIdfrom the payload) and check for duplicates before processing critical actions.
Security Features
- Environment Variables: Keep API keys and secrets out of your codebase using
.env.localand ensure this file is in.gitignore. Use platform-specific environment variable management for deployment (e.g., Vercel Environment Variables, AWS Secrets Manager). - Input Validation: Sanitize and validate all inputs from the frontend (
to,message) and from webhooks. Use libraries likezodfor schema validation on API routes. - Webhook Security: Implementing and verifying the webhook signature is CRITICAL. The example code in Section 4 provides a conceptual implementation, but you must adapt it based on Infobip's specific documentation for the correct header name, algorithm, and encoding. Consult the Infobip documentation (search for webhook security or signature verification) for the precise method. Failure to do this leaves your webhook endpoint vulnerable.
- Rate Limiting: Protect your API endpoints (
/api/send-whatsapp,/api/whatsapp-webhook) from abuse by implementing rate limiting. Tools like@upstash/ratelimitor platform features (e.g., Vercel's IP blocking/rate limiting) can be used. - HTTPS: Always use HTTPS for your application and webhook URLs. Tunneling tools like
ngrokprovide this locally, and deployment platforms like Vercel handle it automatically.
Handling Special Cases (WhatsApp Specific)
- 24-Hour Window: WhatsApp imposes a 24-hour limit for free-form messages initiated by the business. After 24 hours since the user's last message, you can only send pre-approved Template Messages. The code above sends a standard text message (
type: 'text'), which only works within this window or as a reply to an incoming user message. Refer to Infobip's documentation on sending Template Messages for sending messages outside the window. You'll need to use a different payload structure (type: 'template') and provide the registered template name and placeholders. - Message Types: This guide focuses on text messages (
type: 'text'). Infobip supports various types (images, documents, audio, video, location, interactive messages like buttons and lists). Refer to the Infobip SDK documentation and API reference for payload structures for different types. - Opt-ins: Ensure you have proper user consent (opt-in) before initiating conversations or sending promotional messages via WhatsApp, complying with WhatsApp policies and local regulations (like GDPR, TCPA).
- Number Formatting: Always strive to use and validate the E.164 format for phone numbers (e.g.,
+14155552671,447123456789). This typically includes an optional+followed by the country code and the subscriber number, without spaces or dashes. Our validation regex (^\+?\d{1,15}$) enforces this structure.
Deployment and CI/CD
- Platform Choice: Vercel is a natural choice for deploying Next.js applications. Other options include Netlify, AWS Amplify, Render, or self-hosting with Node.js.
- Environment Variables: Configure your
INFOBIP_API_KEY,INFOBIP_BASE_URL,INFOBIP_WHATSAPP_SENDER, andINFOBIP_WEBHOOK_SECRETin your chosen platform's environment variable settings. Do not hardcode them. - Build Command: Typically
npm run buildoryarn build. - Webhook URL Update: Once deployed, update the webhook URL in the Infobip portal to point to your production URL (e.g.,
https://your-app-domain.com/api/whatsapp-webhook). Ensure the secret key is also correctly configured there. - CI/CD: Platforms like Vercel, Netlify, GitHub Actions, GitLab CI offer seamless Git integration for automatic deployments on push/merge to specific branches. Configure build steps and environment variables within the CI/CD pipeline.
- Rollback: Familiarize yourself with your deployment platform's rollback procedures (e.g., Vercel allows instantly promoting a previous deployment).
Troubleshooting and Caveats
- Missing Env Vars: Error ""Infobip client not initialized"" usually means
.env.localis missing, not loaded correctly, or the environment variables (INFOBIP_API_KEY,INFOBIP_BASE_URL) are misspelled or undefined in the current environment (especially check deployment environment variables). - Invalid Phone Number Format: Ensure the
tonumber in the send request strictly follows E.164 format (e.g.,+14155552671,447123456789). The API route includes validation, but double-check the input. - Webhook Not Receiving:
- Verify the public URL (
ngrokor deployed URL +/api/whatsapp-webhook) is correctly configured in the Infobip portal. - Ensure your local server (
npm run dev) or deployment is running. - Check
ngrok's web interface (http://localhost:4040) or your tunneling tool's logs for incoming requests. - Confirm your firewall isn't blocking incoming connections (less common with tunneling/deployment platforms).
- Verify the public URL (
- Webhook Signature Failure:
- Ensure the
INFOBIP_WEBHOOK_SECRETin your.env.local(and deployment environment) exactly matches the secret configured in the Infobip portal. - Double-check the header name (
X-Infobip-Signature?), hashing algorithm (sha256?), and encoding (hex?) used in theverifyInfobipSignaturefunction against Infobip's official documentation. The provided function is a template.
- Ensure the
- 400 Bad Request (Sending): Often due to missing
toormessagein the request body, or invalid phone number format. Check the API route's logs for specific error messages. - Infobip API Errors: Check the error response (
error.response?.data) logged in thecatchblock of the/api/send-whatsapproute for specific error details from Infobip (e.g., authentication failure, insufficient funds, invalid sender). - 24-Hour Window Exceeded: If sending fails outside the 24-hour window, you likely need to use pre-approved WhatsApp Template Messages instead of standard text messages.
Frequently Asked Questions (FAQ)
Q: What Next.js and Node.js versions are required? A: Next.js 13+ with App Router support and Node.js v18.x or v20.x LTS are required. Earlier versions lack current security patches and App Router features.
Q: How long does WhatsApp Business Account verification take? A: Infobip's WhatsApp Business Account verification typically takes 1-3 business days. You cannot send messages until verification completes.
Q: What is the WhatsApp 24-hour messaging window?
A: WhatsApp allows free-form messages only within 24 hours of the user's last message to your business. Outside this window, you can only send pre-approved Template Messages. This guide covers free-form text messages (type: 'text') valid within the 24-hour window.
Q: How do I send Template Messages outside the 24-hour window?
A: Use type: 'template' in your send request with a registered template name and parameters. Templates must be pre-approved by WhatsApp through Infobip. See Infobip's Template Message documentation.
Q: What phone number format does WhatsApp require?
A: Use E.164 international format: optional '+' followed by 1-15 digits total (country code + subscriber number). Examples: +14155552671 (US), 447123456789 (UK). The corrected regex validates this properly.
Q: Can I send media (images, videos, documents) via WhatsApp?
A: Yes. Infobip supports images, documents, audio, video, location, and interactive messages (buttons, lists). Change type parameter and provide appropriate content structure. See Infobip SDK documentation for payload formats.
Q: How do I verify the webhook signature?
A: The provided verifyInfobipSignature function is a template. Consult Infobip's webhook security documentation for exact header name, hashing algorithm, and encoding. Implementing this correctly is critical for production security.
Q: What are the rate limits for sending WhatsApp messages? A: Rate limits depend on your Infobip account tier and WhatsApp Business Account status. Newly verified accounts typically start with lower limits (80-1000 messages/24 hours) that increase based on quality and volume. Check Infobip dashboard for your specific limits.
Q: Do I need user consent to send WhatsApp messages? A: Yes. You must obtain proper user opt-in before initiating conversations or sending promotional messages. Comply with WhatsApp Business policies and local regulations (GDPR, TCPA, etc.).
Q: How do I handle webhook retries and duplicates?
A: Implement idempotency by storing processed message IDs (message.messageId from payload) in your database. Check IDs before processing to prevent duplicate actions. Infobip retries webhooks if it doesn't receive timely 200 OK responses.
Q: Can I test webhooks without deploying or using ngrok?
A: For local development, tunneling tools (ngrok, localtunnel, Cloudflare Tunnels) are necessary since Infobip requires publicly accessible HTTPS URLs. For persistent testing, deploy to staging environment (Vercel preview deployments work well).
Q: What's the difference between this and SMS integration? A: WhatsApp requires Business Account verification, supports richer media types, has the 24-hour window rule, requires Template Messages for proactive outreach, and typically offers better engagement rates. SMS has simpler setup, no 24-hour restrictions, but limited to 160-character text (or concatenated segments).
Q: How do I track message delivery status?
A: Add notifyUrl parameter to your send request with your delivery report webhook URL. Infobip sends POST requests to this URL with delivery status updates (sent, delivered, read, failed).
Q: Is this code production-ready?
A: This tutorial provides a foundation. For production, add: robust input validation (zod), comprehensive error handling, retry mechanisms with job queues, structured logging (Winston/Pino), monitoring (Datadog/Sentry), rate limiting, proper webhook signature verification per Infobip docs, and database for message tracking.
Frequently Asked Questions
How to send a WhatsApp message with Next.js?
Create an API route in your Next.js app that uses the Infobip SDK to send WhatsApp messages. This route should handle POST requests containing the recipient's phone number and the message content. The provided code example utilizes the '@infobip-api/sdk' and environment variables for secure credential management. A simple frontend form can then interact with this API route.
What is the Infobip WhatsApp Business API?
The Infobip WhatsApp Business API is a service provided by Infobip, a Communications Platform as a Service (CPaaS) provider. It enables developers to programmatically send and receive WhatsApp messages, integrating this communication channel directly into applications like the Next.js app demonstrated in this guide.
Why use Next.js for WhatsApp integration?
Next.js, a React framework, simplifies full-stack application development, making it an excellent choice for building a WhatsApp integration. It offers features like API routes for backend logic, server-side rendering, and a streamlined developer experience, as shown in the tutorial.
When should I use WhatsApp Template Messages with Infobip?
WhatsApp enforces a 24-hour window for free-form messages initiated by businesses. After this period, you must use pre-approved Template Messages. Consult Infobip's documentation for sending these messages, as they require a specific format ('type: 'template'') and pre-registered template names.
Can I receive WhatsApp messages in my Next.js app?
Yes, by setting up a webhook. Configure a dedicated API route in your Next.js app (e.g., '/api/whatsapp-webhook') and provide this URL to Infobip. They will send an HTTP POST request to this endpoint every time a message is received, triggering your handling logic. Be sure to implement robust security measures, especially webhook signature verification, to protect your application.
How to set up Infobip WhatsApp webhook in Next.js?
You'll need to create an API route in your Next.js application specifically to handle incoming webhook requests from Infobip. This route should parse the incoming message data and process it according to your application's needs, such as saving it to a database or triggering a reply. Critically, ensure that your implementation includes webhook signature verification to maintain security.
What is the E.164 format for phone numbers?
E.164 is an international standard for phone number formatting. It ensures consistent and unambiguous representation, generally consisting of a '+' followed by the country code and subscriber number, without any spaces or dashes. For instance, a US number would be formatted as +14155552671, and a UK number as +447123456789.
How to handle Infobip webhook signature verification?
Webhook signature verification is paramount for security. Consult Infobip's documentation for their exact specifications. The tutorial provides a template using Node.js's 'crypto' library involving HMAC SHA256 hashing. You'll need to confirm the header name (e.g., 'X-Infobip-Signature'), algorithm, and encoding with their official documentation.
What are the prerequisites for integrating Infobip WhatsApp with Next.js?
Before starting, you will need Node.js and npm/yarn installed. A crucial step is to set up environment variables for your Infobip API Key and Base URL, as outlined in the guide.
How to test Infobip WhatsApp integration locally?
Use a tool like ngrok to expose your local development server to the internet, providing a public URL for your webhook. This allows Infobip to send requests to your application during development. Send a test WhatsApp message through your application's frontend, and reply to that message from WhatsApp to test the inbound webhook functionality.
Where to find Infobip API key and base URL?
These credentials are located within your Infobip account portal. After logging in, navigate to the API Keys Management section (usually accessible from the Developer settings or main dashboard), where you can generate and manage your API key. Your Base URL is generally also displayed here.
What environment variables are needed for the Infobip integration?
You will need `INFOBIP_API_KEY`, `INFOBIP_BASE_URL`, `INFOBIP_WHATSAPP_SENDER`, and `INFOBIP_WEBHOOK_SECRET`. These should be stored in a `.env.local` file and never committed to version control.
Why is input validation important for WhatsApp messages?
Validating inputs protects your application from vulnerabilities and ensures that data is correctly formatted. The tutorial demonstrates basic validation for the recipient's phone number (E.164 format) and the presence of a message body, along with enhanced E.164 validation.
How to deploy a Next.js app with Infobip WhatsApp integration?
Platforms like Vercel are well-suited for Next.js deployments. Make sure to configure your environment variables on the chosen platform, update the webhook URL in the Infobip portal to your production URL after deployment, and consider setting up CI/CD for automated build and deployment processes.