Frequently Asked Questions
First, create a Next.js app and an API route file at 'src/app/api/infobip-webhook/route.ts'. Then, set up environment variables in '.env.local', including your Infobip credentials and a webhook secret. This API route will handle incoming SMS messages from Infobip.
The webhook URL format is your deployed app's public URL plus the API route path. For example: 'https://your-app-domain.com/api/infobip-webhook'. Use ngrok for local testing.
Basic Authentication secures your webhook by requiring a username and password. This prevents unauthorized access and ensures only Infobip can send data to your endpoint. You'll set the password to match your 'INFOBIP_WEBHOOK_SECRET'.
Use Prisma if you need to store incoming SMS messages for later analysis, history tracking, or to manage stateful conversations. The article provides a schema example for storing message data.
Yes, you can use ngrok to create a temporary public URL that forwards requests to your local development server. This allows you to test the integration before deployment.
Secure your webhook with Basic Authentication by setting the 'Authorization' header in your requests. The username is often your API Key ID or a designated string, while the password is your 'INFOBIP_WEBHOOK_SECRET'. Verify the exact username Infobip requires.
The webhook expects a JSON payload with 'results', 'messageCount', and 'pendingMessageCount'. 'results' is an array of incoming messages, each containing details like 'messageId', 'from', 'to', 'text', and 'receivedAt'.
The provided code example iterates through the 'results' array in the webhook payload. Inside the loop, you can implement your logic to store the message, check for keywords, trigger replies, or enqueue for background processing.
Returning a 200 OK response promptly acknowledges successful receipt of the webhook to Infobip, preventing unnecessary retries. Do this even if internal processing encounters errors after authentication, but log such errors thoroughly.
The 'INFOBIP_WEBHOOK_SECRET' environment variable stores a secret string you generate. It acts as the password for Basic Authentication, securing your webhook. This secret must match the password configured in your Infobip webhook settings.
Implement robust error handling using try-catch blocks. For client-side errors, return 4xx status codes. For internal errors after successful authentication, return 200 OK to acknowledge receipt, but log the error for later investigation.
This integration uses Next.js for the app and API route, Node.js as the runtime, Infobip as the CPaaS provider, and optionally Prisma for database interaction and ngrok for local testing.
You'll need an active Infobip account, Node.js and npm/yarn installed, basic understanding of JavaScript and related technologies, and optionally a database and ngrok.
The article provides a Prisma schema example that includes fields for the sender, recipient, message text, timestamp, and more. You can adjust this schema based on your specific needs.
This guide provides a complete walkthrough for building a Next.js application capable of receiving and processing inbound SMS messages sent via the Infobip platform. By implementing a webhook endpoint, your application can handle replies, commands, or any incoming SMS traffic directed to your Infobip number, enabling true two-way messaging conversations.
We'll cover setting up your Next.js project, creating the API route to act as a webhook receiver, configuring Infobip to forward messages, handling basic security, processing incoming messages, storing them (optionally), and deploying the application.
Project Goals:
Technologies Used:
System Architecture:
Prerequisites:
1. Setting up the Project
Let's start by creating a new Next.js project and setting up the basic structure and environment variables.
Create a Next.js App: Open your terminal and run the following command, replacing
infobip-inbound-app
with your desired project name. We'll use TypeScript for better type safety.Follow the prompts (you can accept the defaults). This command sets up a new Next.js project using the App Router (
--app
), TypeScript, ESLint, and Tailwind CSS (optional but common).Navigate to Project Directory:
Set up Environment Variables: Create a file named
.env.local
in the root of your project. This file will store sensitive information like API keys and secrets. It's crucial not to commit this file to version control (it's included in the default.gitignore
created bycreate-next-app
).INFOBIP_BASE_URL
&INFOBIP_API_KEY
: Obtain these from your Infobip account dashboard. Needed if you extend the app to send SMS replies.INFOBIP_WEBHOOK_SECRET
: This is a secret you define. It acts as the password for Basic Authentication to secure your webhook endpoint. Configure this exact value in the Infobip portal (Section 4).DATABASE_URL
: Add this only if you plan to implement the database layer (Section 6). Adjust the format based on your chosen database.Project Structure: The
create-next-app
command with the--app
flag sets up the App Router structure. Our primary focus will be within thesrc/app/api/
directory where we'll create the webhook endpoint.2. Implementing the Core Functionality (Webhook Endpoint)
The core of this application is the API route that listens for incoming POST requests from Infobip.
Create the API Route File: Create a new file at
src/app/api/infobip-webhook/route.ts
. Next.js automatically maps files namedroute.ts
within theapp
directory structure to API endpoints. This file will handle requests made to/api/infobip-webhook
.Implement the Basic Handler: Add the following code to
src/app/api/infobip-webhook/route.ts
:InfobipWebhookPayload
/InfobipIncomingMessage
: Interfaces defining the expected data structure. Added a disclaimer to check official Infobip documentation.POST
Function: HandlesPOST
requests from Infobip.INFOBIP_WEBHOOK_SECRET
. Added notes about verifying the requiredusername
from Infobip's settings.req.json()
parses the incoming request body. Includes basic checks forbody.results
.results
array.200 OK
on successful receipt/processing. Returns401
for auth failures,400
for invalid JSON. Recommended200 OK
for internal processing errors after receipt to avoid unnecessary retries, but includes comments on the500
alternative.3. Understanding the API Layer Contract
The API route
src/app/api/infobip-webhook/route.ts
serves as the API layer for receiving inbound SMS. Here's a summary of its contract:Endpoint:
POST /api/infobip-webhook
POST
method is expected to receive message data.GET
or other methods should return405 Method Not Allowed
.Authentication: Basic Authentication
Authorization: Basic <credentials>
header.<credentials>
part is a Base64 encoded string ofusername:password
.password
MUST be the value you set forINFOBIP_WEBHOOK_SECRET
.username
MUST be verified in your Infobip webhook configuration (it could be your API Key ID, a fixed string, or potentially ignored by Infobip if the password matches - confirm in their UI).Request Body (Expected from Infobip):
application/json
Response Body (Sent back to Infobip):
Testing with cURL: (Run your Next.js app locally, expose with
ngrok
, replace placeholders)(Remember: Verify the exact
YOUR_USERNAME
required by checking your Infobip webhook configuration settings.)4. Integrating with Infobip
This is where you configure Infobip to send incoming SMS messages to your newly created webhook endpoint.
Obtain Infobip Credentials (If Sending Replies):
.env.local
file (INFOBIP_API_KEY
,INFOBIP_BASE_URL
). Your Base URL looks something likexxxxx.api.infobip.com
.Configure Inbound Message Routing (Webhook): The exact steps can vary slightly based on Infobip's UI updates, but generally involve:
https://your-app-domain.com/api/infobip-webhook
. During local development, you'll use anngrok
URL (see Section 13 - Note: Section 13 was not provided in the original text, refer to testing sections).InfobipWebhook
. Enter what Infobip requires here.INFOBIP_WEBHOOK_SECRET
in your.env.local
file.Environment Variables Summary:
INFOBIP_BASE_URL
(Optional for receiving): The base domain for API calls (e.g.,xxxxx.api.infobip.com
). Needed for sending.INFOBIP_API_KEY
(Optional for receiving): Your secret API key. Needed for sending.INFOBIP_WEBHOOK_SECRET
: The password you define and set in both.env.local
and the Infobip webhook Basic Auth configuration. Used by your webhook handler to verify requests. Required for secure receiving.DATABASE_URL
(Optional): Connection string for your database. Needed if storing messages.5. Implementing Error Handling and Logging
Robust error handling and logging are vital for production applications.
Error Handling Strategy:
try...catch
blocks to capture errors during request processing (parsing, validation, business logic).400 Bad Request
for malformed JSON or invalid payload structures. Return401 Unauthorized
for failed authentication. Return405 Method Not Allowed
for incorrect HTTP methods. These indicate client-side issues (Infobip sending invalid data or incorrect configuration on either side).200 OK
to acknowledge receipt to Infobip and prevent retries for potentially persistent internal issues. Log the error clearly so you can investigate.500 Internal Server Error
might be unavoidable, potentially triggering Infobip retries.Logging: While
console.log
works for development, use a structured logging library likepino
orwinston
for production.src/lib/logger.ts
:debug
,info
,warn
,error
).info
level in production due to volume and potential PII; usedebug
if necessary.Retry Mechanisms (Infobip Side):
2xx
response within a timeout period (e.g., a few seconds).200 OK
after authentication and basic validation.200 OK
.5xx
may trigger Infobip retries (check their docs for policy). Use this response code sparingly_ as recommended above.6. Creating a Database Schema and Data Layer (Optional)
Storing incoming messages enables history tracking_ analysis_ and stateful conversations. We'll use Prisma.
Install Prisma:
Initialize Prisma:
This creates a
prisma
directory with aschema.prisma
file and updates.env.local
with a placeholderDATABASE_URL
. Ensure your.env.local
has the correctDATABASE_URL
.Define Schema: Edit
prisma/schema.prisma
:Apply Schema Migrations:
migrate dev
_ but can be run manually:Implement Data Access in Webhook:
src/lib/prisma.ts
):