Frequently Asked Questions
Use Node.js with Express, the Infobip API, and node-cron to build an SMS reminder system. Create an API endpoint to handle reminder requests and a scheduler to check for due reminders and dispatch them via Infobip.
The Infobip Node.js SDK simplifies interaction with the Infobip SMS API, allowing you to easily send SMS messages from your Node.js application. It handles authentication, request formatting, and response parsing.
Prisma is a next-generation ORM that streamlines database operations in Node.js. It provides type safety, schema migrations, and an intuitive API for querying and updating the PostgreSQL database where reminder information is stored.
If your reminder system operates in a high-concurrency or distributed environment, a more robust locking mechanism like Redis is recommended to prevent race conditions when multiple scheduler instances might run concurrently.
While the article uses PostgreSQL, you could adapt the system to use other databases by configuring the appropriate Prisma data source and adjusting database interaction code in the scheduler and controller.
You'll need an Infobip account and an API key. Obtain these from the Infobip portal under Developers -> API Keys, then store them securely as environment variables (INFOBIP_API_KEY and INFOBIP_BASE_URL).
Node-cron is a task scheduling library that enables periodic execution of functions within your Node.js application. It is used to trigger the check for due reminders at defined intervals.
The project's Infobip service constructs a payload with recipient number and message text, then uses the Infobip Node.js SDK's send() method to make the API call, handling successful submissions or potential errors.
The example uses a basic API key for authentication. However, for production, stronger methods like JWT or OAuth2 are recommended. Implement appropriate authentication middleware to protect the endpoint.
E.164 is an international standard for phone number formatting. It includes a '+' sign followed by the country code and national number without spaces or punctuation, ensuring consistency for global SMS delivery.
Node-cron uses a cron expression format (e.g., ' ' for every minute, or '/5 ' for every 5 minutes). See the node-cron documentation for advanced scheduling patterns.
Implement a retry mechanism in the scheduler job’s catch block. If sending via the primary SMS service fails, store retry attempts in the database and re-attempt sending up to a defined limit.
The scheduler job handles failures by updating the reminder status in the database to 'FAILED'. Detailed error information is logged for debugging. Consider a fallback strategy or retry mechanism to improve reliability.
You need Node.js v18+, access to a PostgreSQL database, an active Infobip account with API credentials, and familiarity with Node.js, Express, and APIs.
Automating communication is crucial for engaging users and streamlining operations. Sending timely reminders – for appointments, payments, or events – is a common requirement. This guide provides a complete walkthrough for building a production-ready system in Node.js and Express to schedule and send SMS reminders using the Infobip API and its Node.js SDK.
We will build an API endpoint to accept reminder requests and a background scheduler that checks for due reminders and dispatches them via Infobip SMS. This approach gives you full control over the scheduling logic within your application while leveraging Infobip's robust communication infrastructure.
Project Overview and Goals
Goal
To create a Node.js Express application that can:
Problem Solved
This system solves the challenge of reliably sending automated, time-sensitive SMS notifications without manual intervention, improving user engagement and reducing missed appointments or deadlines.
Technologies
node-cron
: Task scheduler library for running background jobs within Node.js.dotenv
: For managing environment variables.System Architecture
Outcome
By the end of this guide, you will have a functional Express application with an API endpoint (
POST /api/reminders
) to schedule SMS messages and a background worker that sends these messages at the specified time via Infobip.Prerequisites
1. Setting up the project
Let's start by creating the project structure and installing necessary dependencies.
Environment Setup
Ensure Node.js and npm (or yarn) are installed. You can download Node.js from the official website. Verify the installation:
Project Initialization
Create Project Directory:
Initialize npm Project:
This creates a
package.json
file.Install Dependencies:
Initialize Prisma:
This creates a
prisma
directory with aschema.prisma
file and a.env
file for database connection details.Project Structure
Organize your project for maintainability:
Configure Environment Variables (
.env
)Prisma already added
DATABASE_URL
. Add placeholders for Infobip credentials and the server port. Replace placeholders later with actual values.Purpose: Using
.env
keeps sensitive information like API keys and database URLs out of your codebase, adhering to security best practices.dotenv
library loads these variables intoprocess.env
.Basic Express Server Setup (
src/index.js
)Why: This sets up a basic Express server, loads environment variables, includes JSON parsing, defines a simple health check, wires up routes (created later), includes middleware for auth and errors (defined later), and starts the server. Crucially, it also initializes the reminder scheduler job.
Note on Dependencies: Notice the
require
statements forlogger
,basicAuth
, anderrorHandler
. The actual code for these modules will be created in later sections (Sections 5 and 3, respectively). If running incrementally, these lines would cause errors until those modules exist.2. Implementing core functionality (Scheduler)
We'll use
node-cron
to periodically check for reminders that need to be sent.Create the Scheduler Job (
src/jobs/reminderScheduler.js
)Why
node-cron
It's a simple, widely used library for scheduling tasks within a Node.js process. Perfect for periodic jobs like checking for due reminders.
Logic
taskRunning
flag as a mutex. Caveat: This simple flag might not be fully robust in edge cases like unhandled promise rejections before the flag is reset or in distributed environments. Consider Redis-based locks or similar for higher guarantees if needed.sendAt
is in the past or present (UTC) andstatus
is 'PENDING'.take: 100
) to manage load.infobipService
(defined later) to send the SMS.status
to 'SENT' or 'FAILED' based on the outcome.logger
, defined later).Integration
The
initializeScheduler
function is exported and called insrc/index.js
when the server starts.3. Building a complete API layer (Scheduling Endpoint)
We need an API endpoint for clients to submit reminder requests.
Define Routes (
src/routes/reminderRoutes.js
)Why: This file defines the specific HTTP methods and paths for reminder-related actions, linking them to controller functions and applying validation middleware.
Implement Controller (
src/controllers/reminderController.js
)Why: The controller handles the core logic for the API endpoint.
express-validator
results to check for bad input.libphonenumber-js
to validate and format the phone number to E.164 standard, crucial for reliable international SMS sending.sendAt
timestamp, ensuring it's a valid date in the future. Clarified that scheduling in the immediate same minute might be prevented by the< new Date()
check.next(error)
).Implement Basic Authentication Middleware (
src/middleware/authMiddleware.js
)Why: Protects the scheduling endpoint from unauthorized access. This is a very basic example using a static API key passed in a header (
x-api-key
). Added a warning recommending stronger methods for production.Implement Request Validation (
src/utils/validators.js
)Why: Uses
express-validator
to define rules for incoming request bodies. Ensures required fields are present, have the correct types, and meet basic constraints (like message length). This prevents invalid data from reaching the controller logic.API Endpoint Documentation & Testing
You can test the
POST /api/reminders
endpoint usingcurl
or Postman.curl
Example:Replace placeholders with your actual values.
Request Body (JSON):
Success Response (JSON):
Error Response (JSON - Validation Example):
4. Integrating with Infobip
Now, let's implement the service that uses the Infobip Node.js SDK to send SMS messages.
Create Infobip Service (
src/services/infobipService.js
)Why: This service encapsulates all interaction with the Infobip SDK.
Infobip
client usingbaseUrl
andapiKey
from environment variables. Added error handling for missing variables and client initialization failure.AuthType.ApiKey
.sendSms
function constructs the payload. Added clarification on the optionalfrom
field (Sender ID) and its implications regarding registration, cost, and deliverability.messageId
and status group.error.response?.data
but added a comment warning about potentially sensitive information. Also logs non-sensitive payload parts.Fallback Strategy
If you need higher resilience, you could implement a fallback mechanism. In the
catch
block ofcheckAndSendReminders
(Section 2), instead of immediately marking as FAILED, you could call another function (e.g.,alternativeSmsService.sendSms
). This would require:src/services/alternativeSmsService.js
).5. Implementing error handling, logging, and retry mechanisms
Robust error handling and logging are essential for production systems.
Consistent Error Handling Strategy
express-validator
) returning 400 status code.authMiddleware
, returning 401.errorHandler
), logged as critical errors, and return a generic 500 status code to the client.Global Error Handling Middleware (
src/middleware/errorMiddleware.js
)(Note: The rest of Section 5, including Logger Configuration and Retry Mechanisms, was missing from the original provided text. This rewrite includes the completed
errorHandler
based on the structure.)