Skip to content

Sending mail

Optional, and only ever used for setup and reset links. The SMTP side is a few fields in Admin → Mail; getting the mail delivered is the harder half.

Do not send directly from a home connection

Residential address ranges sit on blocklists (Spamhaus PBL and similar) by default, most ISPs block outbound port 25, and you cannot usually set reverse DNS for your own IP. Mail sent directly will be rejected or silently binned.

Send through a relay instead. Any of these work, and a home library sends a handful of messages a month, so free tiers are ample:

Relay Notes
A transactional provider — Postmark, Amazon SES, Mailgun, Brevo, Resend Best deliverability; they handle DKIM signing for you. Most want your domain verified before they will send anything.
Your existing mailbox — Gmail/Workspace, Fastmail, Migadu Simplest if you already pay for one. Use an app password, never your account password. Gmail: smtp.gmail.com:587, STARTTLS.
Your ISP's smarthost Often unauthenticated on port 25 from their own network. Fine, and free.

Using Google Workspace

If you already pay for Workspace on a domain you own, that is the quickest start and needs nothing new. Pick a route by the From address you want.

Send as yourself, with an app password. Five minutes, no admin console.

  1. Turn on 2-Step Verification for the account — app passwords are unavailable without it.
  2. myaccount.google.com → Security → 2-Step Verification → App passwords → create one named "Longbox". You get sixteen characters; spaces in it do not matter.
  3. In Admin → Mail pick Google Workspace / Gmail from the relay list, then fill in your full address as the username and the app password as the password.
  4. Send a test.

The part that catches people: Gmail rewrites the From: header to the authenticated account unless the address is one you have verified. So to send as longbox@yourdomain rather than as yourself:

  1. Admin console → Directory → Users → your user → add longbox@ as an email alias. Aliases are free; they do not cost a seat.
  2. Gmail → Settings → Accounts and Import → Send mail as → add the alias and confirm it.
  3. Use it as the From address in Longbox.

Or use the SMTP relay service. Slightly more setup, but it lets you send as any address in your domain without verifying each one, which is tidier for an application identity. Admin console → Apps → Google Workspace → Gmail → Routing → SMTP relay service → Add. Allow senders from your domain, require SMTP authentication, then pick Google Workspace SMTP relay service in Longbox.

Check DKIM is actually on. Workspace sets up MX and SPF when you add a domain, but DKIM signing is off until you turn it on, and plenty of domains have run for years without it:

Admin console → Apps → Google Workspace → Gmail → Authenticate email → select the domain → Generate new record (2048-bit) → publish the TXT it gives you at google._domainkey.yourdomainStart authentication.

Your SPF record should include Google:

yourdomain.com.  TXT  "v=spf1 include:_spf.google.com ~all"

And add DMARC if you have none:

_dmarc.yourdomain.com.  TXT  "v=DMARC1; p=none; rua=mailto:you@yourdomain.com"

Because you are sending as your own domain, through a relay listed in your SPF, signed with your own DKIM key, alignment works out — which is precisely why this setup is the easy one.

Limits. Workspace allows roughly 2,000 external recipients a day per user, or 10,000 through the relay service. Longbox sends a handful of messages a month, so this is not a constraint — but Google's terms do not cover bulk or transactional sending for a product, which is the real reason to move on later.

Moving to a dedicated domain later

Nothing in the code is tied to a provider: app/mailer.py is plain SMTP, and every setting lives in the admin page or the environment. Switching is:

  1. Register the domain and verify it with the new provider (Postmark, SES, Mailgun, whichever).
  2. Publish their SPF include:, their DKIM selector, and a DMARC record on the new domain.
  3. Change five fields in Admin → Mail: server, port, security, username, password — and the From address to one at the new domain.
  4. Update LONGBOX_PUBLIC_URL if the app moves host too, so setup and reset links point somewhere reachable.
  5. Send a test, then check it with mail-tester.com.

One thing worth doing now to make that painless: send from a dedicated alias like longbox@yourdomain from the start, rather than your personal address. Then the From has always been an application identity, users are not used to seeing your name on it, and the eventual change is one field rather than a change of character. It also keeps replies and bounces out of your own inbox.

If you send from your own domain, publish three DNS records

These are what stop your mail being treated as forgery. All three are TXT records, and your relay will tell you the exact values.

SPF — says which servers may send as your domain.

example.com.  TXT  "v=spf1 include:spf.example-relay.com ~all"

Only one SPF record per domain; if you already have one, merge the include: rather than adding a second. Start with ~all (soft fail) and tighten to -all once you are confident nothing legitimate is being missed.

DKIM — a signature on each message, so it survives forwarding (SPF does not). Your relay generates a key pair, keeps the private half, and gives you a public key to publish under a selector of their choosing.

selector1._domainkey.example.com.  TXT  "v=DKIM1; k=rsa; p=MIGfMA0G..."

DMARC — ties the two together and tells receivers what to do on failure.

_dmarc.example.com.  TXT  "v=DMARC1; p=none; rua=mailto:dmarc@example.com"

Start at p=none, read the aggregate reports for a week or two, then move to p=quarantine and eventually p=reject.

The mistake almost everyone makes

DMARC does not just check that SPF and DKIM pass — it checks alignment: the domain in the visible From: header must match the domain SPF authorised, or the domain DKIM signed (d=). So if your From address is longbox@example.com but you relay through Gmail without configuring your domain there, SPF and DKIM can both pass on gmail.com and DMARC still fails.

Set LONGBOX_SMTP_FROM to an address at the domain you actually configured. If you do not own a domain, send from an address your relay already owns and authenticates (your own Gmail address, say) — never invent a From address on a domain you do not control.

Other things worth knowing

  • TLS. Use port 587 with STARTTLS, or 465 with implicit TLS. Longbox verifies certificates, so a relay with a self-signed certificate is refused. That is deliberate; the alternative is shipping credentials to anyone who can intercept the connection.
  • Credentials. Use an app password or a send-scoped API key, and put it in the admin page (it goes into the SQLite database) or the environment. Never the repository.
  • Make the links reachable. Set LONGBOX_PUBLIC_URL so links point at the hostname your users can actually resolve, not the container's. A reset link is a bearer credential, so serve it over HTTPS and set LONGBOX_SECURE_COOKIES=1.
  • Test it. Admin → Mail → Send a test message, then check the result with mail-tester.com, or open it in Gmail and use Show original to confirm SPF, DKIM and DMARC all say PASS.
  • Reverse DNS only matters if you ignore the advice above and send directly: the PTR for your sending IP must resolve to a name that resolves back to it.

Email is not a confidential channel

A reset link in an inbox is a bearer token, which is why they expire in an hour, work once, revoke every session when used, and trigger a notification to the account owner. If you would rather not rely on email at all, the administrator-hands-over-a-link route needs no mail server and is arguably better for a household: you can pass the link over something you actually trust.