Skip to content

About

AWS End User Messaging and AWS SES Webhooks

Topics

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

aws-messaging-webhook

CI MSRV License

One Rust Lambda function that receives AWS messaging events from Amazon SNS, records them in DynamoDB, and republishes them to an EventBridge bus your applications subscribe to. It handles:

  • AWS End User Messaging (EUM): inbound SMS and delivery receipts.
  • Amazon SES: sending events (bounces, complaints, opens, clicks) and inbound mail.

Optionally, it also runs a mailbox on SES with an HTTP API to read and send mail.

How it works

EUM / SES ─► SNS ─► Function URL (HTTPS) or direct invoke
                      │
                      ├─ verify   SNS signature + topic allowlist
                      ├─ persist  DynamoDB, one conditional write per event
                      ├─ act      opt-outs, suppression, delivery feedback
                      │
                      └─ DynamoDB stream ─► relay ─► EventBridge ─► your apps
  • Verify. Every message must carry a valid SNS signature and come from an allowlisted topic.
  • Persist. A conditional write makes SNS redeliveries harmless.
  • Act. STOP/START update the EUM opt-out list. Hard bounces and complaints go on the SES suppression list. Delivery receipts send message feedback.
  • Publish. A stream relay publishes each saved event, with retries and a dead-letter queue.

Subscriptions confirm themselves. If someone abuses an UnsubscribeURL, the function re-subscribes.

Quick start

Install Rust, cargo-lambda and the AWS SAM CLI, then:

sam build
sam deploy --guided   # set pAllowedTopics to your account id

Subscribe your SNS topics to the endpoints the stack outputs. See docs/deploy.md.

Important

Set pAllowedTopics. A valid signature proves only that a message came from SNS in some account. Keep raw message delivery off on every subscription.

Mailbox

Set pMailDomain and pMailInbox to receive mail at <inbox>@<domain>. Inbound mail is stored in S3 and DynamoDB, threaded, and exposed through a /v0 API that also sends mail.

  • Setup: parameters and five one-time steps after the first deploy
  • API: routes, labels, filtering and sending
  • Events: message.* events and webhook delivery
  • Tracking: opens, clicks and custom tracking domains
  • Storage: mail table, bucket layout and retention
  • Runbook: stuck sends and failed ingests

Documentation

Doc Covers
Deploy Parameters, topic subscriptions, retry behavior
Events EventBridge detail types and payloads
Data model Events table and cross-account read access
Operations Logs, metrics, alarms and an end-to-end check
Mailbox design Why the mailbox is built the way it is

Development

cargo test --workspace   # no AWS account needed
cargo clippy --all-targets --all-features -- -D warnings
prek run                 # fmt, clippy, deny, actionlint, zizmor
Crate Purpose
crates/mailbox Pure mailbox domain: message/thread/send types, ids, labels, MIME parsing and building, wire shapes
crates/mailbox-store The mail table: keys, transaction planner, the Table seam and the Mailbox over it
crates/sns-message-verifier SNS signature verification. The test-fixtures feature signs test messages
crates/webhook The Lambda function (package aws-messaging-webhook)
crates/webhook-test-support Fakes and request harness shared by the webhook crate's integration tests

Dependency direction: aws-messaging-webhook -> mailbox-store -> mailbox.

Debug builds read SNS_CERT_HOST_OVERRIDE to run against a local fake SNS under cargo lambda watch. Release builds always verify.

License

Licensed under either of the Apache License 2.0 or the MIT license, at your option.

About

AWS End User Messaging and AWS SES Webhooks

Topics

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Sponsor this project

Used by

Contributors

Languages