← all writing

Sending free transactional emails with Cloudflare Workers

· 2 min read · Comments ↓

Learn how to send free transactional emails with Cloudflare Workers, with minimal setup and a simple workers API.

Listen to this post
0:00

While setting up authentication for https://dump.place, I realised that I needed to send emails to users.

I didn’t want to use a third-party service like SendGrid, Resend or Mailgun, because I didn’t want to pay for something that was not ‘mission-critical’ to the app, especially because it was just a side project.

I also didn’t want to set up my own email server, because that would be a lot of work, and I didn’t want to deal with the maintenance and security issues that come with running an email server.

So.. The best solution I found was to use Cloudflare Workers to send emails.

Wait, Cloudflare does that? 🤔

Yes. Cloudflare has been providing this service for a while, but it’s not very well known. They partnered with MailChannels for a way to provide users to send emails through cloudflare IP addresses.

Cloudflare IP Addresses

How do you send an email though a Cloudflare IP address? Using Cloudflare Workers, of course!

So, I found this github repository that acts as a proxy between your app and Cloudflare’s email service.

How to use it

  1. Click this button

Deploy to Cloudflare Workers

  1. Follow the steps, it’s pretty straightforward.

Steps to deploy

Note: You’ll need to add your TOKEN variable in the wrangler.toml file, or you can add it in the Cloudflare dashboard. Just create a random, secure string and add it as a variable.

  1. After you’ve deployed the worker, you can send an api request to the worker to send an email.

here’s the code from my nextauth file in dump.place

      async sendVerificationRequest({ identifier: email, url }) {
        await fetch("https://your-worker.workers.dev/api/email", {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
            Authorization: `${env.EMAIL_TOKEN}`,
          },
          body: JSON.stringify({
            to: email,
            from: "Email Addr <your@cloudflare.domain>",
            subject: "Verify your email address.",
            text: `Welcome to my app. Click here to authenticate: ${url}`,
          }),
        });
      },

well… that was easy.

Yes, it was. I was surprised too. I thought it would be a lot more complicated, but it was pretty easy to set up.

Thx for reading this small (tutorial?) post. I hope you found it useful. If you did, share it! It helps me a lot.

NOTE:

Upon tweeting this blog, many pointed out the potential security issues with MailChannels. I’ll leave the tweets here