Frequently Asked Questions
Use NestJS with the AWS Pinpoint SMS and Voice API v2 and Amazon S3. Create a NestJS API endpoint to handle requests, upload media to S3, and send MMS via Pinpoint. This setup enables your application to send rich media content to users.
AWS Pinpoint SMS and Voice API v2 is the service used to send SMS and MMS messages. The v2 version specifically provides the SendMediaMessage capability, which allows you to send multimedia content.
NestJS provides a structured and efficient way to build server-side applications. Its modular architecture, dependency injection, and TypeScript support make it a robust choice for integrating with AWS services.
Use a bucket policy when you need to grant read access to your S3 bucket for AWS Pinpoint without making objects public. This is a more secure way to manage access control than relying on ACLs for every single object.
Yes, the provided DTO uses international format validation (E.164) for phone numbers. Ensure your AWS Pinpoint Origination Identity is configured for international messaging if needed.
Store your AWS credentials (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION) securely in a .env file. Then, use NestJS's ConfigModule to load these variables into your application, avoiding hardcoding and improving testability.
Amazon S3 stores the media files (images, videos) that are attached to your MMS messages. The NestJS application uploads the media to S3 and then provides the S3 URI to Pinpoint for sending.
AWS Pinpoint needs access to the media files stored in S3 to include them in the MMS messages. This is managed via a bucket policy, which is a secure way to control access without making your files public.
Use the FileInterceptor from @nestjs/platform-express to intercept and process the incoming media file. Combine this with ParseFilePipe and validators like FileTypeValidator and MaxFileSizeValidator to ensure only valid files are accepted.
You'll need sms-voice:SendMediaMessage to send MMS via Pinpoint, s3:PutObject to upload media to S3, and potentially s3:PutObjectAcl depending on how you manage S3 access control.
Implement error handling for both S3 upload and Pinpoint sending operations. Catch AWS SDK errors, log them with stack traces, and throw appropriate HTTP exceptions. Consider using a custom exception filter to standardize error responses.
Create separate modules for AWS interactions (AwsModule) and MMS logic (MmsModule). Use services to encapsulate logic and controllers to expose API endpoints. This provides a clean and maintainable structure.
You'll need Node.js, an AWS account with proper IAM permissions, AWS CLI (optional), NestJS CLI, an MMS-capable phone number or short code registered with AWS Pinpoint, and a basic understanding of TypeScript, NestJS, and REST APIs.
Although not covered in the initial setup, consider implementing a database schema (e.g., using TypeORM or Prisma) to log MMS send attempts, status, and responses. This enables better tracking, analysis, and auditing.
Production-Ready Guide: Sending MMS with NestJS and AWS Pinpoint
This guide provides a comprehensive, step-by-step walkthrough for building a production-ready system to send Multimedia Messaging Service (MMS) messages using NestJS and the AWS Pinpoint SMS and Voice API v2. We'll cover everything from project setup and core implementation to error handling, security, and deployment.
By the end of this tutorial, you will have a functional NestJS API endpoint capable of accepting a destination phone number, a message body, and a media file, uploading the file to Amazon S3, and sending an MMS message via AWS Pinpoint. This solves the need for applications to programmatically send rich media content to users' mobile devices, enhancing engagement beyond simple text messages.
Technologies Used:
SendMediaMessagecapability.multipart/form-data, used for file uploads.System Architecture:
Prerequisites:
npm install -g @nestjs/cli).1. Setting Up the Project
Let's initialize our NestJS project and install necessary dependencies.
1. Create NestJS Project:
Open your terminal and run:
Choose your preferred package manager (npm or yarn) when prompted.
2. Install Dependencies:
We need packages for AWS SDK v3, configuration management, validation, file uploads, and unique IDs.
3. Environment Variables Setup:
Create a
.envfile in the project root for storing sensitive configuration. Never commit this file to version control. Add a.env.examplefile to track required variables.Ensure your
.gitignorefile includes.env.4. AWS IAM Setup:
Create an IAM user (or use an existing one/role) with programmatic access. Attach a policy granting the necessary permissions.
Minimal Permissions Policy Example (
mms-sender-policy.json):Create the user/role and attach this policy.
Record the
AWS_ACCESS_KEY_IDandAWS_SECRET_ACCESS_KEYin your.envfile.Why these permissions?
sms-voice:SendMediaMessage: Allows sending MMS messages via Pinpoint v2.s3:PutObject: Allows uploading the media file to your S3 bucket.s3:PutObjectAcl: Might be needed depending on your bucket's access control strategy.5. AWS S3 Bucket Setup:
Create Bucket: Use the AWS console or CLI to create an S3 bucket in the same AWS Region as your Pinpoint Origination Identity. Choose a unique name.
Block Public Access: Generally recommended to keep "Block all public access" settings enabled unless you have a specific reason not to.
Bucket Policy for Pinpoint Access: Pinpoint needs permission to read the objects you upload. Add a bucket policy to grant this access. Replace
YOUR_MMS_MEDIA_BUCKET_NAMEandYOUR_AWS_ACCOUNT_ID.6. AWS Pinpoint Origination Identity:
AWS_PINPOINT_ORIGINATION_IDENTITYvariable in your.envfile.7. Configure NestJS ConfigModule:
Import and configure
ConfigModulein your main application module (app.module.ts) to load environment variables.Why
ConfigModule? It provides a structured way to access environment variables throughout the application via dependency injection, avoiding directprocess.envaccess and enhancing testability.2. Implementing Core Functionality
We'll create dedicated modules and services for AWS interactions and MMS logic.
1. AWS Module & Service:
This centralizes AWS SDK client initialization.
Create Module/Service:
Implement AWS Service (
src/aws/aws.service.ts):Update AWS Module (
src/aws/aws.module.ts):Why this structure?
ConfigServicefor credentials, avoiding hardcoding.OnModuleInitensures clients are ready when the module initializes.@Global()makes theAwsServiceeasily injectable across the app.2. MMS Module & Service:
This module handles the specific logic for uploading to S3 and sending MMS via Pinpoint.
Create Module/Service:
Implement MMS Service (
src/mms/mms.service.ts):Update MMS Module (
src/mms/mms.module.ts):Why this structure?
AwsServiceandConfigServicefor dependencies.uuidfor unique filenames in S3, preventing collisions.uploadMediaToS3andsendMms.3. Building the API Layer
We'll create a controller with an endpoint to receive MMS requests and trigger the service.
Create Controller:
Create DTO (Data Transfer Object) for Validation:
Create a file
src/mms/dto/send-mms.dto.ts:Implement MMS Controller (
src/mms/mms.controller.ts):Why this structure?
@nestjs/platform-express'sFileInterceptorto handlemultipart/form-data.ParseFilePipewith validators (FileTypeValidator,MaxFileSizeValidator) for robust file validation before hitting the service logic.SendMmsDtoand relies onValidationPipe(enabled globally later) for validating text fields.MmsServiceto delegate the core logic.202 Acceptedas the process involves external asynchronous systems.Enable Global Validation Pipe:
Modify
src/main.tsto enable automatic validation using the DTOs.Testing the Endpoint:
You can use
curlor Postman to test.Curl Example:
Postman:
POST.http://localhost:3000/mms/send.Bodytab, selectform-data.KEYnameddestinationPhoneNumber, enter a valid E.164 number inVALUE.KEYmessageBody, enter text inVALUE.KEYmediaFile. In theVALUEcolumn, click the dropdown and selectFile. Then clickSelect Filesand choose your media file.Send.Expected Response (Success - 202 Accepted):
Expected Response (Validation Error - 400 Bad Request):
4. Integrating with Third-Party Services (AWS)
This section summarizes the key integration points already covered:
.envandConfigModule. Accessed inAwsServiceto initialize SDK clients..env. Bucket Policy allows Pinpoint read access. Upload logic inMmsService..env. Used inMmsService'sSendMediaMessageCommand.AWS_REGIONin.env) must all be the same.SendTextMessageCommandor the standard SNSPublishCommandif preferred for SMS).5. Error Handling, Logging, and Retry Mechanisms
Loggerin services and controllers. Logs key events (request received, upload start/finish, send start/finish) and errors with stack traces.nestjs-cls) to trace requests across logs.ValidationPipeandParseFilePipefor input validation errors (400 Bad Request).MmsService) catches specific AWS SDK errors during S3 upload and Pinpoint send.InternalServerErrorException(500) for service failures, which can be caught by NestJS's default exception filter or a custom one.ThrottlingException) to appropriate HTTP status codes (e.g., 429 Too Many Requests).AwsService, but the defaults are often sufficient.6. Database Schema and Data Layer (Optional Enhancement)
While not strictly required for sending MMS, tracking sent messages is crucial for auditing, analytics, and status checking.
MmsLogid(Primary Key, UUID)messageId(String, Indexed, Nullable - from Pinpoint response)destinationPhoneNumber(String, Indexed)originationIdentity(String)messageBody(Text, Nullable)mediaS3Uri(String)status(Enum: PENDING, ACCEPTED, SENT, FAILED, DELIVERED - Requires event handling from Pinpoint)pinpointResponse(JSON, Nullable - Store raw response/error)createdAt(Timestamp)updatedAt(Timestamp)@nestjs/typeorm typeorm pgor@prisma/client).TypeOrmModuleor Prisma service.MmsLogentity/model.MmsService.MmsServicebefore calling Pinpoint (status: PENDING) and update with themessageIdandstatus: ACCEPTEDupon successful API call acceptance.SENT,FAILED,DELIVEREDstatus, you need to configure Pinpoint Event Destinations (e.g., sending events to an SQS queue or Lambda function) and process these events to update theMmsLogstatus.