Frequently Asked Questions
Your Infobip API Key and Base URL can be found in your Infobip account dashboard. Look for a section labeled 'API Keys,' 'API Credentials,' or a similar name. The specific location might vary based on the Infobip portal's layout.
You can send SMS messages within a RedwoodJS application by creating a service that utilizes the Infobip Node.js SDK. This service interacts with Infobip's API to send messages programmatically. You then expose this service functionality via a GraphQL mutation or a custom API function within your RedwoodJS application. Be sure to configure the necessary environment variables with your Infobip account credentials first.
Infobip is a cloud communications platform that provides the SMS API used by the RedwoodJS application. The integration uses Infobip's Node.js SDK to interact with their services, allowing you to send and receive SMS messages. You'll need an Infobip account and API key to use this integration.
Prisma, a next-generation ORM, is used to store the history of both inbound and outbound SMS messages. Prisma simplifies database interactions, making it easy to create, read, update, and delete records in the database. The schema in api/db/schema.prisma
needs to include a SmsMessage
model.
Create a RedwoodJS API function (using the rw g function
command) to act as your webhook endpoint. This function will receive incoming messages from Infobip. Configure your Infobip account to send inbound SMS webhooks to the public URL of this function. Implement security measures within your RedwoodJS function to verify the origin and integrity of the incoming webhook data.
You need Node.js (LTS recommended), Yarn, an active Infobip account, your Infobip API Key and Base URL, and a provisioned Infobip phone number. Basic RedwoodJS knowledge is also helpful, along with a way to expose your local development server for webhook testing (like ngrok).
Use a tool like ngrok or cloudflared to create a tunnel from your local development environment to a public URL. This makes your RedwoodJS API function accessible to Infobip for webhook delivery during development. Run ngrok http 8911
if your RedwoodJS API is running locally on port 8911.
Implement robust signature verification using a strong, randomly generated secret shared with Infobip. Use this secret to verify that incoming webhook requests genuinely originate from Infobip, preventing unauthorized access or data manipulation. Always use HTTPS for webhook URLs.
The client interacts with the RedwoodJS frontend, which communicates with the RedwoodJS API. The API interacts with the Infobip service using the Node.js SDK to send SMS messages to the end user's phone. Inbound messages are sent to the RedwoodJS API via webhooks, then stored in a database using Prisma.
Within your inbound webhook handler, parse the incoming message body for keywords like 'STOP' and 'HELP'. Implement the appropriate logic, such as updating user opt-out status or providing help information. This is essential for compliance with regulations like TCPA.
The SmsMessage
model is used to store details like message direction, sender and recipient numbers, message content, status, Infobip message and bulk IDs, and a processing flag. It is recommended to index the infobipMessageId
, sender
, recipient
, and createdAt
fields for efficient querying.
Configure the webhook URL in your Infobip account after you have a publicly accessible URL for your RedwoodJS API function. This URL is necessary for Infobip to send inbound SMS messages to your application. This is typically done during the integration phase after the local API endpoint is ready.
Yes, RedwoodJS allows you to use other Prisma-compatible databases like SQLite, MySQL, or MongoDB by modifying the provider
setting in the api/db/schema.prisma
file and setting the correct connection string in the .env
file. However, this guide assumes the default PostgreSQL settings.
Implement try...catch
blocks in both service and API functions to handle potential errors. Log errors using Redwood's logger and store error details in the database. Return appropriate HTTP status codes from the webhook handler and structured error responses from the sendSms service to manage issues effectively.
Build Two-Way SMS Messaging with Infobip and RedwoodJS
Integrate Infobip's SMS capabilities into your RedwoodJS application to enable sending outbound messages and receiving inbound messages via webhooks for complete two-way communication.
You'll build a RedwoodJS application that can:
This setup enables applications to interact with users via SMS for notifications, alerts, verification, or conversational features, while leveraging the robust structure and developer experience of RedwoodJS.
Technologies used:
Prerequisites:
System architecture:
Ensure your target platform supports Mermaid rendering for this diagram.
Final outcome:
You'll have a functional RedwoodJS application capable of sending SMS messages via an API call and automatically receiving and processing inbound SMS replies sent to your Infobip number, storing relevant details in your database.
Set up your RedwoodJS project
Create a new RedwoodJS project and install the necessary dependencies.
Create a new RedwoodJS app: Open your terminal and run:
This scaffolds a new RedwoodJS project with TypeScript enabled in the
redwood-infobip-sms
directory.Install the Infobip Node.js SDK: Navigate to the
api
directory and install the SDK:Configure environment variables: RedwoodJS uses
.env
files for environment variables. Create a.env
file in the project's root directory:Add your Infobip credentials and a secret for webhook validation:
INFOBIP_BASE_URL
/INFOBIP_API_KEY
: Find these in your Infobip account dashboard (usually under API Keys or similar).INFOBIP_WEBHOOK_SECRET
: Generate a strong, unique random string using a password manager oropenssl rand -hex 32
. Share this secret with Infobip to verify webhook authenticity.Initialize your database with Prisma: RedwoodJS uses Prisma. By default, it's configured for PostgreSQL. Change the provider in
api/db/schema.prisma
if needed (e.g., SQLite for simple testing). Ensure your database connection string is correctly set in the.env
file (Redwood creates aDATABASE_URL
variable).This guide proceeds with the default PostgreSQL setup assumption.
Implement outbound SMS functionality
Create a RedwoodJS service to handle Infobip SDK interactions and an API function to expose this functionality.
Define your database schema for messages: Update
api/db/schema.prisma
to include a model for storing SMS messages:Apply database migrations: Run the migration command to apply the schema changes to your database:
This creates the
SmsMessage
table.Generate the Infobip service: Use Redwood's generator to create a service file:
This creates
api/src/services/infobip/infobip.ts
.Implement
sendSms
in the service: Openapi/src/services/infobip/infobip.ts
and add the logic to send SMS messages using the SDK and store the record.Infobip
client lazily using credentials from.env
. Notes verifyAuthType
and the SDK method/payload/response structure against official documentation.sendSms
function takes recipient (to
), messagetext
, and an optionalfrom
sender ID.channels.sms.send
method (verify this against current documentation).SmsMessage
table) along with relevant IDs and status information returned by Infobip (verify response structure).{ success: false, … }
) instead of throwing, which is suitable for GraphQL resolvers.logger
is included.Expose the service via GraphQL API: Create a GraphQL mutation to trigger the
sendSms
service.This generates
api/src/graphql/sms.sdl.ts
. Define the mutation:sendSms
service function implemented above matches this SDL, returning theSmsSendResponse
type including theerrorMessage
on failure. The@requireAuth
directive requires Redwood's authentication. Remove it for testing without auth, but secure it for production.Build the inbound webhook API
This is the core of two-way messaging – receiving messages from Infobip. Create a standard Redwood API function (REST-like) to act as the webhook receiver.
Generate Webhook API Function:
This creates
api/src/functions/infobipWebhook.ts
. The--no-auth
flag makes it publicly accessible, which is necessary for Infobip to reach it. We will add security manually via signature verification.Implement Webhook Handler Logic: Open
api/src/functions/infobipWebhook.ts
and implement the handler. This function needs to:verifyInfobipSignature
): This is paramount. The function is now uncommented. Extremely strong warnings were added emphasizing the need to verify the header name, algorithm, and signature format against official Infobip documentation for SMS webhooks.results
array is explicitly called out as an assumption that needs verification.infobipMessageId
remains crucial for handling potential webhook retries.SmsMessage
withdirection: 'INBOUND'
.// TODO:
comment remains, but the surrounding text now better explains its purpose as the integration point for application-specific actions.statusCode: 200
acknowledges successful receipt to Infobip. Non-2xx codes signal issues.Configure Infobip webhook settings
Tell Infobip where to send incoming messages.
Expose your local endpoint: For development, expose your RedwoodJS API endpoint to the public internet. Tools like
ngrok
orcloudflared
can do this.yarn rw dev
(runs on port 8911 for the API by default).ngrok http 8911
https://abcdef123456.ngrok.io
). Your webhook endpoint URL will be this base URL plus the Redwood function path:https://abcdef123456.ngrok.io/infobipWebhook
Configure the webhook in Infobip:
https://your-app.com/api/infobipWebhook
). Ensure it uses HTTPS.INFOBIP_WEBHOOK_SECRET
from your.env
). This allows Infobip to calculate the signature it sends in the header, enabling yourverifyInfobipSignature
function to work. If Infobip does not provide a specific field for a shared secret for signature generation for SMS webhooks, consult their documentation on how they recommend securing inbound SMS webhooks (e.g., Basic Auth, IP allow-listing, or another mechanism). Do not proceed without confirming Infobip's documented security method.Test your webhook:
SmsMessage
table and verify the inbound message appears withdirection: "INBOUND"
.Implement error handling and logging
try…catch
blocks. ThesendSms
service returns structured errors.logger.error
.errorMessage
field of theSmsMessage
model.logger
) is used. Configure log levels inapi/src/lib/logger.ts
as needed (e.g.,level: 'debug'
for development).findUnique
byinfobipMessageId
) handles duplicates caused by retries.sendSms
service (e.g., using libraries likeasync-retry
with exponential backoff) if the initial Infobip API call fails due to transient network issues or temporary Infobip problems (e.g., 5xx errors from their API).Design your database schema
SmsMessage
model inschema.prisma
(defined earlier) provides the structure.db
imported fromsrc/lib/db
) is used in the service and webhook function for database operations (create
,findUnique
).yarn rw prisma migrate dev
handles schema changes. Commit migration files (api/db/migrations/*
) to version control.infobipMessageId
,sender
,recipient
, andcreatedAt
. Prisma adds indexes on@id
and@unique
fields automatically. Add@index([sender, createdAt])
if you query by sender frequently.Secure your SMS integration
INFOBIP_API_KEY
andINFOBIP_BASE_URL
securely in.env
and never commit them to version control. Use environment variable management in your deployment environment.sendSms
mutation, Redwood automatically provides some input type validation. Add more specific validation (e.g., phone number format using a library likelibphonenumber-js
) in your service if needed.sendSms
endpoint and potentially the webhook endpoint from abuse or accidental loops. RedwoodJS doesn't have built-in rate limiting for API functions/GraphQL. Implement it using:rate-limiter-flexible
,express-rate-limit
adapted for serverless contexts). Search for libraries compatible with your deployment target (e.g., "rate limiting middleware for AWS Lambda" or specific solutions for Vercel/Netlify Edge Functions).sendSms
GraphQL mutation uses@requireAuth
. Ensure proper authentication and authorization are enforced on endpoints that trigger actions or expose sensitive data.Handle special cases and compliance
+15551234567
). Use libraries likelibphonenumber-js
for parsing and validation, especially for user-provided input.Testing your integration
Before deploying to production, thoroughly test both outbound and inbound messaging:
Test outbound SMS
Using GraphQL Playground:
yarn rw dev
http://localhost:8911/graphql
success: true
and check your database for the outbound record.Check message delivery:
Test inbound SMS
Send test message:
Verify database storage:
yarn rw prisma studio
SmsMessage
table for the inbound message.sender
,recipient
,body
, andinfobipMessageId
are populated correctly.Test error scenarios:
Load testing considerations
For production deployments handling high volume:
Deploying to production
Deploy your RedwoodJS application with SMS capabilities:
Environment configuration
INFOBIP_BASE_URL
INFOBIP_API_KEY
INFOBIP_WEBHOOK_SECRET
DATABASE_URL
.env
files to version control.Deployment platforms
Post-deployment checklist
sendSms
endpoint.Frequently asked questions
How do I handle multiple Infobip numbers? Add a
phoneNumber
field to your database schema and pass it as thefrom
parameter when sending. Configure separate webhooks in Infobip for each number, or use a query parameter to differentiate them.Can I send MMS or multimedia messages? Infobip supports MMS through their API. Update the SDK call to use the MMS endpoint and include media URLs in the payload. Refer to Infobip's MMS documentation for specific requirements.
How do I implement conversation threading? Store a
conversationId
orthreadId
in your database to group related messages. Link inbound and outbound messages by phone number and timestamp to create conversation views.What happens if my webhook endpoint is down? Infobip will retry webhook delivery according to their retry policy (typically exponential backoff). Check Infobip documentation for specific retry behavior and implement the idempotency check to handle duplicates.
How do I handle international phone numbers? Always use E.164 format (
+
followed by country code and number). Use thelibphonenumber-js
library to parse and validate international numbers before storing or sending.Can I schedule SMS messages for later delivery? Yes, use Infobip's scheduling feature by adding a
sendAt
parameter to your SMS payload with an ISO 8601 timestamp. Store the scheduled time in your database for reference.How do I track message costs? Enable cost tracking in your Infobip account and use their reporting API to fetch cost data. Store the
bulkId
from Infobip responses to correlate messages with billing reports.Next steps and enhancements
Extend your two-way SMS integration: