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": "receive@yourdomain.com",
                        "name": "Test Recipient"}]}
            ],
            "from": {
                "email": "send@yourdomain.com",
                "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" },
    })
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment