Frequently Asked Questions
Integrate Infobip's WhatsApp API into your NestJS project by installing the necessary dependencies like '@infobip-api/sdk', '@nestjs/config', 'dotenv', 'class-validator', and 'class-transformer'. Then, set up environment variables for your Infobip credentials and configure the 'ConfigModule' to load them. Finally, create a WhatsApp feature module with a controller and service to handle message sending and receiving.
The Infobip WhatsApp API is a communication platform service that allows you to send and receive WhatsApp messages programmatically. This guide uses the Infobip Node.js SDK to simplify interaction with the API, enabling features like sending text messages and receiving incoming messages via webhooks.
NestJS provides a robust and structured framework for building scalable server-side applications. Its features like dependency injection, validation pipes, and modular architecture accelerate development and improve code maintainability, making it ideal for integrating with external APIs like Infobip's WhatsApp API.
Data Transfer Objects (DTOs) are essential for defining the expected structure and validation rules for incoming requests. They improve code clarity and security by ensuring data integrity. Use DTOs with NestJS's 'ValidationPipe' for automatic request validation.
To send a WhatsApp message, create a service method that uses the Infobip SDK. Inject the 'ConfigService' to access your API credentials, initialize the Infobip client, and use the 'channels.whatsapp.send' method with a properly formatted payload. Expose this functionality through a controller endpoint, validating input using a DTO.
The '@infobip-api/sdk' is the official Infobip Node.js SDK. It simplifies interaction with the Infobip API by providing convenient methods for sending messages, managing webhooks, and other functionalities. It streamlines the integration process compared to making direct HTTP requests.
To set up a webhook, configure the webhook URL in the Infobip portal to point to your NestJS application's endpoint. For local development, use a tool like 'ngrok'. Create a DTO to define the structure of incoming messages and a controller endpoint to handle webhook requests. Importantly, implement security measures like signature verification using a secret key from Infobip to authenticate webhook requests.
The '@nestjs/config' module provides a structured and secure approach to manage environment-specific configurations, such as API keys, database credentials, and other sensitive data. It prevents hardcoding such values in your application code, making it easy to switch configurations between development, testing, and production environments.
Yes, you can test webhooks locally by using a tunneling tool like 'ngrok'. 'ngrok' creates a temporary public URL that forwards requests to your local development server. Configure this URL as your webhook URL in the Infobip portal, allowing you to receive webhook requests even during local development.
Handle webhook errors by implementing thorough error handling in your webhook handler method. Use try-catch blocks to catch potential errors during message processing, including signature verification failures, and log detailed error information. Consider using a queue system for asynchronous processing and retries to handle transient failures and load spikes.
'class-validator' and 'class-transformer' work together for request validation and transformation in NestJS. 'class-validator' provides decorators like '@IsNotEmpty', '@IsString', and '@IsPhoneNumber' to define validation rules for DTO properties, and class-transformer' handles the actual transformation of the request body into a DTO instance.
Secure your webhook endpoint by implementing signature verification. Obtain a webhook secret from your Infobip portal and use it to compute an HMAC-SHA256 hash of the incoming request body. Compare the computed hash with the signature provided in the request header ('x-infobip-signature' or similar) to ensure the request originated from Infobip.
Manage environment variables securely using the '@nestjs/config' module along with 'dotenv'. Create a '.env' file to store your environment-specific variables, and configure the 'ConfigModule' in your main application module. Never commit your '.env' file to version control to prevent exposing sensitive data.
Production-Ready NestJS & Infobip WhatsApp Integration Guide
This guide provides a comprehensive, step-by-step walkthrough for integrating Infobip's WhatsApp API into a NestJS application using Node.js. We'll cover everything from initial project setup and sending messages to handling incoming webhooks, error management, security, and deployment best practices. By the end, you'll have a robust foundation for production-level WhatsApp communication.
We assume minimal prior knowledge beyond basic NestJS and Node.js concepts, explaining each step and decision clearly. We prioritize practical, real-world implementation details to ensure your integration is reliable and scalable.
Project Overview and Goals
What We're Building:
We will build a NestJS application capable of:
Problem Solved:
This integration enables applications to leverage WhatsApp for various communication needs, such as notifications, customer support interactions, OTP delivery, or marketing messages (respecting WhatsApp policies), automating processes previously handled manually or through less direct channels.
Technologies Used:
@infobip-api/sdk
: The official Infobip Node.js SDK, simplifying interactions with the Infobip API.@nestjs/config
: For managing environment variables securely.class-validator
&class-transformer
: For robust request validation using Data Transfer Objects (DTOs).System Architecture:
Prerequisites:
npm install -g @nestjs/cli
).ngrok
or similar: For testing webhooks locally.curl
: For testing API endpoints.1. Setting up the Project
Let's initialize our NestJS project and install necessary dependencies.
Create a New NestJS Project: Open your terminal and run:
Choose your preferred package manager (npm or yarn) when prompted.
Install Dependencies: We need the Infobip SDK and NestJS configuration module.
@infobip-api/sdk
: The core library for interacting with Infobip.@nestjs/config
: Manages environment variables.dotenv
: Loads environment variables from a.env
file for local development.class-validator
&class-transformer
: Enable validation using DTOs.Configure Environment Variables:
.env
file in the project root:.env
. Never commit this file to version control.INFOBIP_BASE_URL
&INFOBIP_API_KEY
: Log in to your Infobip Portal. Navigate to the homepage or API Keys management section. Your unique Base URL and API Key will be displayed.INFOBIP_WHATSAPP_SENDER
: Navigate to Channels and Numbers -> WhatsApp -> Numbers. Copy the registered sender number you intend to use. Ensure it's approved and active.Load Environment Variables using
ConfigModule
: Import and configureConfigModule
in your main application module (src/app.module.ts
). Making it global simplifies access in other modules.ConfigModule
? It provides a structured and secure way to handle environment-specific configurations, preventing hardcoding sensitive data like API keys directly in the code.isGlobal: true
avoids needing to importConfigModule
into every feature module that requires access to environment variables.Enable Validation Pipe Globally: Configure the
ValidationPipe
insrc/main.ts
to automatically validate incoming request payloads against DTOs.Create the WhatsApp Feature Module: Generate a module, controller, and service for our WhatsApp functionality using the NestJS CLI.
This creates a
src/whatsapp
directory withwhatsapp.module.ts
,whatsapp.controller.ts
, andwhatsapp.service.ts
. The CLI automatically updatessrc/app.module.ts
to importWhatsappModule
.2. Implementing Core Functionality (Sending Messages)
We'll implement the logic to send a WhatsApp message via the Infobip SDK within our
WhatsappService
.Initialize Infobip Client in the Service: Inject
ConfigService
intoWhatsappService
and initialize the Infobip client in the constructor.Implement the
sendTextMessage
Method: Add a method to handle sending the message payload.try...catch
block handles potential API errors gracefully, logs them, and throws appropriate NestJS HTTP exceptions. Basic input validation is added as a safety measure, though the primary validation occurs via DTOs in the controller. We return theresponse.data
which contains useful information likemessageId
.3. Building the API Layer (Sending Messages)
Now, let's expose an endpoint in
WhatsappController
to trigger thesendTextMessage
method.Create a Data Transfer Object (DTO): Define a DTO to specify the expected shape and validation rules for the request body.
ValidationPipe
, provide automatic request validation, improving security and data integrity. Using@IsPhoneNumber
is preferred for robust validation.Implement the Controller Endpoint: Inject
WhatsappService
and create a POST endpoint.@Body() sendMessageDto: SendMessageDto
? This tells NestJS to parse the request body and validate it against theSendMessageDto
using the globally configuredValidationPipe
.HttpStatus.ACCEPTED
? Sending a message is often asynchronous. Returning 202 Accepted signifies the request is valid and processing has started, but doesn't guarantee immediate delivery.BadRequestException
, 500 forInternalServerErrorException
).Testing the Endpoint: Start your application:
npm run start:dev
Usecurl
or Postman to send a POST request:Replace
YOUR_REGISTERED_TEST_NUMBER
with your registered test number (e.g.,447123456789
). You should receive a202 Accepted
response and the message on your WhatsApp (if using your registered trial number). Check the application logs and the Infobip portal for status updates.4. Integrating with Third-Party Services (Infobip Webhook)
To receive messages sent to your Infobip WhatsApp number, you need to configure a webhook.
Configure Webhook in Infobip Portal:
ngrok
to expose your local port:ngrok http 3000
(if your app runs on port 3000).https://<your-ngrok-id>.ngrok.io
URL.https://<your-ngrok-id>.ngrok.io/whatsapp/webhook
(we'll create/whatsapp/webhook
next)..env
file (e.g.,INFOBIP_WEBHOOK_SECRET
).Create DTO for Incoming Webhook Payload: Define a DTO based on the expected structure of Infobip's incoming WhatsApp message webhook. Note: This structure might vary slightly; always refer to the official Infobip documentation for the most accurate payload format.
@ValidateNested
and@Type
are crucial for validating nested objects and arrays. Using@IsDateString()
forreceivedAt
is safer if you know the format is ISO8601.Implement the Webhook Handler in Controller: Add a new POST endpoint in
WhatsappController
to receive webhook events.HttpStatus.OK
? Webhook providers like Infobip expect a quick 2xx response to acknowledge receipt. Long processing should happen asynchronously.bodyParser.raw({ type: 'application/json' })
) inmain.ts
.Implement Processing Logic in Service: Add a method in
WhatsappService
to handle the incoming message data. You'll also need to add the verification logic stubbed in the controller if you implement it.INFOBIP_WEBHOOK_SECRET
to your.env
file and retrieve it viaConfigService
when implementing signature verification.Testing the Webhook:
ngrok
tunnel are running.5. Implementing Proper Error Handling, Logging, and Retry Mechanisms
Robust error handling and logging are crucial for production.
Error Handling Strategy:
ValidationPipe
-> 400 Bad Request.BadRequestException
,NotFoundException
, etc., where applicable within the service.try...catch
). Log detailed error information (includingerror.response?.data
if available). ThrowInternalServerErrorException
or a more specific custom exception if you can map Infobip errors.ForbiddenException
(403) if signature verification fails.Logging:
Logger
. Inject it where needed (private readonly logger = new Logger(ClassName.name)
).log
: General information (request received, action started, webhook received).warn
: Potential issues (invalid format detected but handled, retry attempt, signature failure).error
: Failures (API call failed, processing error, configuration missing). Include stack traces.debug
: Detailed information for troubleshooting (full API responses/payloads) – disable in production unless needed.pino
orwinston
for structured logging (JSON format), log rotation, and transport to external logging services (e.g., Datadog, ELK Stack). Configure log levels via environment variables.Retry Mechanisms (Conceptual):
for
loop with delays (shown below - use with caution).async-retry
or integrate with a queue system (e.g., BullMQ) that has built-in retry logic with exponential backoff. Queues are strongly recommended for production reliability.