This is a submission for the Postmark Challenge: Inbox Innovators.
What I Built
I build a simple service that allows you to securely upload email attachments directly to AWS S3 simply by forwarding it to an email address. When your inbox gets crowded and you want to keep your important attachments in cloud storage, you can forward your email to <folder>
@email-to-s3.email
. The service will process those attachments using Postmark's Inbound API and store the files in your own cloud folder on S3.
Demo
Forward any attachment:
The service uploads it and responds with a link to the file in the cloud:
It also stores it under a S3 folder linked to your email address so you can login and retrieve your uploads any time.
This is just a proof of concept. There are a number of cases where it would be ideal to upload attachments to a cloud folder simply by forwarding an email: customer reports, notifications from internal systems, team collaboration, project management streamlining, etc. This code should be easy to adapt to these and many other use cases.
Code Repository
levinunnink
/
email-to-s3
An example of how to upload email attachments to S3 using the Postmark Inbound hooks
Email to S3
Lightweight Express.js service that receives inbound emails via Postmark and uploads attachments to any S3-compatible block storage (AWS S3, Cloudflare R2, DigitalOcean Spaces, etc.) under the pattern <email-address>/<attachment-name>
. No database dependencies.
Features
- Receives inbound email webhooks from Postmark
- Uploads attachments to S3
- No database dependencies
Requirements
- Node.js >= 14
- Credentials for your storage (Access Key and Secret)
- S3 bucket or bucket-equivalent name created in your provider
- Postmark server API token
- Serverless Framework installed (
npm install -g serverless
)
Installation
git clone https://github.com/levinunnink/email-to-s3.git
cd email-to-s3
npm install
Configuration
Environment Variables
Copy .env.example
to .env
and fill in:
# .env
STORAGE_ENDPOINT=https://<account>.<region>.r2.cloudflarestorage.com # e.g. Cloudflare R2 endpoint
STORAGE_REGION=auto # Some providers may ignore region
STORAGE_ACCESS_KEY_ID=your-access-key-id
STORAGE_SECRET_ACCESS_KEY=your-secret-access-key
STORAGE_BUCKET=your-bucket-name
POSTMARK_SERVER_TOKEN=your-postmark-token
PORT=3000
SEND_EMAIL_RESPONSE=1 # Indicates if the service should send a response email with the
…How I Built It
Tech Stack: Node.js & TypeScript, Express.js, AWS SDK v3, Postmark SDK, Serverless Framework
Storage Abstraction: A generic
StorageClient
wraps any S3-compatible endpoint, usingforcePathStyle
and customendpoint
for providers like R2 or Spaces.Serverless: Deployed as an AWS Lambda behind API Gateway, defined in
serverless.yml
with least-privilege IAM. This should be trivial to stand up on AWS, Cloudflare Pages, or DigitalOcean Apps.Postmark Integration: Parses
InboundMessage
, decodes Base64 attachments, and streams each file into your bucket. On failure, returns HTTP 500 so Postmark will retry. Additionally we use the Postmark Transactional API to send email responses with the uploaded attachments. (This can be disabled with a an env variable.)Developer Experience: Zero database. You just configure environment variables, deploy, and you’re live. Local dev uses
ts-node-dev
for quick iteration.
Top comments (3)
Really cool idea and the implementation seems straightforward! One suggestion: It would be nice to see some info about security precautions, since forwarding emails to a third-party address could be risky for sensitive files. Otherwise, great proof of concept!
Looks cool!
Thanks!