Developer Guide: Sending MMS with AWS Pinpoint and RedwoodJS - code-examples -

Frequently Asked Questions

You can send MMS messages with RedwoodJS by integrating with AWS Pinpoint and S3. This involves setting up AWS resources (IAM user, S3 bucket, Pinpoint number), installing the AWS SDK v3, configuring environment variables, implementing a RedwoodJS service function, and exposing the functionality via a GraphQL mutation. The service function interacts with the Pinpoint API to send messages, using S3 to store media attachments.
AWS Pinpoint is used for sending the actual MMS messages. Its `SendMediaMessage` API action, part of the SMS and Voice v2 API, handles message dispatch. Pinpoint integrates with S3 for media handling and requires specific IAM permissions for secure access. Note: Pinpoint's primary MMS support is for US and Canadian destinations.
MMS messages include media attachments (images, videos, etc.). An S3 bucket is used to store these media files, which AWS Pinpoint then accesses and includes when sending the MMS. The S3 bucket and your Pinpoint origination number *must* be in the same AWS region.
Toll-free numbers are often easiest for initial testing and development with Pinpoint. However, for production application-to-person (A2P) messaging in the US, 10DLC (10-digit long code) is the standard and generally recommended for better deliverability and compliance. Short codes require a more complex application process.
No, AWS Pinpoint cannot receive inbound MMS media (like images sent to your Pinpoint number). While it can typically receive inbound *text* (SMS) replies, if the number and Pinpoint are configured to do so, it does not support receiving media attachments in replies.
Create a dedicated IAM user or role with a least-privilege policy. This policy should grant `sms-voice:SendMediaMessage` permission for Pinpoint and `s3:GetObject` (and optionally `s3:ListBucket`) permission for your S3 bucket containing the media files. Restricting permissions enhances security.
The AWS SDK for JavaScript v3 is used with the specific client package `@aws-sdk/client-pinpoint-sms-voice-v2`. This provides the necessary functions and types to interact with the Pinpoint SMS and Voice v2 API. Install it with: `yarn add @aws-sdk/client-pinpoint-sms-voice-v2` within the `api` side of your redwood project.
AWS Pinpoint needs to access the media files stored in your S3 bucket to include them in the MMS message. For efficiency and to avoid cross-region data transfer costs, these resources must be in the same AWS region. This is a mandatory requirement for MMS sending.
Media URLs must be S3 URIs in the format `s3://YOUR_BUCKET_NAME/path/to/your/file.jpg`. Ensure your IAM user has `s3:GetObject` permission for the specified objects in the bucket. The bucket must be in the same region as your Pinpoint origination number.
Use a `try...catch` block in your service function. Catch errors from the AWS SDK, log details using `logger.error`, and re-throw a more generic error to the GraphQL layer. You can check for specific AWS error types (e.g., `ValidationException`) to refine handling.
The `MessageId` in the Pinpoint `SendMediaMessage` response only confirms that AWS Pinpoint has *accepted* the send request. It does *not* guarantee message delivery to the handset. Tracking delivery requires setting up event streaming (e.g., using SNS or Kinesis).
Use a retry mechanism (a simple loop or library like `async-retry`) to handle transient errors like network issues or throttling. Include exponential backoff and ensure you *only* retry on appropriate, transient errors. Avoid retrying on validation or permission errors.
Store AWS credentials securely in a `.env` file in the root of your RedwoodJS project. This file should *never* be committed to version control. Use environment variables like `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`.
The RedwoodJS service, typically named `mmsService` (or similar) and located at `api/src/services/mms/mms.ts`, encapsulates all logic for sending MMS messages using the AWS SDK and handling responses or errors. The service function is automatically linked to your GraphQL mutation if you follow Redwood naming conventions.