Skip to main content

Sender addresses, sending speed and testing

Once a provider is chosen, three things are left: the sender's name and address, how fast announcements go out, and proving that it all works. This page covers them for whoever runs the server.

Sender and reply addresses​

VariableDefaultWhat it does
EMAIL_FROMnoneWho the email is from, for every message. Write it as Harmony Community Choir <noreply@example.org>. A bare address also works. Required for every provider except log and none.
EMAIL_REPLY_TOnoneWhere replies go, unless the message sets its own. For announcements, the committee's mailbox is a good choice.
CONTACT_FORM_TOthe public email in Site SettingsWhere contact-form messages are sent. Also where the notice goes when someone stops or restarts a kind of mail.

Details:

  • A contact-form message sets its own reply address, the visitor's, so replying to it answers the visitor whatever EMAIL_REPLY_TO says.
  • CONTACT_FORM_TO falls back to the email address under Site Settings, Contact. If neither is set, or email is off or has no EMAIL_FROM, or the send fails, the contact message is kept under Messages in the admin panel instead of being emailed, and no opt-out notice is sent. (Messages is in the admin menu while the Contact form switch in Site Settings, Features is on.)
  • Announcements and the other kind can have their own sender; see Send announcements through a different service.
EMAIL_FROM="Harmony Community Choir <noreply@example.org>"
EMAIL_REPLY_TO=board@example.org
CONTACT_FORM_TO=board@example.org

The wording of the emails​

The sign-off on login links and ticket emails, and the foot of announcements, are not set on the server. An admin changes them in Site Settings, Email; see The sign-off and footer of your emails.

In production, unsubscribe links and the login links themselves are built from SITE_URL, never from the address a visitor happened to use. (In development, with SITE_URL empty, they follow the page that asked.) If SITE_URL is wrong, those links point to the wrong place. In production the server warns "SITE_URL is not set: emailed login links need the site address" when it is missing.

Sending speed​

Announcements and mailings are not sent from one long job. The admin's page asks the server for one batch at a time and keeps asking until everyone has been sent to, then reports any address that failed.

VariableDefaultWhat it does
EMAIL_BATCH_SIZE15How many people each request sends to.
EMAIL_PER_SECOND8How many messages go out at once before a one-second pause. A batch is sent in groups of this size (never larger than the batch itself).

With the defaults, a batch of 15 goes as a group of 8, a pause of a second, then a group of 7. Both settings have a floor of 1.

  • The admin must keep the page open until it says the sending is finished. Closing it stops the requests.
  • On Node or Docker, raise EMAIL_BATCH_SIZE (for example to 50) to send fewer, longer requests. Keep EMAIL_PER_SECOND below your provider's own limit; Amazon SES, for one, publishes a sending rate for each account.
  • On Cloudflare, the free plan allows 50 outbound requests for each invocation of the Worker, which is why the batch is small. Stay near 15 on the free plan; a paid plan allows more.

Make sure mail is delivered​

Each provider tells you to prove that you own the sending domain, by adding DNS records. Do that before going live:

  1. Verify the domain of EMAIL_FROM with your provider.
  2. Add the SPF and DKIM records the provider gives you. Without them many inboxes will put your mail in spam, or refuse it.
  3. Send from an address on that domain. A sender such as noreply@example.org is fine with a sending service even if it is not a real mailbox (an ordinary mail server may insist on an address of the account), but replies to it will vanish, so set EMAIL_REPLY_TO to a mailbox someone reads.

Test it​

  1. Run npm run config:check on the server. It prints the settings in force with secrets masked and lists problems, such as a missing sender. Exit status 1 means problems were found. See Check your configuration.
  2. Test a login link. On the member portal's login page, enter the address of a member who exists and check that the link arrives. (The form gives the same answer for any address, so a missing email does not tell you the address is unknown; look in the server log.)
  3. Test an announcement. In the admin panel open Announcements, press Email to members on an announcement, enter your own address under Send a test to one address first and press Send test. One real email goes through the configured provider, with the subject starting [Test], and the page tells you whether it worked. The announcement must be visible to members first. Mailings to donors and ticket holders have a Send test button of their own.
  4. Test the contact form by sending a message from your public site, and check that it arrives at CONTACT_FORM_TO.

If the page says "The test email could not be sent", the reason is in the server log, starting with the provider's name, for example Resend rejected the email. Then see Troubleshooting: nobody can log in, or emails do not arrive.

With EMAIL_PROVIDER=log the test appears to succeed, because the "send" is writing to the log. The page adds a note when this happens, so look there for the message rather than in an inbox.