Developer Guide: Sending SMS with AWS SNS in Next.js using Node.js
This guide provides a step-by-step walkthrough for integrating Amazon Simple Notification Service (SNS) into a Next.js application to send SMS messages using Node.js for the backend logic via API routes.
Project Overview and Goals
What We're Building: We will build a simple Next.js application featuring a backend API endpoint. This endpoint will accept a phone number and a message, then use the AWS SDK for JavaScript (v3) to interact with AWS SNS and send the message as an SMS to the specified number.
Problem Solved: This implementation enables developers to add reliable SMS notification capabilities (like OTPs, alerts, or status updates) to their Next.js applications without managing complex telephony infrastructure. AWS SNS handles the carrier integrations and delivery complexities.
Technologies Used:
- Next.js: A React framework providing server-side rendering, static site generation, and simplified API route creation. We'll use API routes for our backend logic.
- Node.js: The runtime environment for our Next.js API route.
- AWS SDK for JavaScript v3 (
@aws-sdk/client-sns
): The official AWS SDK used to interact with SNS programmatically. - AWS Simple Notification Service (SNS): The managed AWS service that facilitates sending messages, including SMS.
- AWS Identity and Access Management (IAM): Used to securely grant our application the necessary permissions to publish messages via SNS.
System Architecture:
The data flow is straightforward:
- Client Request: A client (e.g., a frontend form, Postman, curl) sends a POST request to our Next.js API endpoint (
/api/send-sms
) containing the recipient's phone number and the message content. - Next.js API Route: The Node.js code within the API route receives the request.
- AWS SDK: The API route uses the
@aws-sdk/client-sns
library, configured with appropriate IAM credentials, to prepare and send aPublishCommand
to AWS SNS. - AWS SNS: SNS receives the command, validates it, and attempts to deliver the SMS message to the specified phone number via downstream carriers.
- SMS Delivery: The recipient receives the SMS message on their mobile device.
- API Response: The Next.js API route sends a response back to the client indicating success (with a message ID) or failure.
Flow: Client
-> Next.js API Route
-> AWS SDK
-> AWS SNS
-> Mobile Network
-> Recipient
Prerequisites:
- Node.js (v18.x or v20.x LTS recommended; v14.x+ required for AWS SDK v3 ES6 modules)
- npm or yarn package manager
- An active AWS account
- Basic familiarity with Next.js and JavaScript/Node.js
- AWS CLI installed and configured (optional, but helpful for local credential management)
Expected Outcome: By the end of this guide, you will have a functional Next.js API endpoint capable of sending SMS messages via AWS SNS, along with foundational knowledge for error handling, security, and deployment considerations.
1. Setting up the Project
Let's create a new Next.js project and install the necessary dependencies.
-
Create Next.js App: Open your terminal and run:
npx create-next-app@latest sns-sms-app
Choose your preferred settings when prompted (e.g., TypeScript: No, ESLint: Yes, Tailwind CSS: No,
src/
directory: No, App Router: No (or Yes, adapting API route location), import alias: default). -
Navigate to Project Directory:
cd sns-sms-app
-
Install Dependencies: We need the AWS SDK for SNS and
dotenv
for managing environment variables locally.npm install @aws-sdk/client-sns dotenv
Alternatively using yarn:
yarn add @aws-sdk/client-sns dotenv
@aws-sdk/client-sns
: The modular AWS SDK package for SNS.dotenv
: Loads environment variables from a.env
file intoprocess.env
during development.
-
Configure Environment Variables: Create a file named
.env.local
in the root of your project. This file will store your AWS credentials securely during local development. Never commit this file to Git.Add the following variables, leaving the values blank for now. We'll obtain these in the AWS Setup step.
# .env.local AWS_ACCESS_KEY_ID= AWS_SECRET_ACCESS_KEY= AWS_REGION=
AWS_ACCESS_KEY_ID
: Your AWS IAM user's access key.AWS_SECRET_ACCESS_KEY
: Your AWS IAM user's secret key.AWS_REGION
: The AWS region where you want to use SNS (e.g.,us-east-1
). SMS availability varies by region.us-east-1
has broad support.
-
Update
.gitignore
: Ensure.env.local
is listed in your.gitignore
file (Create Next App usually adds.env*.local
automatically). If not, add it:# .gitignore .env*.local
-
Project Structure: Your basic structure will look like this (assuming
pages
router):sns-sms-app/ ├── pages/ │ ├── api/ │ │ └── # We will create send-sms.js here │ ├── _app.js │ └── index.js ├── public/ ├── styles/ ├── .env.local # Your local secrets (DO NOT COMMIT) ├── .gitignore ├── next.config.js ├── package.json └── README.md
We will create our API logic inside the
pages/api/
directory.
2. AWS Setup (IAM User)
To allow our Next.js application to send SMS via SNS, we need to create an IAM user with specific permissions.
- Navigate to IAM: Log in to your AWS Management Console and go to the IAM service.
- Create User:
- Click on
Users
in the left sidebar, then clickCreate user
. - Enter a User name (e.g.,
nextjs-sns-sender
). Do not check ""Provide user access to the AWS Management Console"". ClickNext
. - Select
Attach policies directly
. - Click
Create policy
. This will open a new tab.
- Click on
- Create IAM Policy:
- In the new
Create policy
tab, select the JSON editor. - Paste the following policy document. This grants the minimum permission required to publish messages directly to phone numbers via SNS.
{ ""Version"": ""2012-10-17"", ""Statement"": [ { ""Sid"": ""AllowSNSDirectPublishSMS"", ""Effect"": ""Allow"", ""Action"": ""sns:Publish"", ""Resource"": ""*"" } ] }
- Explanation:
Action: ""sns:Publish""
: Allows the user to publish messages.Resource: ""*""
: Necessary when publishing directly to phone numbers using thePhoneNumber
parameter. If you were publishing only to specific SNS Topics, you would list their ARNs here for tighter security.
- Explanation:
- Click
Next
. - Give the policy a Name (e.g.,
SNSPublishDirectSMS
) and optionally a description. ClickCreate policy
.
- In the new
- Attach Policy & Create User:
- Go back to the
Create user
browser tab. Click the refresh button next toCreate policy
. - Search for the policy you just created (
SNSPublishDirectSMS
). - Check the box next to the policy. Click
Next
. - Review the user details and permissions. Click
Create user
.
- Go back to the
- Retrieve Access Keys (IMPORTANT):
- On the confirmation screen, click on the user name you just created (
nextjs-sns-sender
). - Go to the
Security credentials
tab. - Scroll down to
Access keys
and clickCreate access key
. - Select
Application running outside AWS
(or Command Line Interface if using AWS CLI profile). - Click
Next
. - Optionally add a description tag. Click
Create access key
. - CRITICAL: You will now see the Access key ID and Secret access key. Copy both immediately and store them securely. You will not be able to see the Secret access key again after leaving this screen.
- Paste these values into your
.env.local
file.# .env.local AWS_ACCESS_KEY_ID=YOUR_ACCESS_KEY_ID_HERE AWS_SECRET_ACCESS_KEY=YOUR_SECRET_ACCESS_KEY_HERE AWS_REGION=us-east-1 # Or your chosen supported region
- Click
Done
.
- On the confirmation screen, click on the user name you just created (
3. SNS Client Setup
Let's create a reusable SNS client instance.
-
Create Library File: Create a directory
lib
in your project root and add a filesnsClient.js
inside it.mkdir lib touch lib/snsClient.js
-
Instantiate SNS Client: Add the following code to
lib/snsClient.js
:// lib/snsClient.js import { SNSClient } from ""@aws-sdk/client-sns""; import ""dotenv/config""; // Ensure environment variables are loaded (especially for non-Next.js environments if reused) // The AWS SDK automatically searches for credentials in the following order: // 1. Environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN) // 2. Shared credential file (~/.aws/credentials) // 3. Shared configuration file (~/.aws/config) // 4. EC2 instance profile or ECS container credentials (if running on AWS) // Ensure your region is set correctly const region = process.env.AWS_REGION; if (!region) { console.warn( ""AWS_REGION environment variable not set. Defaulting may occur, but explicit setting is recommended."" ); // Optionally throw an error if region is absolutely required: // throw new Error(""AWS_REGION environment variable is required.""); } const snsClient = new SNSClient({ region: region, // Credentials are automatically sourced from environment variables or shared config. // You generally DO NOT need to pass credentials explicitly here if using .env.local or ~/.aws/credentials. }); export { snsClient };
- Explanation:
- We import the
SNSClient
from the SDK. - We import
dotenv/config
to ensure.env.local
is loaded if this module were ever run outside the Next.js context (Next.js loads.env.local
automatically for API routes). - We explicitly create the client, passing the
region
from our environment variables. The SDK handles finding theAWS_ACCESS_KEY_ID
andAWS_SECRET_ACCESS_KEY
fromprocess.env
automatically.
- We import the
- Explanation:
4. Building the API Layer
Now, we'll create the Next.js API route that uses our snsClient
to send the SMS.
-
Create API Route File: Create the file
pages/api/send-sms.js
. -
Implement API Logic: Paste the following code into
pages/api/send-sms.js
:// pages/api/send-sms.js import { snsClient } from ""../../lib/snsClient""; import { PublishCommand } from ""@aws-sdk/client-sns""; // Basic input validation function (customize as needed) const validateInput = (phoneNumber, message) => { if (!phoneNumber || typeof phoneNumber !== ""string"") { return ""Phone number is required and must be a string.""; } // E.164 format regex (basic check; more robust validation might be needed for production edge cases) // Allows '+' followed by 1 to 14 digits after the country code digit. const phoneRegex = /^\+[1-9]\d{1,14}$/; if (!phoneRegex.test(phoneNumber)) { return ""Invalid phone number format. Must be E.164 (e.g., +15551234567).""; } if (!message || typeof message !== ""string"" || message.trim().length === 0) { return ""Message is required and cannot be empty.""; } if (message.length > 1600) { // SNS automatically handles segmentation but good to have a sanity limit return ""Message exceeds maximum length (1600 characters).""; } return null; // Indicates valid input }; export default async function handler(req, res) { // Only allow POST requests if (req.method !== ""POST"") { res.setHeader(""Allow"", [""POST""]); return res.status(405).json({ success: false, error: `Method ${req.method} Not Allowed`, }); } const { phoneNumber, message } = req.body; // --- Input Validation (Security) --- const validationError = validateInput(phoneNumber, message); if (validationError) { console.warn(""Validation failed:"", validationError); return res.status(400).json({ success: false, error: validationError }); } // --- Set SMS Type (Optional but Recommended) --- // Default without MessageAttributes is Promotional. Transactional is better for OTPs/Alerts. // See section 8 for details. const messageAttributes = { ""AWS.SNS.SMS.SMSType"": { DataType: ""String"", StringValue: ""Transactional"", // Set to 'Transactional' for high priority (e.g., OTPs) // Change to 'Promotional' for marketing (lower cost/priority) }, // You can add other attributes like SenderID here if configured // ""AWS.SNS.SMS.SenderID"": { // DataType: ""String"", // StringValue: ""MySenderID"", // Your registered Sender ID // }, }; // --- Prepare SNS Publish Command --- const params = { Message: message, PhoneNumber: phoneNumber, // Must be in E.164 format MessageAttributes: messageAttributes, // Set SMS type (Transactional recommended for non-marketing) }; const command = new PublishCommand(params); // --- Send SMS via SNS --- try { const data = await snsClient.send(command); console.log(""SMS sent successfully. MessageId:"", data.MessageId); return res.status(200).json({ success: true, messageId: data.MessageId }); } catch (err) { console.error(""Error sending SMS via SNS:"", err); // Provide more specific feedback if possible let errorMessage = ""Failed to send SMS.""; if (err.name === ""InvalidParameterValueException"") { errorMessage = ""Invalid parameter provided to SNS. Check phone number format (E.164) or message content.""; } else if (err.name === ""AuthorizationErrorException"") { errorMessage = ""Authorization error. Check AWS credentials and IAM permissions.""; } else if (err.name === ""ThrottlingException"") { errorMessage = ""Request throttled by AWS. Please try again later.""; } else if (err.name === ""InternalErrorException"") { errorMessage = ""Internal server error on AWS side. Please try again later.""; } else if (err.name === ""PhoneNumberOptedOutException"") { errorMessage = ""Phone number is opted out of receiving SMS messages.""; } // Add more specific error checks based on potential SNS exceptions return res .status(500) .json({ success: false, error: errorMessage, details: err.message }); // Include err.message for detailed debugging if needed } }
-
Testing the Endpoint (curl): Make sure your Next.js development server is running (
npm run dev
oryarn dev
).Open a new terminal window and run the following
curl
command, replacing+15551234567
with a valid E.164 formatted phone number (ideally your own for testing) and customizing the message:curl -X POST http://localhost:3000/api/send-sms \ -H ""Content-Type: application/json"" \ -d '{ ""phoneNumber"": ""+15551234567"", ""message"": ""Hello from Next.js and AWS SNS! This is a test message."" }'
- Expected Request Body (JSON):
{ ""phoneNumber"": ""+1XXXXXXXXXX"", ""message"": ""Your message content"" }
- Expected Success Response (JSON):
You should receive the SMS shortly after seeing this response.
{ ""success"": true, ""messageId"": ""xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"" }
- Expected Error Response (JSON, e.g., validation):
{ ""success"": false, ""error"": ""Invalid phone number format. Must be E.164 (e.g., +15551234567)."" }
- Expected Request Body (JSON):
5. Implementing Error Handling and Logging
Our API route already includes basic error handling and logging:
try...catch
Block: Wraps thesnsClient.send()
call to catch exceptions during the SNS interaction.- Input Validation: Prevents invalid data from reaching the SNS publish command.
- Console Logging:
console.error
is used to log failures on the server-side (visible in your terminal during development or in Vercel/server logs when deployed).console.log
confirms successful sending.console.warn
logs validation failures.
- Specific Error Messages: The
catch
block attempts to identify common SNS error types (err.name
) to provide more user-friendly feedback in the API response, while still logging the full error details server-side. - HTTP Status Codes: Uses appropriate codes (200, 400, 405, 500) to signal the outcome.
Further Enhancements (Beyond Basic):
- Structured Logging: For production, use libraries like
Pino
orWinston
for structured JSON logs, making them easier to parse and analyze in log aggregation tools. - Error Tracking Services: Integrate services like Sentry or Datadog to capture, aggregate, and alert on application errors.
- Retry Mechanisms: While the AWS SDK might handle some transient network retries, for critical messages requiring guaranteed delivery attempts, consider implementing a queue-based system (like AWS SQS) with exponential backoff logic. The API route would push the message details to the queue, and a separate worker process would handle dequeuing, sending via SNS, and implementing retries on failure. This is more complex and usually reserved for high-throughput or high-reliability scenarios.
6. Database Schema and Data Layer
This specific guide focuses solely on sending an SMS via an API call and does not require a database.
If your application needed to store message history, user preferences, or associate SMS messages with specific users or events, you would typically:
- Choose a Database: PostgreSQL, MySQL, MongoDB, DynamoDB, etc.
- Design Schema: Define tables/collections (e.g.,
users
,sms_messages
with columns likemessage_id
,recipient_phone
,status
,sent_at
,user_id
,content
). Use an Entity Relationship Diagram (ERD) tool to visualize relationships. - Implement Data Layer: Use an ORM (like Prisma, TypeORM, Sequelize) or a database client library to interact with the database. Implement functions like
saveMessageRecord
,updateMessageStatus
. - Migrations: Use the ORM's migration tools (
prisma migrate dev
,sequelize db:migrate
) to manage schema changes. - Integration: Call data layer functions from your API route before or after sending the SMS to record the attempt and outcome.
This is beyond the scope of basic SNS sending but is a common next step in real-world applications.
7. Adding Security Features
Security is paramount, especially when dealing with external services and potentially user-provided data.
- Input Validation: (Implemented in API route) Crucial to prevent malformed requests and potential injection attacks (though less direct risk for SNS message content itself compared to SQL injection). Ensure phone numbers match E.164 and messages have reasonable length/content. Sanitize message content if it originates directly from untrusted user input.
- API Key Protection: (Implemented via
.env.local
and Environment Variables) Never hardcode AWS credentials in your source code. Use environment variables and ensure.env*.local
files are in.gitignore
. Use your deployment platform's secret management features (e.g., Vercel Environment Variables, AWS Secrets Manager). - IAM Least Privilege: (Implemented via IAM Policy) The IAM user
nextjs-sns-sender
only hassns:Publish
permission, limiting potential damage if credentials were compromised. Avoid using root account keys. - Rate Limiting: (Not Implemented - Recommended) Protect your API endpoint from abuse and control costs.
- Implement using libraries like
rate-limiter-flexible
orexpress-rate-limit
(if using Express middleware). - Leverage platform features (e.g., Vercel's rate limiting).
- Configure reasonable limits (e.g., 5 requests per minute per IP address).
- Implement using libraries like
- Authentication/Authorization: If the API endpoint should only be accessible by logged-in users or specific services, implement authentication (e.g., using NextAuth.js, JWT, or API keys for service-to-service communication) and authorization checks within the API route before processing the request.
- HTTPS: Ensure your Next.js application is served over HTTPS (handled automatically by platforms like Vercel).
8. Handling Special Cases
- E.164 Phone Number Format: (Handled via Validation) SNS strictly requires the E.164 format (
+
followed by country code and number, no spaces or dashes, e.g.,+12125551234
,+442071234567
). Your frontend or backend must ensure numbers are in this format before calling the API. - SMS Type (Transactional vs. Promotional): (Handled via
MessageAttributes
)- Promotional: (Default if
MessageAttributes
is omitted) Optimized for cost, lower delivery priority, may be blocked by DND (Do Not Disturb) registries. Suitable for marketing. - Transactional: (Set in our example code) Optimized for reliability, higher delivery priority, can often bypass DND. Use for critical messages like OTPs, alerts, order confirmations. Slightly higher cost per message.
- Modify the
StringValue
in themessageAttributes
object inpages/api/send-sms.js
based on your use case.
- Promotional: (Default if
- Opt-Out Handling: Users can reply ""STOP"" to opt-out of receiving messages. Sending to an opted-out number will fail (SNS returns
PhoneNumberOptedOutException
).- You can check if a number is opted out before sending using the
CheckIfPhoneNumberIsOptedOutCommand
from@aws-sdk/client-sns
. This adds latency but can prevent errors and save cost. See AWS SDK documentation for usage. Our basic error handling catches the exception after the send attempt.
- You can check if a number is opted out before sending using the
- Character Limits & Encoding: Standard SMS messages have limits (160 characters for GSM-7 encoding, 70 for UCS-2 used for non-Latin characters). SNS automatically handles segmentation for longer messages (sending multiple linked SMS), but each segment is billed separately. Be mindful of message length for cost.
- Sender ID: By default, messages may come from a shared short code or random long code number depending on the destination country. You can request dedicated short codes or long codes, or register an Alphanumeric Sender ID (where supported) through the AWS console for branding (subject to country regulations and additional cost). See ""Pinpoint SMS and voice settings"" in the AWS console. If registered, you can specify it via
MessageAttributes
.
9. Implementing Performance Optimizations
For basic, low-volume SMS sending, performance is usually not a major concern. The key points are:
- Asynchronous Operations: The
await snsClient.send(command)
call is asynchronous, meaning your Node.js process isn't blocked while waiting for SNS. This allows the API route to handle other requests efficiently. - Client Reuse: We instantiate the
snsClient
once (lib/snsClient.js
) and reuse it across API requests, avoiding the overhead of creating a new client for every call. - Caching: Not typically applicable for the sending action itself.
- High Throughput: If you need to send a very large volume of SMS messages quickly, sending them sequentially from a single API route instance can become a bottleneck. The recommended pattern is:
- API route receives request(s).
- API route pushes message details (recipient, content) onto a queue (e.g., AWS SQS).
- A separate backend worker process (e.g., an AWS Lambda function triggered by SQS, or a dedicated Node.js service) reads messages from the queue (potentially in batches) and calls
snsClient.send()
for each. This decouples sending from the initial request and enables parallel processing.
10. Adding Monitoring, Observability, and Analytics
Monitoring is essential to understand if your SMS sending is working correctly and cost-effectively.
- AWS CloudWatch Metrics: SNS automatically publishes metrics to CloudWatch in the region you're using. Key metrics include:
NumberOfMessagesPublished
: Successful requests to the SNS API.NumberOfNotificationsDelivered
: Successful deliveries to the carrier (doesn't guarantee final device delivery).NumberOfNotificationsFailed
: Deliveries that failed (e.g., invalid number, opted-out, carrier block).SMSMonthToDateSpentUSD
: Your spending.- Create CloudWatch Alarms on these metrics (e.g., alert if
NumberOfNotificationsFailed
spikes, or ifSMSMonthToDateSpentUSD
exceeds a budget).
- AWS CloudWatch Logs: Enable delivery status logging in your SNS settings (Account level -> Text messaging (SMS) -> Edit -> Delivery status logging). This provides detailed logs for each message attempt, including success/failure reasons, message IDs, and pricing, sent to a CloudWatch Log Group you specify. This is invaluable for troubleshooting specific delivery issues.
- Application Logs: (Implemented via
console.log
/console.error
) Your Next.js API route logs provide context about requests entering your system and any errors occurring before or during thesnsClient.send()
call. Ensure these logs are captured by your deployment platform (Vercel, AWS, etc.). - Health Checks: Implement a simple health check endpoint (e.g.,
/api/health
) in your Next.js app that returns a200 OK
status. Use monitoring services to ping this endpoint regularly to ensure your application is responsive. - Dashboards: Create a CloudWatch Dashboard visualizing the key SNS metrics (
NumberOfNotificationsDelivered
,NumberOfNotificationsFailed
,SMSMonthToDateSpentUSD
) alongside relevant application metrics.
11. Troubleshooting and Caveats
Common issues when sending SMS with SNS:
AuthorizationErrorException
: Almost always an IAM permissions issue or incorrect/missing AWS credentials.- Verify the
AWS_ACCESS_KEY_ID
andAWS_SECRET_ACCESS_KEY
in your environment variables are correct and belong to the IAM user (nextjs-sns-sender
). - Ensure the
SNSPublishDirectSMS
policy (or equivalent) is attached to the user and has""Action"": ""sns:Publish"", ""Resource"": ""*""
. - Check that the
AWS_REGION
environment variable matches the region where you expect SNS to operate.
- Verify the
InvalidParameterValueException
: Usually related to thePhoneNumber
format.- Ensure the number starts with
+
and includes the country code (E.164 format). No spaces, dashes, or parentheses. - Check that the
Message
content is valid (e.g., not excessively long if you added strict checks).
- Ensure the number starts with
- SMS Not Received (but API returns success):
- SNS Sandbox: New AWS accounts are placed in the SNS sandbox, which limits sending to verified phone numbers only and has low sending quotas. Verify destination numbers in the SNS console or request to move your account out of the sandbox via an AWS support case (Pinpoint SMS and voice settings -> Request production access). This is a very common issue for new users.
- Opted-Out Number: The recipient may have previously replied STOP. The API call will now likely fail with
PhoneNumberOptedOutException
. Check delivery status logs if enabled. - Invalid/Inactive Number: The phone number might be incorrect or no longer in service.
- Carrier Filtering: Mobile carriers may sometimes filter messages as spam, especially if coming from shared numbers or containing certain keywords. Using Transactional SMS type, dedicated numbers, or registered Sender IDs can help.
- Region Support: Ensure the destination country is supported for SMS sending from your chosen AWS region.
- Check CloudWatch Delivery Status Logs: If enabled, these provide the most detail on delivery failures after SNS accepts the message.
ThrottlingException
: You're exceeding SNS sending limits for your account or region. Slow down requests or request a limit increase via AWS support. Using a queue can help smooth out traffic.- Spending Limit Exceeded: Your account has a monthly SMS spending limit configured in SNS. Check and potentially increase it in the SNS console (Text messaging (SMS) settings).
- Region Mismatch: Ensure the
AWS_REGION
environment variable used by the SDK client matches the region where you configured any SNS settings (like spending limits or Sender IDs) and where your IAM user operates (though IAM is global, keys are generated globally).us-east-1
is often a safe default for broad SMS support.
12. Deployment and CI/CD
Deploying your Next.js application requires ensuring your AWS credentials and region are securely available in the production environment.
Key Steps:
- Environment Variables: Do not commit your
.env.local
file. Use your deployment platform's interface to set the required environment variables:AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
AWS_REGION
- Example (Vercel): Go to your Project Settings -> Environment Variables. Add each variable, ensuring they are set for the ""Production"" environment (and ""Preview""/""Development"" if needed). Keep them ""Secret"".
- Example (AWS Amplify/EC2/Lambda): Use the service's environment variable configuration, AWS Secrets Manager, or Parameter Store.
- Build Process: Your standard Next.js build process (
npm run build
) remains the same. - Deployment: Deploy using your platform's CLI (
vercel deploy --prod
) or Git-based deployment workflow. The deployed application (specifically the API route) will pick up the environment variables set in the platform. - CI/CD Pipeline:
- Use standard CI/CD tools (GitHub Actions, GitLab CI, Jenkins).
- The pipeline needs secure access to deploy to your platform.
- Crucially, ensure AWS secrets are handled securely, often using the CI/CD platform's secrets management features, injecting them only during the deployment step, not during build if possible.
- Rollback: Familiarize yourself with your deployment platform's rollback procedures (e.g., Vercel's previous deployments) in case a deployment introduces issues.
13. Verification and Testing
Thorough testing ensures your SMS functionality works as expected.
- Manual Verification:
- Deploy your application to a preview or production environment.
- Use
curl
or Postman (as shown in Section 4) to hit your deployed API endpoint (https://your-app-domain.com/api/send-sms
). - Use your own phone number (or a colleague's) as the recipient (ensure it's verified if still in the SNS Sandbox).
- Verify:
- You receive a
200 OK
success response with amessageId
. - The SMS message arrives on the phone.
- The message content is correct.
- You receive a
- Test edge cases: invalid phone number format, empty message, excessively long message. Verify you get the expected
400 Bad Request
or500 Internal Server Error
responses with appropriate error messages.
- Check CloudWatch Metrics/Logs:
- After sending test messages, go to the CloudWatch console in your selected AWS region.
- Check SNS metrics (
NumberOfMessagesPublished
,NumberOfNotificationsDelivered
,NumberOfNotificationsFailed
). - If delivery status logging is enabled, check the corresponding Log Group for detailed success/failure records.
- Automated Testing (Recommended):
- API Integration Tests: Use tools like Jest or Vitest with
supertest
to make actual HTTP requests to your local running dev server's API endpoint. You'd likely mock thesnsClient.send
call to avoid sending real SMS during tests.
- API Integration Tests: Use tools like Jest or Vitest with