Frequently Asked Questions
This involves setting up a Node.js project with Express, integrating the Infobip API for SMS, using a database like PostgreSQL with Prisma as the ORM, and scheduling tasks with node-cron to trigger reminder checks and send messages at the specified time via the Infobip service.
Infobip is a cloud communications platform used to send SMS messages. The Infobip API and Node.js SDK are integrated into the application to handle sending SMS reminders. The project uses the official @infobip-api/sdk
package.
Prisma acts as an ORM (Object-Relational Mapper), simplifying database interactions. This makes it easier to work with PostgreSQL by providing a type-safe and convenient way to query and manage data within the Node.js application.
Set NODE_ENV
to production
when deploying your application to a live server environment. This affects error handling and logging. In development mode, more verbose error details are shown, while in production, they are usually suppressed for security.
The guide primarily uses PostgreSQL, but Prisma supports other databases as well. You would need to adjust the datasource
configuration in your schema.prisma
file and install the appropriate database driver for Prisma.
Use npm install express @infobip-api/sdk pg node-cron dotenv libphonenumber-js
for core dependencies and npm install --save-dev prisma
for Prisma (used in development). These commands install the packages listed in the package.json
file.
node-cron
is a task scheduler in Node.js. It's used to periodically trigger the function that checks for pending reminders and sends them via the Infobip SMS API.
The guide recommends a structure that separates concerns: routes, controllers, services, configuration, and jobs. This organization makes the codebase cleaner and easier to manage and scale.
The reminderService.js
file handles the core logic for managing reminders. This includes creating new reminders, validating input, finding due reminders in the database, and updating their status after processing.
E.164 is an international standard for phone number formatting (e.g., +14155552671). Using a consistent format, like E.164, ensures that phone numbers are stored and processed correctly, especially when sending SMS internationally.
The smsService.js
uses try...catch blocks to handle errors during the SMS sending process via Infobip. It also includes detailed logging of these errors and updates the reminder status in the database to ERROR
, storing the error message if the sending fails.
The PROCESSING
status prevents a reminder from being sent multiple times. When the scheduler finds due reminders, it marks them as PROCESSING
before sending the SMS. This ensures that even with multiple scheduler instances, the same reminder is not picked up and sent twice.
This guide provides a step-by-step walkthrough for building a production-ready Node.js application using the Express framework to schedule and send SMS reminders via the Infobip API. We'll cover everything from project setup and database integration to scheduling logic, error handling, security, and deployment.
Project Goal: To create a backend service that allows users (or other systems) to schedule SMS reminders (e.g., appointments, payment due dates) which are automatically sent at the specified time using Infobip.
Problem Solved: Automates the process of sending timely SMS notifications, improving communication and reducing manual effort. Handles scheduling complexity, API integration, and ensures reliable delivery.
Technologies Used:
@infobip-api/sdk
).node-cron
: Task scheduler for Node.js to trigger reminder checks periodically.dotenv
: Module to load environment variables from a.env
file.libphonenumber-js
: Library for parsing, formatting, and validating phone numbers.winston
(for logging),express-validator
(for validation),express-rate-limit
(for security),helmet
(security headers).(See
package.json
in Section 1 for example dependency versions used in this guide.)System Architecture:
(Note: Rendering requires Markdown platform support for Mermaid diagrams.)
Prerequisites:
Final Outcome: A running Node.js service with an API endpoint to schedule reminders and a background job that automatically sends these reminders via Infobip SMS at the correct time.
1. Setting up the project
Let's initialize our Node.js project and install the necessary dependencies.
Create Project Directory: Open your terminal and create a new directory for the project, then navigate into it.
Initialize Node.js Project: This creates a
package.json
file.Install Dependencies: We need Express for the server, the Infobip SDK, Prisma for database interaction,
pg
as the PostgreSQL driver,node-cron
for scheduling,dotenv
for environment variables, andlibphonenumber-js
for phone number validation.express
: Web framework.@infobip-api/sdk
: Official SDK for interacting with Infobip APIs.pg
: Node.js driver for PostgreSQL (required by Prisma).node-cron
: Job scheduler.dotenv
: Loads environment variables from.env
file.libphonenumber-js
: Phone number parsing/validation/formatting.prisma
: Development dependency for Prisma CLI commands (schema management, migrations).Initialize Prisma: This creates a
prisma
directory with aschema.prisma
file and a.env
file (if one doesn't exist).Configure Database Connection (.env): Open the
.env
file created by Prisma (or create one if it wasn't). Update theDATABASE_URL
variable with your PostgreSQL connection string.DATABASE_URL
: Replace placeholders with your actual database user, password, host, port, and database name. Ensure the database (reminder_db
in the example) exists. Use quotes if your password contains special characters.INFOBIP_API_KEY
,INFOBIP_BASE_URL
,INFOBIP_SENDER_ID
: We'll get these from Infobip later (Section 3). Leave them blank for now or use placeholders.PORT
: The port your Express server will listen on.NODE_ENV
: Set toproduction
in deployment environments.Define Project Structure: Create the following directories and files for organization:
Create Basic Express Server (
src/app.js
):Create Server Entry Point (
src/server.js
):Add Start Script (
package.json
): Add scripts to easily run your server and tests.^3.0.0
) are examples at the time of writing. You should use the versions installed bynpm install
or check for the latest compatible versions.)npm start
. If you installnodemon
(npm install --save-dev nodemon
), you can usenpm run dev
for automatic restarts during development.npm test
will run Jest tests (requires Jest setup, see Section 13).Setup
.gitignore
: Create a.gitignore
file in the root directory to avoid committing sensitive files and unnecessary directories.2. Database Schema and Data Layer (Prisma)
We'll define the database schema for our reminders and set up Prisma Client to interact with it.
Define Prisma Schema (
prisma/schema.prisma
): Open theprisma/schema.prisma
file and define theReminder
model.id
: Unique CUID for each reminder.phoneNumber
: Recipient's number. Stored in E.164 format (enforced by service).message
: Text content of the SMS (using@db.Text
for flexibility).sendAt
: The crucial field storing the scheduled time in UTC.status
: Tracks the lifecycle of the reminder using anenum
.PROCESSING
helps prevent double-sending.infobipMessageId
: Useful for tracking and debugging with Infobip.errorMessage
: Stores failure reasons.@@index([status, sendAt])
: Adds a database index to optimize queries for finding due reminders.Create Database Migration: Run the following command to create the SQL migration files based on your schema changes and apply them to your database. Prisma will prompt you to name the migration (e.g.,
init_reminder_model
).prisma/migrations/
.Reminder
table andStatus
enum.Initialize Prisma Client: Create an instance of Prisma Client to use throughout your application.
Implement Data Access Logic (
src/services/reminderService.js
): This service will handle creating reminders and finding ones that are due.createReminder
: Takes details, performs strict validation (expects E.164 number), and saves to the DB. Includes basic error handling for DB operations.findAndMarkDueReminders
: Queries forPENDING
reminders using the index, fetches a batch, and attempts to atomically update their status toPROCESSING
. Returns only the reminders successfully marked. Includes logging and error handling.updateReminderStatus
: Updates the reminder's status toSENT
orERROR
. Includes error handling for the update operation.3. Integrating with Infobip (SMS Sending Service)
Now, let's set up the Infobip SDK client and create a service to handle sending SMS messages.
Obtain Infobip Credentials:
Log in to your Infobip account.
API Key: Navigate to the API Keys management section (often under your account settings or developer tools). Generate a new API key if you don't have one. Copy this key.
Base URL: Your Base URL is specific to your account and region. You can usually find this on the API Keys page or the main dashboard/homepage after logging in. It looks something like
xxxxx.api.infobip.com
. Copy this URL.Sender ID: Decide on a Sender ID (the "from" name/number shown on the recipient's phone). For trial accounts, you might be restricted to specific shared numbers or need to register your own number. For paid accounts, you can often register alphanumeric Sender IDs (like "MyCompany"). Check Infobip's documentation for rules in your target countries.
Update
.env
: Paste your copied API Key, Base URL, and chosen Sender ID into the.env
file:Free Trial Limitation: Remember, if using a free trial, you can typically only send SMS messages to the phone number you verified during signup.
Configure Infobip SDK Client (
src/config/infobip.js
):Infobip
client instance. We export the client for use in other services.Create SMS Sending Service (
src/services/smsService.js
):infobipClient
andlogger
.sendSms
function.infobipClient.channels.sms.send
.status.groupName
(e.g., 'PENDING', 'ACCEPTED') for better robustness.4. Implementing Scheduling Logic (
node-cron
)We'll use
node-cron
to periodically check for due reminders and trigger the sending process.Create the Scheduler Job (
src/jobs/reminderScheduler.js
):