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.envfile.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.jsonin 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.jsonfile.Install Dependencies: We need Express for the server, the Infobip SDK, Prisma for database interaction,
pgas the PostgreSQL driver,node-cronfor scheduling,dotenvfor environment variables, andlibphonenumber-jsfor 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.envfile.libphonenumber-js: Phone number parsing/validation/formatting.prisma: Development dependency for Prisma CLI commands (schema management, migrations).Initialize Prisma: This creates a
prismadirectory with aschema.prismafile and a.envfile (if one doesn't exist).Configure Database Connection (.env): Open the
.envfile created by Prisma (or create one if it wasn't). Update theDATABASE_URLvariable with your PostgreSQL connection string.DATABASE_URL: Replace placeholders with your actual database user, password, host, port, and database name. Ensure the database (reminder_dbin 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 toproductionin 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 installor check for the latest compatible versions.)npm start. If you installnodemon(npm install --save-dev nodemon), you can usenpm run devfor automatic restarts during development.npm testwill run Jest tests (requires Jest setup, see Section 13).Setup
.gitignore: Create a.gitignorefile 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.prismafile and define theRemindermodel.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.Textfor flexibility).sendAt: The crucial field storing the scheduled time in UTC.status: Tracks the lifecycle of the reminder using anenum.PROCESSINGhelps 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/.Remindertable andStatusenum.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 forPENDINGreminders 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 toSENTorERROR. 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.envfile: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):Infobipclient instance. We export the client for use in other services.Create SMS Sending Service (
src/services/smsService.js):infobipClientandlogger.sendSmsfunction.infobipClient.channels.sms.send.status.groupName(e.g., 'PENDING', 'ACCEPTED') for better robustness.4. Implementing Scheduling Logic (
node-cron)We'll use
node-cronto periodically check for due reminders and trigger the sending process.Create the Scheduler Job (
src/jobs/reminderScheduler.js):