Skip to content

Instantly share code, notes, and snippets.

@stonking
Created May 13, 2022 19:31
Show Gist options
  • Save stonking/3902550b2b0066a28a5064b73e2505ee to your computer and use it in GitHub Desktop.
Save stonking/3902550b2b0066a28a5064b73e2505ee to your computer and use it in GitHub Desktop.
Send email from Cloudflare Workers via MailChannels

Send email from Cloudflare Workers via MailChannels

Cloudflare announced a partnership with MailChannels that allows you to send free email via workers.

The example code that MailChannels supplied wasn't working so I fixed it here to make testing easy.

  1. Add include:relay.mailchannels.net to your domain's SPF record.
  2. Update the code below with your email addresses
  3. Create worker, paste code, save and deploy and test

Follow Adam Sculthorpe on Twitter if you have questions or found this useful.

addEventListener("fetch", event => {
    event.respondWith(handleRequest(event.request))
})

async function handleRequest(request) {
    let content = "";
    for( var i of request.headers.entries() ) {
        content += i[0] + ": " + i[1] + "\n";
    }
    let send_request = new Request("https://api.mailchannels.net/tx/v1/send", {
        "method": "POST",
        "headers": {
            "content-type": "application/json",
        },
        "body": JSON.stringify({
            "personalizations": [
                { "to": [ {"email": "[email protected]",
                        "name": "Test Recipient"}]}
            ],
            "from": {
                "email": "[email protected]",
                "name": "Test Sender",
            },
            "subject": "Test Subject",
            "content": [{
                "type": "text/plain",
                "value": "Test message content\n\n" + content,
            }],
        }),
    });

    let respContent = "";
    // only send the mail on "POST", to avoid spiders, etc.
    if( request.method == "POST" ) {
        const resp = await fetch(send_request);
        const respText = await resp.text();
        respContent = resp.status + " " + resp.statusText + "\n\n" + respText;
    }

    let htmlContent = "<html><head></head><body><pre>" + "</pre><p>Click to send message: <form method='post'><input type='submit' value='Send'/></form></p>" + "<pre>" + respContent + "</pre>" + "</body></html>";
    return new Response(htmlContent, {
        headers: { "content-type": "text/html" },
    })
}
@petrus9
Copy link

petrus9 commented Aug 25, 2024

Thanks! Now that MailChannels for Cloudflare Pages / Workers is almost EOL (Aug 31, 2024) how would you transition this code to use a personal Mailchannels API key?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment