Frequently Asked Questions
Use the Infobip Node.js SDK (@infobip-api/sdk) to send SMS messages. The `sendSms` function within the provided `infobipService.js` module handles constructing the API request and sending it to Infobip. Make sure you have your API key, base URL, and sender ID configured correctly in your .env file to initialize the Infobip client successfully.
The Infobip inbound SMS webhook sends a POST request with a JSON body containing message details. Key fields include `results[0].from` (sender's number), `results[0].text` (message content), `results[0].to` (your Infobip number), and `results[0].messageId`. The `results` array may contain multiple messages, although typically just one. Always check the current Infobip documentation for the full, updated schema.
INFOBIP_SENDER_ID represents your Infobip number or registered Alphanumeric Sender ID, and it is crucial for two-way communication. It allows users to reply to the SMS messages they receive, as replies will be routed back to the configured sender. If not set, replies likely won't function as expected.
Use the `app.post('/webhook/infobip/sms', webhookHandler.handleIncomingSms)` route in your Express application. The `webhookHandler.handleIncomingSms` function parses the webhook's JSON payload, extracts the sender and message text, and implements your application's logic (like sending a reply).
Use a tunneling tool like ngrok to create a public URL that forwards requests to your local server running on port 3000. Run `ngrok http 3000` in your terminal. Ngrok provides a temporary public URL you can configure in the Infobip portal, so they can reach your local webhook endpoint during development.
You need an active Infobip account with a provisioned phone number, Node.js and npm installed, basic JavaScript and API knowledge, and a way to expose your local server (like ngrok). Familiarity with Express.js and RESTful APIs is also beneficial.
Install the SDK with `npm install @infobip-api/sdk dotenv`. Then initialize an Infobip client in your code, providing your API key, base URL, and `AuthType.ApiKey`. The dotenv package is used to manage credentials securely. The code example provides details on initializing and using the SDK for sending SMS.
Infobip recommends responding to webhooks (e.g., with a 200 OK) as quickly as possible, ideally within a few seconds, to prevent timeouts. This acknowledgment confirms receipt to Infobip. You can then perform potentially slower processing asynchronously.
If your SMS app needs to manage state (like a chatbot, survey, or multi-step interaction), you'll need a database to store user data, messages, and session information. Stateless apps (like the simple echo bot) may not require a database.
Store your Infobip API keys in a `.env` file, load them into your application using the `dotenv` package, and never commit the `.env` file to version control. This keeps sensitive credentials out of your codebase and repository.
Use try-catch blocks to handle potential errors when sending SMS messages or processing webhooks. Log errors with relevant context. For production, use a dedicated logging library like Winston or Pino. Implement retry mechanisms with exponential backoff for transient errors like network issues.
While you can potentially use a registered Alphanumeric Sender ID in some cases, for reliable two-way SMS, it's highly recommended to use your provisioned Infobip number as the sender. Users can then directly reply to the messages.
Use a library like `async-retry` to implement retry logic for API calls to the Infobip SDK. This helps manage transient errors, like network issues, by automatically retrying the request. Make sure to configure exponential backoff to prevent overloading the API.
Build Production-Ready Two-Way SMS with Node.js, Express, and Infobip
This guide provides a complete walkthrough for building a robust Node.js application using the Express framework to handle two-way SMS communication powered by the Infobip API. You'll learn how to set up your project, send SMS messages, receive incoming messages via webhooks, handle errors, and deploy your application.
We'll build a simple ""echo bot"" - an application that automatically replies to any incoming SMS with the same message text. This serves as a solid foundation for more complex conversational logic.
Project Goals:
Technologies Used:
@infobip-api/sdk
): For interacting with Infobip's SMS services.System Architecture:
Prerequisites:
curl
or Postman).Final Outcome:
By the end of this guide, you will have a running Node.js/Express application that can receive SMS messages sent to your Infobip number and automatically reply. You will also have a solid understanding of integrating Infobip for two-way SMS communication and best practices for building such applications.
1. Setting up the Project
Let's start by creating our project structure and installing the necessary dependencies.
Create Project Directory: Open your terminal or command prompt and create a new directory for your project. Navigate into it:
Initialize Node.js Project: Initialize the project using npm. This creates a
package.json
file to manage dependencies and project metadata. You can accept the defaults or customize them.-y
? This flag automatically accepts the default settings fornpm init
, speeding up the process. You can omit it to configure settings manually.Install Dependencies: We need Express for our web server, the Infobip SDK to interact with their API, and
dotenv
to manage environment variables.express
: The web framework.@infobip-api/sdk
: The official Infobip Node.js SDK simplifies API interactions.dotenv
: Loads environment variables from a.env
file intoprocess.env
.Create Project Structure: Let's organize our code logically.
src/
: Contains our main application source code.src/server.js
: The main entry point for our Express application.src/infobipService.js
: A dedicated module for Infobip API interactions (sending SMS).src/webhookHandler.js
: A module to handle incoming Infobip webhooks..env
: Stores sensitive configuration like API keys (DO NOT commit this file)..gitignore
: Specifies intentionally untracked files that Git should ignore (likenode_modules
and.env
).Configure
.gitignore
: Add the following lines to your.gitignore
file to prevent committing sensitive information and unnecessary files:Set up Basic Express Server (
src/server.js
): Opensrc/server.js
and add the following initial setup:require('dotenv').config()
: Must be called early to load variables before they are used.express.json()
: This middleware is essential. Infobip sends webhook data as JSON in the request body. This middleware parses it and makes it available asreq.body
./webhook/infobip/sms
: This is the specific path where our application will listen for incoming SMS notifications from Infobip. You'll configure this URL in the Infobip portal later.Add Start Script to
package.json
: Open yourpackage.json
file and add astart
script within the"scripts"
section. This provides a standard way to run your application.Now you can start your server (though it won't do much yet) by running
npm start
.2. Implementing Core Functionality (Sending SMS)
We'll create a dedicated service to encapsulate the logic for sending SMS messages using the Infobip SDK.
Configure Environment Variables (
.env
): Open the.env
file and add your Infobip API Key and Base URL.INFOBIP_API_KEY
:a1b2c3d4e5f67890a1b2c3d4e5f67890-a1b2c3d4-e5f6-7890-a1b2-c3d4e5f67890
).INFOBIP_BASE_URL
:xxxxx.api.infobip.com
. Do not includehttps://
here; the SDK handles the protocol.INFOBIP_SENDER_ID
:447123456789
) or a registered alphanumeric string (e.g.,InfoSMS
).Security: Never commit your
.env
file to version control. Use the.gitignore
file to prevent accidental exposure.Create Infobip Service (
src/infobipService.js
): This module will initialize the Infobip client and provide a function to send messages.Infobip
client using the credentials from.env
.AuthType.ApiKey
is specified.sendSms
Function: Takes the recipient, message text, and optionally a sender ID. It constructs the payload according to the Infobip API specification (specifically for the/sms/2/text/advanced
endpoint structure, which the SDK uses).try...catch
block to handle potential API errors during the send request and logs relevant information.INFOBIP_SENDER_ID
for two-way communication. If not set, Infobip might use a default sender, which likely won't work for replies.3. Building the API Layer (Handling Inbound SMS)
Now, let's implement the logic to receive and process the incoming SMS messages sent by Infobip to our webhook endpoint.
Understand the Infobip Inbound SMS Payload: When Infobip receives an SMS directed to your number, it will make a POST request to your configured webhook URL (
/webhook/infobip/sms
in our case). The request body will contain JSON data similar to this structure (refer to official Infobip documentation for the exact, up-to-date schema):results[0].from
(who sent the message) andresults[0].text
(what they sent) are crucial for our echo bot.Implement the Webhook Handler (
src/webhookHandler.js
): This module takes the incoming request, extracts the necessary information, and uses theinfobipService
to send a reply.200 OK
response back to Infobip before doing potentially long-running processing (like calling the API to send the reply). Webhooks often have short timeouts.results
array, although typically it contains only one message per webhook request.sender
(from
) andreceivedText
(text
).infobipService.sendSms
, passing the original sender's number as the recipient for the reply.try...catch
around thesendSms
call to handle failures specific to sending the reply.4. Integrating with Infobip (Webhook Configuration)
Your code is ready to send and receive, but you need to tell Infobip where to send the incoming SMS notifications.
Expose Your Local Server: Infobip's servers need to be able to reach your running application. During development, your machine is usually behind a firewall/NAT. Tools like
ngrok
create a secure tunnel and provide a public URL.Install ngrok (Download ngrok).
Run your Node.js app:
npm start
(it should log ""Server listening on port 3000"").In a new terminal window, start ngrok, telling it to forward to your application's port (e.g., 3000):
ngrok will display output similar to this:
Copy the
https://<unique-subdomain>.ngrok-free.app
URL. This is your public webhook URL for now.Configure Webhook in Infobip Portal:
server.js
:https://<unique-subdomain>.ngrok-free.app/webhook/infobip/sms
POST
.(Dashboard navigation paths can change. Refer to the current Infobip documentation if you can't find the exact location.)
5. Error Handling, Logging, and Retries
Production applications need robust error handling and logging.
Consistent Error Handling:
try...catch
blocks in key areas (infobipService.sendSms
,webhookHandler.handleIncomingSms
).Logging:
console.log
andconsole.error
are used for basic logging.Retry Mechanisms:
async-retry
or implement a simple loop with exponential backoff (wait longer between each retry).async-retry
for sending):6. Database Schema and Data Layer (Optional for Stateful Apps)
Our current echo bot is stateless – it doesn't remember past interactions. For most real-world applications (support chats, surveys, multi-step workflows), you'll need a database.
Why a Database?
Example Schema (Conceptual - PostgreSQL/Prisma): You might have tables like:
User
: Stores user information, potentially linked by phone number.Conversation
: Groups related messages.Message
: Stores individual inbound/outbound messages with details (sender, recipient, text, timestamp, Infobip message ID, status, direction - inbound/outbound).Data Access:
webhookHandler.js
modified conceptually):Migrations: Use the ORM's migration tools (e.g.,
prisma migrate dev
) to manage database schema changes safely.7. Adding Security Features
Security is paramount, especially when handling user data and API keys.
.env
to keep API keys out of the codebase. Ensure the.env
file has restrictive permissions and is never committed.from
looks like a phone number, limittext
length). Libraries like Joi or Zod are excellent for schema validation.receivedText
) before storing it in the database or using it in replies to prevent potential Cross-Site Scripting (XSS) issues if this data is ever displayed in a web interface. Libraries likedompurify
(if rendering as HTML) or simply escaping special characters might be needed depending on usage./webhook/infobip/sms
endpoint, pretending to be Infobip./webhook/infobip/sms/YOUR_SECRET_TOKEN
). This provides minimal obscurity but is vulnerable if the URL leaks.express-rate-limit
.server.js
):npm audit
regularly, injection attacks - use ORMs correctly, etc.).8. Handling Special Cases
Real-world SMS involves nuances:
+14155552671
,447123456789
). Ensure your application consistently handles this format when sending replies. Libraries likelibphonenumber-js
can help parse, validate, and format numbers if needed.smsCount
field in the inbound webhook indicates how many segments the incoming message used.STOP
,UNSUBSCRIBE
,HELP
. Your application should recognize these and act accordingly (e.g., opt-out the user, send help information). Infobip might offer features to manage opt-outs automatically.receivedAt
) are usually in UTC. Convert them to appropriate local times if displaying to users or performing time-sensitive logic.9. Implementing Performance Optimizations
For high-volume applications:
res.status(200).send()
) before performing slow operations.k6
,Artillery
, orApacheBench
to simulate high traffic volumes and identify bottlenecks in your webhook handler and API response times.