Use Cloudflare to Catch All Emails
Redirect all Emails to a Worker
Email Routing > Routing Rules > Catch-all address
/**
* @typedef {object} Env
* @property {R2Bucket} r2
* @property {D1Database} d1
*/
export default {
/**
* @param {ForwardableEmailMessage} message
* @param {Env} env
*
* This function is triggered when an email is received.
* It saves the raw email data to R2 and metadata to D1.
*/
async email(message, env) {
const id = crypto.randomUUID();
console.log('Got email from', message.from, 'to', message.to);
const size = message.rawSize;
const date = Date.now();
const { readable, writable } = new FixedLengthStream(size);
message.raw.pipeTo(writable);
// Save raw data to r2
try {
await env.r2.put(`raw/${id}`, readable);
} catch (err) {
console.error(`Failed to put email raw data into r2`, err);
return;
}
// Save metadata to d1
try {
await env.d1.prepare(`INSERT INTO emails (id, size, date, "from", "to") VALUES (?1, ?2, ?3, ?4, ?5)`)
.bind(id, size, date, message.from, message.to)
.run();
} catch (err) {
console.error(`Failed to put email metadata into d1`, err);
return;
}
console.log('Successfully saved email', id)
},
/**
* @param {ScheduledEvent} event
* @param {Env} env
*
* This function is triggered by a scheduled event (cron job).
* It will delete emails older than 5 days.
*/
async scheduled(event, env) {
const time = event.scheduledTime;
const before = time - 5 * 24 * 60 * 60 * 1000; // 5 days
console.log(`[cron] Deleting emails before`, new Date(before));
const query = env.d1.prepare('SELECT id FROM emails WHERE date < ?1');
const res = await query.bind(before).all();
const emails = res.results;
console.log(`[cron] Deleting emails`, emails.map(e => e.id).join(', '));
for (const e of emails) {
await env.r2.delete(`raw/${e.id}`);
await env.d1.prepare('DELETE FROM emails WHERE id = ?1').bind(e.id).run();
}
console.log(`[cron] Deleted ${emails.length} emails`);
},
}
Configure cloudflare to redirect some Emails to a specific address
- Email Routing > Routing Rules > Custom addresses
- Redirect jhon@my-domain.com to jhon.doe+my-domain@gmail.com
- Validate the email address (jhon.doe@gmail.com will receive a validation email for jhon.doe+my-domain@gmail.com)
Configure GMail (jhon.doe@gmail.com) to receive some Emails
https://support.google.com/mail/answer/22370?hl=en
Tip: You can send emails from up to 99 different email addresses.
Step 1: Add an address you own
- On your computer, open Gmail.
- In the top right, click Settings Settings and then See all settings.
- Click the Accounts and import or Accounts tab.
- In the "Send mail as" section, click Add another email address.
- Enter your name (John Doe) and the external address (jhon@my-domain.com) you want to send from (uncheck "Treat as an alias").
- Enter the Scaleway SMTP server (smtp.tem.scaleway.com, port 465)
===============
This way you:
- can receive emails to your custom domain email address, they will be redirected to your Gmail account
- can use your Gmail account to send emails with your custom domain email address
- can handle the catch-all emails with a Worker
- don't need to pay for a custom email hosting service
- don't need to setup a gmail application password
- you are SPF/DKIM compliant thanks to Scaleway