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:
SendMediaMessage
capability.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
.env
file in the project root for storing sensitive configuration. Never commit this file to version control. Add a.env.example
file to track required variables.Ensure your
.gitignore
file 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_ID
andAWS_SECRET_ACCESS_KEY
in your.env
file.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_NAME
andYOUR_AWS_ACCOUNT_ID
.6. AWS Pinpoint Origination Identity:
AWS_PINPOINT_ORIGINATION_IDENTITY
variable in your.env
file.7. Configure NestJS ConfigModule:
Import and configure
ConfigModule
in 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.env
access 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?
ConfigService
for credentials, avoiding hardcoding.OnModuleInit
ensures clients are ready when the module initializes.@Global()
makes theAwsService
easily 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?
AwsService
andConfigService
for dependencies.uuid
for unique filenames in S3, preventing collisions.uploadMediaToS3
andsendMms
.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
'sFileInterceptor
to handlemultipart/form-data
.ParseFilePipe
with validators (FileTypeValidator
,MaxFileSizeValidator
) for robust file validation before hitting the service logic.SendMmsDto
and relies onValidationPipe
(enabled globally later) for validating text fields.MmsService
to delegate the core logic.202 Accepted
as the process involves external asynchronous systems.Enable Global Validation Pipe:
Modify
src/main.ts
to enable automatic validation using the DTOs.Testing the Endpoint:
You can use
curl
or Postman to test.Curl Example:
Postman:
POST
.http://localhost:3000/mms/send
.Body
tab, selectform-data
.KEY
nameddestinationPhoneNumber
, enter a valid E.164 number inVALUE
.KEY
messageBody
, enter text inVALUE
.KEY
mediaFile
. In theVALUE
column, click the dropdown and selectFile
. Then clickSelect Files
and 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:
.env
andConfigModule
. Accessed inAwsService
to initialize SDK clients..env
. Bucket Policy allows Pinpoint read access. Upload logic inMmsService
..env
. Used inMmsService
'sSendMediaMessageCommand
.AWS_REGION
in.env
) must all be the same.SendTextMessageCommand
or the standard SNSPublishCommand
if preferred for SMS).5. Error Handling, Logging, and Retry Mechanisms
Logger
in 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.ValidationPipe
andParseFilePipe
for 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.
MmsLog
id
(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 pg
or@prisma/client
).TypeOrmModule
or Prisma service.MmsLog
entity/model.MmsService
.MmsService
before calling Pinpoint (status: PENDING
) and update with themessageId
andstatus: ACCEPTED
upon successful API call acceptance.SENT
,FAILED
,DELIVERED
status, you need to configure Pinpoint Event Destinations (e.g., sending events to an SQS queue or Lambda function) and process these events to update theMmsLog
status.