Frequently Asked Questions
You can send WhatsApp messages from a Next.js application by using AWS Lambda as the backend and the Meta Business API. Create a Next.js API route that triggers a Lambda function, which securely retrieves your WhatsApp API credentials from AWS Secrets Manager and sends the message via the Meta Graph API.
AWS Lambda provides serverless compute for executing the message-sending logic. It retrieves credentials from AWS Secrets Manager and interacts with the Meta Graph API without requiring you to manage server infrastructure.
AWS Secrets Manager securely stores sensitive information like your WhatsApp API access token, protecting it from exposure in your code or environment variables. The Lambda function retrieves the token from Secrets Manager at runtime.
Message templates are mandatory for production applications, particularly for business-initiated conversations outside the 24-hour customer service window, or for sending notifications. You must use pre-approved templates by Meta to comply with their policies.
While Meta provides a temporary test phone number for development, it has limitations and is unsuitable for production. You must register your own business phone number through the Meta platform for production messaging.
Create a Meta App, enable the WhatsApp product, note the Phone Number ID, add your test phone number as a recipient, and generate a permanent access token for a system user. This access token is essential for interacting with the WhatsApp Business API.
The core AWS services are Lambda for serverless execution, Secrets Manager for storing API credentials, and IAM for managing permissions. You may also optionally utilize the AWS CLI/SDK for local deployment.
In the AWS Lambda console, create a new function using Node.js as the runtime. Configure the function's execution role with access to Secrets Manager. Finally, write your function code to fetch secrets and use Axios or another HTTP client to send requests to the Meta API.
Implement robust phone number validation using libraries like `libphonenumber-js` for ensuring E.164 formatting. Verify numbers within the Next.js API route before passing them to the Lambda function.
Protect your Next.js API route with authentication/authorization mechanisms, validate phone numbers thoroughly, use IAM least privilege for AWS resources, and implement rate limiting to prevent abuse of your API.
Implement detailed logging, define standard error responses, and consider retry mechanisms only for transient network errors or AWS service issues. For persistent Lambda failures, use Lambda Destinations (SQS or another Lambda function) for further processing.
Axios is used within the AWS Lambda function to make HTTP POST requests to the Meta Graph API. These requests send the actual WhatsApp messages, containing the recipient's phone number and the message content within the body of the request.
You can manually deploy your Lambda code as a zip file containing the function's logic and dependencies. For production, utilize infrastructure-as-code tools such as AWS CDK, Serverless Framework, SAM, or Terraform for a more reproducible and efficient deployment process.
Store opt-out information (e.g., using a database) and ensure your Lambda function checks this status before attempting to send any message. Respecting user choices regarding communication is vital for compliance and user trust.
Leverage message templates with language packs to handle different languages and locales appropriately. Ensure your message content is correctly translated and localized for the intended recipient.
This guide provides a step-by-step walkthrough for building a system where your Next.js application can trigger WhatsApp messages using AWS Lambda as the backend processor and the official Meta (WhatsApp) Business API for delivery. We'll cover everything from setting up your AWS and Meta accounts to deploying and testing the final solution.
This approach enables your application to send notifications, alerts, or other messages directly to users on WhatsApp, leveraging the scalability and security of AWS services. We use
AWS Lambda
for serverless execution,AWS Secrets Manager
for securely storing API credentials, and theMeta Graph API
for interacting with WhatsApp.Project Overview and Goals
Goal: To create a secure and scalable pipeline enabling a Next.js application to send WhatsApp messages via an API call.
Problem Solved: Provides a reliable way to integrate WhatsApp messaging into web applications without managing complex messaging infrastructure directly, suitable for notifications, alerts, or potentially customer service interactions (within Meta's policies).
Technologies:
AWS Lambda
.Architecture:
Prerequisites:
Secrets Manager
secrets.Final Outcome: A Next.js application with an API endpoint (e.g.,
/api/send-whatsapp
) that accepts a recipient phone number and message text, triggers anAWS Lambda
function, which securely retrieves credentials and sends the message via theMeta API
to the recipient's WhatsApp.1. Setting up the Infrastructure and Credentials
This section covers the essential groundwork: configuring Meta for WhatsApp API access and setting up AWS resources.
1.1. Configure Meta for Developers and WhatsApp
You need to create a Meta App, enable WhatsApp, generate credentials, and add a test recipient.
Create a Meta App:
My Apps
->Create App
.Other
->Next
.Business
as the app type ->Next
.App name
(e.g.,MyNextJsWhatsAppSender
), yourApp contact email
.Meta Business Account
. If you don't have one, you might need to create it. Use this term consistently.Create app
and complete any security checks.Add WhatsApp Product:
Add products to your app
section.WhatsApp
and clickSet up
.Continue
.Note Phone Number ID and Add Test Recipient:
WhatsApp
->API Setup
page.Send and receive messages
, Meta provides a temporary Test Phone Number. Note thePhone number ID
associated with this test number. You'll need it later.To
field underSend messages with the API
, add your personal phone number (including country code, e.g.,15551234567
) that has WhatsApp installed. ClickSend
.Create a System User and Generate Permanent Token:
Users
->System users
, clickAdd
.System user name
(e.g.,whatsapp-api-user
), set theSystem user role
to Admin. ClickCreate system user
.whatsapp_business_management
,whatsapp_business_messaging
) is sufficient for your use case, following the principle of least privilege.Add assets
.Apps
in the left column.MyNextJsWhatsAppSender
).Manage App
(Full Control) permissions for this app.Save Changes
.Generate new token
.Token expiration
to Never.Available permissions
, select:whatsapp_business_management
whatsapp_business_messaging
Generate token
.WHATSAPP_ACCESS_TOKEN
.1.2. Set up AWS IAM User (for Deployment/Local SDK use)
Create an IAM user with programmatic access to manage AWS resources if you plan to deploy or test locally using the AWS SDK. If deploying via a CI/CD pipeline with assumed roles, this specific user might not be needed for the pipeline itself.
Users
->Create user
.User name
(e.g.,nextjs-whatsapp-deployer
).Provide user access to the AWS Management Console - *optional*
if desired. Crucially, ensure you enable Programmatic access if you intend to use AWS CLI/SDK locally with access keys.AWSLambda_FullAccess
(or more restricted permissions likeiam:PassRole
,lambda:CreateFunction
,lambda:UpdateFunctionCode
, etc.)SecretsManagerReadWrite
(or more restricted)IAMFullAccess
(needed to create the Lambda execution role, use with extreme caution and replace with minimal permissions likeiam:CreateRole
,iam:AttachRolePolicy
,iam:GetRole
for the specific role in production)Next
, add tags (optional), and clickCreate user
.AWS_ACCESS_KEY_ID
andAWS_SECRET_ACCESS_KEY
for local configuration. Configure your AWS CLI with these credentials usingaws configure
.1.3. Store WhatsApp Token in AWS Secrets Manager
Never hardcode sensitive tokens in your code or Lambda environment variables.
Store a new secret
.Other type of secret
.Secret key/value
:WHATSAPP_ACCESS_TOKEN
.Add row
.WHATSAPP_PHONE_NUMBER_ID
.Phone Number ID
you noted from the Meta API Setup page.aws/secretsmanager
is usually fine). ClickNext
.Secret name
(e.g.,whatsapp/api/credentials
). Remember this name. Add a description. ClickNext
.Next
.Store
.arn:aws:secretsmanager:us-east-1:123456789012:secret:whatsapp/api/credentials-XXXXXX
).1.4. Set up Next.js Project
Initialize a new Next.js project and install dependencies. We will use the AWS SDK for JavaScript v3 throughout for consistency.
Create Project:
(Choose options like TypeScript, App Router, etc., as desired. This guide assumes JavaScript and Pages Router for simplicity, but concepts apply to App Router).
Install Dependencies (for Next.js API Route):
@aws-sdk/client-lambda
: AWS SDK v3 client for invoking Lambda functions from your Next.js API route.axios
: For making HTTP requests (if needed elsewhere in Next.js, not directly used in the API route example).dotenv
: To manage environment variables locally.Note: The AWS Lambda function itself will also need dependencies (
@aws-sdk/client-secrets-manager
,axios
). These must be included in the Lambda deployment package (see Section 2), not necessarily installed in the Next.js project'snode_modules
.Configure Environment Variables (Local): Create a file named
.env.local
in the root of your Next.js project. Do not commit this file to Git.AWS_REGION
: The AWS region where you created yourSecrets Manager
secret and will deploy your Lambda.LAMBDA_FUNCTION_NAME
: The name you will give your Lambda function in AWS.SECRET_ARN
(For Lambda): The ARN of the secret stored inSecrets Manager
. This will be configured directly in the Lambda environment settings, not in the Next.js.env.local
.2. Implementing Core Functionality (AWS Lambda)
This Lambda function retrieves the WhatsApp token from
Secrets Manager
and calls theMeta API
. It uses the AWS SDK v3.Create Lambda Function:
Create function
.Author from scratch
.SendWhatsAppMessageLambda
(or the name you chose in.env.local
).Node.js 18.x
(or a later supported version that includes AWS SDK v3, or bundle it).x86_64
(orarm64
).Change default execution role
.Create a new role with basic Lambda permissions
. Name it something descriptive likeSendWhatsAppMessageLambdaRole
.Create function
.Add Secrets Manager Permissions to Lambda Role:
Configuration
->Permissions
tab.Execution role
name (e.g.,SendWhatsAppMessageLambdaRole
). This opens the IAM console.Add permissions
->Attach policies
.SecretsManagerReadWrite
policy. Warning: This grants write access too. For better security, create a custom inline policy instead.Add permissions
->Create inline policy
.Secrets Manager
.Read
-> SelectGetSecretValue
.Add ARN
. Paste the ARN of the secret you created earlier (arn:aws:secretsmanager:REGION:ACCOUNT_ID:secret:whatsapp/api/credentials-XXXXXX
). ClickAdd ARNs
.Review policy
. Give it a name (e.g.,AllowReadWhatsAppSecret
). ClickCreate policy
.AWSLambdaBasicExecutionRole
policy is usually attached by default and includes this:logs:CreateLogGroup
,logs:CreateLogStream
,logs:PutLogEvents
).Configure Lambda Environment Variables:
Configuration
->Environment variables
.Edit
.Add environment variable
.SECRET_ARN
, Value: Paste the ARN of your secret inSecrets Manager
.AWS_NODEJS_CONNECTION_REUSE_ENABLED
, Value:1
(Good practice for performance).Save
.Write Lambda Function Code (
index.mjs
):Code
tab in your Lambda function.index.mjs
with the following code. This uses Node.js 18.x features and AWS SDK v3.@aws-sdk/client-secrets-manager
,axios
), they must be included in your Lambda deployment package (e.g., in anode_modules
folder within the zip file).Deploy Lambda Code:
lambda-package
).index.mjs
file inside it.cd lambda-package
.npm init -y && npm install @aws-sdk/client-secrets-manager axios --save-prod
.cd ..
.zip -r function.zip lambda-package
.Code
tab), clickUpload from
->.zip file
. Upload yourfunction.zip
.3. Building the API Layer (Next.js API Route)
This API route in your Next.js app will receive requests from the frontend and invoke the Lambda function using AWS SDK v3.
Create the API Route File: Create
pages/api/send-whatsapp.js
(orapp/api/send-whatsapp/route.ts
if using App Router).Testing the API Route: Once your Next.js app is running locally (
npm run dev
), you can test the API endpoint usingcurl
or a tool like Postman. ReplaceYOUR_TEST_PHONE_NUMBER
with the number you verified in Meta (including country code, no+
or spaces).You should receive a JSON response indicating success or failure, and a message should appear on your test WhatsApp number. Check your Lambda's CloudWatch logs for detailed execution information.
Sections 4-10: Production Considerations (Summarized)
The previous sections cover the core implementation. For a production-ready system, consider these crucial aspects:
Secrets Manager
. Ensure you understand Meta's API versioning and update your Lambda code accordingly (e.g., thev19.0
in the URL).Meta API
calls might lead to duplicate messages. Consider retries only for transient network errors or AWS service issues (likeSecrets Manager
throttling or Lambda invocation errors), possibly with exponential backoff. For persistent Lambda failures, consider using Lambda Destinations (like an SQS queue or another Lambda) to handle failed event payloads for later inspection or reprocessing./api/send-whatsapp
endpoint. Ensure only authenticated and authorized users/systems can trigger messages (e.g., using NextAuth.js, Clerk, or API keys validated server-side).libphonenumber-js
for proper E.164 validation). Sanitize message content to prevent injection attacks if user input forms part of the message.express-rate-limit
withnext-connect
, Vercel's built-in features, or anAPI Gateway
if used) to prevent abuse, manage costs, and respectMeta API
limits.Meta API
(includingnamespace
,name
,language
, andcomponents
with parameters). See Meta documentation on templates. Sending free-form text is highly restricted.+
followed by country code and number).