Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save landgenoot/07e3d64e3f3db49c5075e5428cbc87eb to your computer and use it in GitHub Desktop.
Save landgenoot/07e3d64e3f3db49c5075e5428cbc87eb to your computer and use it in GitHub Desktop.
Cloudflare Email Worker that parses flags in the local-part of the email address (e.g. somerandomtext-a@example.com), even if the receipient is in the BCC. Corresponding blog post: https://daanmiddendorp.com/tech/2023/06/28/parsing-bcc-recipient-with-cloudflare-email-workers
/**
* Cloudflare Email Worker that parses flags (e.g. -a) and forwards accordingly.
*
* Example:
* somerandomtext-a@example.com would forward to Alice.
* somerandomtext-b@example.com would forward to Bob.
*/
async function email(message, env, ctx) {
let messageSource = await fetchMessageSource(message.raw);
let blacklist = await fetchBlacklist("https://example.com/blacklist.txt");
let recipient = parseRecipient(messageSource);
if (blacklist.indexOf(recipient) > -1) {
return message.setReject("Address is blocked");
}
if (/\b.+-a@example.com\b/gi.test(recipient)) {
await message.forward("alice@company.com");
} else if (/\b.+-b@example.com\b/gi.test(recipient)) {
await message.forward("bob@company.com");
} else {
await message.forward("catchall@company.com");
}
}
/**
* Fetch readable stream, so that we can convert the raw message into a string.
* @param ReadableStream message
* @return string messageSource
*/
async function fetchMessageSource(message) {
const rawMessage = new Response(message);
const arrayBuffer = await rawMessage.arrayBuffer();
const messageSource = String.fromCharCode.apply(null, new Uint8Array(arrayBuffer));
return messageSource;
}
/**
* Download text file and split on newlines.
* @param string url location of the blacklist
* @return string[] blacklist
*/
async function fetchBlacklist(url) {
const response = await fetch(url, {});
const blacklist = (await response.text()).split("\n");
return blacklist;
}
/**
* Parse receipient from Received header (even if BCC'ed)
* Example header:
*
* Received: by mail-vk1-f194.google.com with SMTP id 71fab90a1359d-47167a4ce3cso2249208e0c.2
* for <iets2-d@example.com>; Wed, 28 Jun 2023 04:30:15 -0700 (PDT)
*
* @param string messageSource
* @return string recipient email address
*/
function parseRecipient(messageSource) {
return messageSource.match(/\b(?<=for <).+@example.com(?=>;)\b/gi)[0];
}
export default {
email
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment