<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Gmail on Nelson Chen's Blog</title><link>https://mindflakes.com/tags/gmail/</link><description>Recent content in Gmail on Nelson Chen's Blog</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><copyright>Copyright Nelson Chen</copyright><lastBuildDate>Tue, 16 Jun 2026 14:13:00 -0700</lastBuildDate><atom:link href="https://mindflakes.com/tags/gmail/index.xml" rel="self" type="application/rss+xml"/><item><title>Moving Gmail Send mail as to Cloudflare SMTP</title><link>https://mindflakes.com/posts/2026/06/16/gmail-send-mail-as-cloudflare-smtp/</link><pubDate>Tue, 16 Jun 2026 14:13:00 -0700</pubDate><guid>https://mindflakes.com/posts/2026/06/16/gmail-send-mail-as-cloudflare-smtp/</guid><description>&lt;p&gt;I just finished moving my Gmail &amp;ldquo;Send mail as&amp;rdquo; setup completely to &lt;a href="https://developers.cloudflare.com/email-service/api/send-emails/smtp/"&gt;Cloudflare Email Service&amp;rsquo;s native SMTP submission&lt;/a&gt;. I can send out emails under my mindflakes.com domain.&lt;/p&gt;
&lt;p&gt;The short version is that I had built a small &lt;a href="https://github.com/nelsonjchen/smtp-2-cf-email-service"&gt;Rust SMTP-to-Cloudflare REST API relay&lt;/a&gt; in April. Today I noticed Cloudflare had shipped native SMTP submission.&lt;/p&gt;
&lt;p&gt;Part of the appeal here is minimizing vendors. Cloudflare already hosts the domain, handles incoming mail through &lt;a href="https://blog.cloudflare.com/introducing-email-routing/"&gt;Email Routing&lt;/a&gt;, and now can handle outgoing mail through &lt;a href="https://developers.cloudflare.com/email-service/get-started/send-emails/"&gt;Email Service&lt;/a&gt; too. For a personal domain, that can be cheap or free, and it is a nice alternative to paying for &lt;a href="https://workspace.google.com/pricing.html"&gt;Google Workspace&lt;/a&gt; when a personal Gmail account is otherwise fine.&lt;/p&gt;
&lt;h2 id="the-april-hack"&gt;The April hack&lt;/h2&gt;
&lt;p&gt;In April, I saw Cloudflare&amp;rsquo;s &lt;a href="https://blog.cloudflare.com/email-for-agents/"&gt;public beta announcement&lt;/a&gt; for Email Service and got excited about using Cloudflare for both inbound and outbound personal-domain mail.&lt;/p&gt;
&lt;p&gt;Then I got sad. I wanted Gmail to send mail for one of my domains through &lt;a href="https://developers.cloudflare.com/email-service/get-started/send-emails/"&gt;Cloudflare Email Service&lt;/a&gt;, but I did not see a native SMTP submission path I could just point Gmail at.&lt;/p&gt;
&lt;p&gt;Gmail&amp;rsquo;s &lt;a href="https://support.google.com/mail/answer/22370"&gt;Send mail as&lt;/a&gt; feature wants a normal authenticated SMTP server. You give it a hostname, a port, a username, and a password. Gmail talks SMTP. It does not want to be handed a REST API endpoint.&lt;/p&gt;
&lt;p&gt;At the time, the useful Cloudflare sending shape I had in front of me was the raw MIME REST API. Cloudflare had teased SMTP in the earlier private-beta era, but the public thing I could actually use was not SMTP.&lt;/p&gt;
&lt;p&gt;So I made &lt;code&gt;smtp2cf&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;It was intentionally narrow:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;accept authenticated SMTP from Gmail&lt;/li&gt;
&lt;li&gt;write the raw MIME message to disk before returning &lt;code&gt;250 OK&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;forward that raw MIME to Cloudflare&amp;rsquo;s &lt;a href="https://developers.cloudflare.com/api/resources/email_sending/methods/send_raw"&gt;&lt;code&gt;send_raw&lt;/code&gt; API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;retry transient failures&lt;/li&gt;
&lt;li&gt;move permanent failures to a dead-letter directory&lt;/li&gt;
&lt;li&gt;stay small enough to run on a cheap little VPS with an IPv4 address, because that is what I already had&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Mostly, I wanted to avoid operating a real mail server for a personal domain.&lt;/p&gt;
&lt;h2 id="the-temporary-bridge"&gt;The temporary bridge&lt;/h2&gt;
&lt;p&gt;This is also one of those places where &lt;a href="https://openai.com/codex/"&gt;Codex&lt;/a&gt; changed what felt reasonable to do.&lt;/p&gt;
&lt;p&gt;Before, I probably would have waited for Cloudflare&amp;rsquo;s rollout or grudgingly set up a heavier mail stack. But as far as I could tell, there was no useful public date for SMTP support. So I was impatient and made the bridge I wanted.&lt;/p&gt;
&lt;p&gt;My first &lt;code&gt;smtp2cf&lt;/code&gt; commit was April 18, 2026. I had the repo cleaned up and documented by April 20. It was not a forever project. It was a practical way to bridge the gap until Cloudflare shipped the official SMTP path.&lt;/p&gt;
&lt;p&gt;Cloudflare&amp;rsquo;s docs now have a changelog entry dated June 8, 2026: &lt;a href="https://developers.cloudflare.com/changelog/post/2026-06-08-smtp-submission/"&gt;Authenticated SMTP submission now available in beta&lt;/a&gt;. That means the relay did its job and can leave the live path.&lt;/p&gt;
&lt;h2 id="the-new-setup"&gt;The new setup&lt;/h2&gt;
&lt;p&gt;Cloudflare&amp;rsquo;s &lt;a href="https://developers.cloudflare.com/email-service/api/send-emails/smtp/"&gt;SMTP docs&lt;/a&gt; and Gmail&amp;rsquo;s &lt;a href="https://support.google.com/mail/answer/22370"&gt;Send mail as docs&lt;/a&gt; line up pretty directly:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;host: &lt;code&gt;smtp.mx.cloudflare.net&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;port: &lt;code&gt;465&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;security: implicit TLS&lt;/li&gt;
&lt;li&gt;username: &lt;code&gt;api_token&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;password: a Cloudflare API token with Email Sending access&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I generated a token, changed the Gmail Send mail as SMTP settings, sent a test message, and watched it go through Cloudflare without my relay in the middle.&lt;/p&gt;
&lt;p&gt;That is the best kind of infrastructure migration: delete a moving part and then immediately wonder why you ever had to own it.&lt;/p&gt;
&lt;h2 id="the-now-historical-rust-thing"&gt;The now historical Rust thing&lt;/h2&gt;
&lt;p&gt;The repo is still here:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/nelsonjchen/smtp-2-cf-email-service"&gt;https://github.com/nelsonjchen/smtp-2-cf-email-service&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It is now mostly historical for me.&lt;/p&gt;
&lt;p&gt;I still like a few parts of it. The durable spool is the right instinct. Returning &lt;code&gt;250 OK&lt;/code&gt; before the message is safely written somewhere is how you earn a future debugging session. The Gmail header cleanup is gross but also a useful reminder that &amp;ldquo;raw MIME&amp;rdquo; does not always mean &amp;ldquo;whatever one mail system happened to emit is acceptable to another one.&amp;rdquo;&lt;/p&gt;
&lt;h2 id="my-past-email-setups"&gt;My past email setups&lt;/h2&gt;
&lt;p&gt;This domain has had a few outgoing mail setups over the years.&lt;/p&gt;
&lt;p&gt;Way back, I used &lt;a href="https://www.dreamhost.com/hosting/email/"&gt;DreamHost&lt;/a&gt; for Gmail&amp;rsquo;s &lt;a href="https://support.google.com/mail/answer/22370"&gt;Send mail as&lt;/a&gt; SMTP server. That mostly worked, but it was still another provider in the path.&lt;/p&gt;
&lt;p&gt;Later, I used &lt;a href="https://www.zoho.com/mail/"&gt;Zoho Mail&lt;/a&gt; as a sort of middleman mailbox. Gmail would send as the domain through Zoho, and Zoho would receive mail and forward it onward. I was not happy with either side of that. Incoming forwarding would sometimes fail to take, delivery rates sucked on Zoho, sending email out through Zoho SMTP was a shitshow, and traffic from Zoho to Gmail was a shitshow too.&lt;/p&gt;
&lt;p&gt;The most annoying symptom was the delivery report email. I would get an email with a ZIP file of delivery-rate data, and the vibe was never &amp;ldquo;everything is fine.&amp;rdquo; It was more like &amp;ldquo;congratulations, your mail technically attempted to exist.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Then came &lt;code&gt;smtp2cf&lt;/code&gt;, the Rust relay in this post. That got me away from Zoho and let Gmail hand mail to my own tiny SMTP bridge, which then sent through Cloudflare&amp;rsquo;s raw MIME API. It was better because it was mine and inspectable, but it was still a moving part I had to run.&lt;/p&gt;
&lt;p&gt;This Cloudflare SMTP setup is the first version that feels like the shape I wanted all along: Gmail UI, personal domain, Cloudflare for the domain and mail plumbing, and no mailbox vendor sitting in the middle.&lt;/p&gt;
&lt;p&gt;Anyway, that is the trip report. I am happy this one is boring now.&lt;/p&gt;</description></item></channel></rss>