Last active
June 28, 2023 19:33
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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 { | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment