payload-email-ses
v1.0.1
Published
AWS SESv2 email adapter for Payload CMS 3.x
Maintainers
Readme
payload-email-ses
AWS SESv2 email adapter for Payload CMS 3.x.
Install
pnpm add payload-email-sesPeer dependencies (@aws-sdk/client-sesv2 and payload) must also be installed:
pnpm add @aws-sdk/client-sesv2 payloadUsage
In your payload.config.ts:
import { buildConfig } from "payload";
import { sesAdapter } from "payload-email-ses";
export default buildConfig({
email: sesAdapter({
defaultFromAddress: "[email protected]",
defaultFromName: "My App",
region: "eu-west-1",
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
},
}),
// ... rest of your config
});Configuration
| Option | Type | Required | Description |
| ----------------------------- | -------- | -------- | --------------------------------------- |
| defaultFromAddress | string | Yes | Default sender email address |
| defaultFromName | string | Yes | Default sender display name |
| region | string | Yes | AWS region for SES (e.g. eu-west-1) |
| credentials.accessKeyId | string | Yes | AWS access key ID |
| credentials.secretAccessKey | string | Yes | AWS secret access key |
| logger | Logger | No | Structured logger for email send events |
Logging
Pass a Logger to get structured logs for email send events. The logger is completely optional — emails are delivered normally when no logger is provided. Logging failures never affect email delivery.
import { pino } from "pino";
export default buildConfig({
email: sesAdapter({
defaultFromAddress: "[email protected]",
defaultFromName: "My App",
region: "eu-west-1",
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
},
logger: pino(),
}),
});The Logger interface matches pino, winston, bunyan, and most Node.js loggers:
interface Logger {
info: (msg: string, meta?: Record<string, unknown>) => void;
error: (msg: string, meta?: Record<string, unknown>) => void;
warn: (msg: string, meta?: Record<string, unknown>) => void;
}Log events:
| Event | Level | Metadata |
| ------------ | ------- | ----------------------------------------- |
| Before send | info | to, cc, bcc, from, subject |
| Send success | info | messageId |
| Send failure | error | errorName, errorMessage, to, from |
Sending emails
await req.payload.sendEmail({
to: "[email protected]",
subject: "Welcome",
html: "<h1>Hello!</h1>",
text: "Hello!",
});Override from address per email
await req.payload.sendEmail({
from: "[email protected]",
to: "[email protected]",
subject: "Support",
html: "<p>We got your message.</p>",
});Reply-To
await req.payload.sendEmail({
to: "[email protected]",
subject: "Contact",
html: "<p>Reply to this email.</p>",
replyTo: "[email protected]",
});AWS IAM permissions
The IAM user or role needs at minimum:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["ses:SendEmail", "ses:SendRawEmail"],
"Resource": "*"
}
]
}Exports
sesAdapter— Adapter factory functionbuildFromAddress— Format "Name <email>" helperresolveFromAddress— Resolve from address from various formatsmapDestination— Map to/cc/bcc to SESv2 destinationmapEmailContent— Map subject/html/text to SESv2 content
Type exports: SESAdapterArgs, SESEmailResponse, SESEmailAdapter, Logger
License
MIT
