# Send emails with Discourse

> Point Discourse's SMTP settings at PostShiba.

## What you'll build

A self-hosted Discourse forum that sends its sign-up confirmations, password resets, notifications, and summary emails through PostShiba over SMTP.

## Before you start

- A **Transactional** cluster. Forum notification mail belongs on a transactional cluster, and the type is locked after create. See [Clusters](/docs/dashboard/clusters/introduction).
- An SMTP username and password. Open your cluster in the dashboard, go to its SMTP credentials, and choose **Create SMTP credential**. Copy the password right away, because it is shown once. You can also use the [SMTP credentials API](/docs/api-reference/smtp-credentials).
- A verified sending domain. See [Add and verify a domain](/docs/add-a-domain). The notification email address must be on it.
- A cluster that is ready to send (`sending_ready` is `true`).
- Shell access to a standard Docker install of Discourse, so you can edit `/var/discourse/containers/app.yml`.

## Install

Nothing to install. Discourse has SMTP support built in.

## Send your first email

1. Open `/var/discourse/containers/app.yml` and set these keys in the `env` section. Keep the other keys as they are. Port 587 with `DISCOURSE_SMTP_ENABLE_START_TLS` set to `true` upgrades the connection with STARTTLS. Leave `DISCOURSE_SMTP_FORCE_TLS` unset, because it is for port 465.

```yaml app.yml
env:
  DISCOURSE_SMTP_ADDRESS: smtp.postshiba.com
  DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: smtp_9
  DISCOURSE_SMTP_PASSWORD: "YOUR_PASSWORD"
  DISCOURSE_SMTP_ENABLE_START_TLS: true
  DISCOURSE_SMTP_AUTHENTICATION: plain
  DISCOURSE_NOTIFICATION_EMAIL: hello@mail.example.com
```

Keep the password in double quotes. A `#` outside quotes starts a YAML comment. `DISCOURSE_NOTIFICATION_EMAIL` sets the From address and locks the **notification email** site setting to it.

You can also run `./discourse-setup` from `/var/discourse`. It asks for the SMTP server address, port, user name, password, and notification email address, then writes them to `app.yml`.

2. Rebuild the container so Discourse reads the new settings.

```sh rebuild.sh
cd /var/discourse
./launcher rebuild app
```

3. Sign in as an admin and open `/admin/email/server-settings`. Enter your own address and select **Send test email**. The message shows under Events in the PostShiba dashboard.

Every SMTP setting is on [Send emails with SMTP](/docs/send-with-smtp).

## Troubleshooting

Discourse emails activity summaries to members who have not visited recently, weekly by default. On a large forum, summaries add up to many messages on top of notifications. Size the cluster so its 24-hour cap covers them. When a cap is full, SMTP answers `451 4.7.0 hourly send limit reached` or `451 4.7.0 daily send limit reached` and does not keep the message. Select **Resize** on the cluster page if you need more room. See [What happens at your cap](/docs/dashboard/clusters/what-happens-at-your-cap).

Discourse handles bounces with a VERP return address that it reads by POP3 or direct-delivery incoming mail. With PostShiba, the return path is PostShiba's, so bounces come back to PostShiba and do not show under bounced emails in Discourse. PostShiba suppresses addresses that hard bounce or report spam. Later sends to them are refused with `550 suppressed`.

| What you see in the Discourse log | What to do |
| --- | --- |
| Authentication fails | Check `DISCOURSE_SMTP_USER_NAME` and `DISCOURSE_SMTP_PASSWORD`, and set `DISCOURSE_SMTP_AUTHENTICATION` to `plain`. PostShiba accepts `AUTH PLAIN` only. Rebuild after each change. |
| `550 unverified domain` or `550 from header not aligned with verified domain` | Set `DISCOURSE_NOTIFICATION_EMAIL` to an address on your verified domain. If the **reply by email address** site setting contains `+`, Discourse sends from that address as the envelope sender, so it must be on your verified domain too. |
| `550 domain_suspended` | The From domain is paused. Resume it from [Managing domains](/docs/dashboard/domains/manage-domains). |
| `550 kyc_required` | Your team is pending production approval. Until then, send only to team members, live inbox addresses, and inbox forward-to addresses. See [Does PostShiba require production approval?](/docs/knowledge-base/does-capsule-require-production-approval). |
| `550 suppressed` or `550 firewall: <rule>` | The recipient is on the [suppression list](/docs/dashboard/emails/email-suppressions) or failed an [email firewall](/docs/dashboard/emails/email-firewall) check. |
| `451 4.7.0 hourly send limit reached` or `451 4.7.0 daily send limit reached` | The cluster is at its cap and did not keep the message. Retry later, or resize the cluster. |

## Next steps

- [What happens at your cap](/docs/dashboard/clusters/what-happens-at-your-cap)
- [How to manage suppressions](/docs/dashboard/emails/email-suppressions)
- [Send emails with SMTP](/docs/send-with-smtp) for every setting and reply.
- [Managing webhooks](/docs/webhooks/introduction) to receive delivery events.
