Frequently Asked Questions
Use the Infobip API with a Node.js library like Axios. The provided code example demonstrates sending SMS messages by making POST requests to the Infobip API endpoint with recipient phone numbers, message content, and webhook configuration for delivery status updates. A unique correlationId
is also included in the request to track messages.
SSE provides a lightweight, unidirectional channel for the server to push updates to the client. In this setup, after sending an SMS via Infobip, the backend uses SSE to push delivery status updates to the frontend as they're received from Infobip webhooks. This allows for a real-time status display without the overhead of WebSockets.
PostgreSQL offers a robust and reliable database solution for storing message status data. Prisma, an ORM, simplifies database interactions, allowing you to define the schema in a type-safe manner and generate a client for easy database queries and updates in your Node.js code. The example code demonstrates how to store pending, sent, delivered, and failed message status updates in the database using Prisma, along with details from Infobip about the status of sent messages and associated error details if any.
Infobip uses webhooks to send delivery reports asynchronously. Configure a webhook URL in your Infobip account settings or within each message request, pointing to your Node.js backend. When Infobip attempts message delivery, it will POST status updates to this URL. The example code's server.js file reminds users to ensure that their webhook is correctly configured.
Since Infobip needs a publicly accessible URL to send webhooks, ngrok
creates a tunnel that exposes your locally running server. Infobip can then send webhook updates to your local server during development via the ngrok
forwarding URL. The provided code sets up ngrok automatically.
The frontend initiates the SMS request and establishes an SSE connection to the backend using the correlationId
. The backend then pushes status updates to the frontend via this SSE connection in real-time. Basic understanding of REST APIs and asynchronous JavaScript are listed as prerequisites.
The correlationId
is a unique identifier generated for each SMS request on the backend. It serves as a link between the frontend request, the corresponding message in the database, and the SSE connection used for real-time updates. This ensures that status updates are delivered to the correct client.
A webhook secret adds an extra layer of security. Use it to verify that webhook requests are coming from Infobip and not a malicious source. The code example provides optional WEBHOOK_SECRET
validation middleware to ensure webhook integrity.
Yes, though the provided example uses PostgreSQL with Prisma, you can adapt it to other databases and ORMs. Modify the databaseService
accordingly to use a different database client library and update your schema definitions. Ensure alignment between database schema and the logic that updates and retrieves message status from the database.
The primary dependencies are: express
for the backend framework, axios
for HTTP requests, dotenv
for environment variables, cors
for cross-origin requests, sse-channel
for Server-Sent Events, uuid
for generating unique IDs, @prisma/client
for Prisma, nodemon
(dev) for automatic server restarts, and prisma
(dev) for database migrations. These are all installed when setting up the project using npm.
The code example includes error handling within the webhook handler (handleInfobipWebhook
). Each webhook report is processed individually within a try...catch
block to prevent a single failed report from stopping the others. Error information, if available from Infobip, is logged, and the database is updated accordingly.
Ensure ngrok
is running correctly and that the WEBHOOK_PUBLIC_URL
in your .env
file matches the URL provided by ngrok
. Infobip must be able to reach your local server through this public URL.
Use a free Infobip trial account (be aware of limitations) along with ngrok
for local testing. Send test SMS messages and observe the status updates logged in your Node.js backend and displayed in your frontend application. For persistent webhook URLs during development, consider paid ngrok
or other alternatives like localtunnel
.
This guide provides a complete walkthrough for building a Node.js backend system that sends SMS messages via Infobip, receives delivery status updates through webhooks, stores these updates, and pushes them in real-time to a connected frontend using Server-Sent Events (SSE). This enables you to provide immediate feedback to users about the status of their messages.
Project Goals:
Target Audience: Developers familiar with Node.js, Express, REST APIs, and basic frontend concepts (React/Vue).
Technologies Used:
dotenv
nodemon
(optional),ngrok
(for local webhook testing)Why these technologies?
ngrok
: Essential for exposing your local development server to the internet so Infobip can reach your webhook endpoint.System Architecture:
correlationId
.correlationId
and Infobip'smessageId
) in the database./sse-status/:correlationId
) for the frontend to connect to./infobip-webhook
) for Infobip to send status updates.correlationId
to Infobip'smessageId
and the latest delivery status.Prerequisites:
ngrok
installed for local development webhook testing. (Note: Freengrok
provides temporary URLs. For persistent URLs during development_ consider paidngrok
or alternatives likelocaltunnel
. In production_ you will use your server's actual public URL.)1. Setting up the Project
Let's initialize our Node.js project and install the necessary dependencies.
1.1 Create Project Directory:
1.2 Initialize npm Project:
This creates a
package.json
file.1.3 Install Dependencies:
express
: Web framework for Node.js.axios
: Promise-based HTTP client.dotenv
: Loads environment variables from a.env
file.cors
: Enables Cross-Origin Resource Sharing (necessary if your frontend is on a different domain/port).sse-channel
: Simple library for managing Server-Sent Events channels.uuid
: To generate unique correlation IDs.@prisma/client
: The Prisma database client (required at runtime).nodemon
(dev): Utility that monitors for changes and automatically restarts the server.prisma
(dev): The Prisma CLI for database migrations and management.1.4 Initialize Prisma:
This command does two things:
prisma
directory with aschema.prisma
file. This is where you define your database schema..env
file in the root directory to store environment variables_ including your database connection string.1.5 Configure
.env
:Open the generated
.env
file and update theDATABASE_URL
. Also_ add placeholders for Infobip credentials and other settings.DATABASE_URL
: Replace with your actual PostgreSQL connection string.INFOBIP_BASE_URL
_INFOBIP_API_KEY
: You'll get these from your Infobip dashboard (Account Settings -> API Keys).PORT
: The port your Express server will run on.WEBHOOK_PUBLIC_URL
: Leave this blank for now. We'll fill it when runningngrok
.WEBHOOK_SECRET
: A secret string you'll share only with Infobip (if using secret validation) to verify incoming webhooks.1.6 Configure
package.json
Scripts:Add development scripts to your
package.json
:start
: Runs the application normally.dev
: Runs the application usingnodemon
for auto-restarts.prisma:migrate
: Applies database schema changes.prisma:generate
: Generates the Prisma Client based on your schema.1.7 Project Structure:
Create the following directory structure within your project root:
config
: Loads and exposes environment variables.controllers
: Handles incoming HTTP requests, interacts with services, and sends responses.middleware
: Request handling middleware (like webhook validation).routes
: Defines API endpoints and maps them to controller functions.services
: Contains business logic (interacting with Infobip, database, SSE).utils
: Utility functions like logging.server.js
: Sets up the Express app, middleware, and starts the server.1.8 Basic Server Setup (
src/server.js
):1.9 Config Loader (
src/config/index.js
):1.10 Logger Utility (
src/utils/logger.js
):Note: The provided
logger.js
is extremely basic. For production applications, it is strongly recommended to use a dedicated logging library like Winston or Pino. These libraries offer essential features such as configurable log levels, structured logging (e.g., JSON), multiple transports (console, file, external services), log rotation, and better performance.2. Database Schema and Setup
Define the database schema using Prisma and apply it to your database.
2.1 Define Database Schema (
prisma/schema.prisma
):We need a table to store the status of each message we send.
correlationId
: A UUID we generate before sending the SMS. This is crucial for linking the initial request to subsequent webhook updates and the specific SSE connection.infobipMessageId
: The ID Infobip returns after successfully accepting the message for sending. We use this to match incoming webhooks.status
,statusGroup
,statusDescription
,errorCode
,errorMessage
: Fields to store details from Infobip's delivery reports.2.2 Apply Database Migrations:
Run the migration command to create the
MessageStatus
table in your database. Prisma will prompt you to name the migration (e.g.,init
).If prompted, confirm that you want to create the migration and apply it. This updates your database schema.
2.3 Generate Prisma Client:
Ensure your Prisma Client is up-to-date with the schema:
3. Core Services Implementation
Implement the services for database interactions, managing SSE connections, and sending SMS via Infobip.
3.1 Database Service (
src/services/databaseService.js
):Create a service to handle database interactions using Prisma Client.
3.2 SSE Service (
src/services/sseService.js
):This service manages SSE connections and publishes updates.
3.3 Infobip Service (
src/services/infobipService.js
):Handles communication to the Infobip API.
4. API Layer: Routes and Controllers
Define the API endpoints and the controller logic that orchestrates the services.
4.1 Define Routes (
src/routes/index.js
andsrc/routes/messageRoutes.js
):4.2 Implement Controller (
src/controllers/messageController.js
):