AWS SES
First-class email delivery for Vortos with AWS SES, transactional outbox, suppression lists, bounce handling, rate limits, failover, and observability.
AWS SES
vortos/vortos-aws-ses is the first-class email package for Vortos. It gives application code a small typed API while the package owns the enterprise concerns: SES transport mapping, transactional outbox, worker relay, rate limiting, suppression lists, bounce and complaint webhooks, audit logging, metrics, logs, traces, and testing fakes.
The application API stays small
Most business code injects Vortos\AwsSes\Contract\MailerInterface and calls send(). The selected driver, middleware stack, outbox behavior, retry policy, and observability are configured once at the package boundary.
What The Package Guarantees
The package separates email intent from delivery. A command handler can save a domain aggregate and enqueue an email in the same database transaction. A worker later relays the email to SES with bounded retries. If SES is down, the database transaction still commits and the outbox relay keeps trying.
The package also prevents common production mistakes:
- Invalid email addresses are rejected before the provider call.
- Suppressed recipients are detected before sending.
- SES account rate limits are respected by middleware.
- Provider errors are mapped into Vortos exceptions.
- Bounce and complaint notifications can update the local suppression list.
- Logs, traces, and metrics are enabled by default but can be disabled globally or by typed section enum.
Drivers
ses sends through AWS SES.
log writes email attempts to the PSR logger and is the development default.
null silently drops email and wires test-friendly fake services.
Service Guarantees
Vortos does not hide delivery guarantees behind one ambiguous config switch. The interface you inject tells reviewers exactly what will happen.
use Vortos\AwsSes\Contract\MailerInterface;
use Vortos\AwsSes\Contract\StandaloneMailerInterface;
use Vortos\AwsSes\Contract\ImmediateMailerInterface;
final class RegistrationHandler
{
public function __construct(
private MailerInterface $mailer,
) {}
}MailerInterface is the normal application path. When outbox is enabled, it writes to aws_ses_outbox and requires an active CommandBus or UnitOfWork transaction.
StandaloneMailerInterface opens a short transaction for only the email outbox row. Use it for maintenance commands or scripts that want async reliability without joining a domain transaction.
ImmediateMailerInterface calls the configured transport directly. Use it for diagnostics, probes, or rare workflows where email must be attempted immediately and no outbox row should exist.
Do not send user-facing business email from HTTP controllers directly
Send from command handlers through MailerInterface so domain persistence and email intent are committed atomically. Controllers should translate HTTP into commands.
Architecture
Command Handler
|
| MailerInterface::send(Email)
v
Email Middleware Stack
| validate
| suppression check
| deduplication
| rate limit
| audit/log/trace/metrics
v
Transactional Outbox Writer
|
| same DB transaction as domain save
v
aws_ses_outbox
|
| vortos:ses:outbox:relay
v
SES Driver
|
v
AWS SESWebhook flow:
AWS SNS -> /webhooks/aws/ses -> SNS signature verifier
|
+-> Bounce handlers
+-> Complaint handlers
+-> local suppression listDocumentation Map
Quickstart
Install the package, register it, set environment variables, and send your first email.
Configuration
Every config section, default, and production tuning option.
Sending
Typed Email value objects, attachments, templates, and service guarantee choices.
Outbox
Atomic database transactions, relay workers, retries, and supervisor integration.
Webhooks
SNS bounce and complaint handling with local suppression behavior.
Operations
Commands, tests, fakes, migrations, and production runbooks.
Package Registration
use Vortos\AwsSes\DependencyInjection\AwsSesPackage;
$packages = [
// ... other packages
new AwsSesPackage(),
];The package is optional. If a project does not install or register it, no SES services, tables, commands, middleware, or workers are added.