Email Sending
Overview
The platform sends email to CMS users in two situations: password resets and setting an
initial password for a newly created account. The actual send is pushed onto the email queue
so that a slow SMTP server never holds up an API response.
This consumer has a distinctive behaviour carried over verbatim from the legacy implementation: a failed send is swallowed and the message is always acknowledged — no retry, no DLQ. Conversely, a payload that fails to parse is not acknowledged and will be redelivered.
Business Flow
- Receive a payload containing the destination address, the verification code, the expiry date in both date and text form, and a flag indicating whether this is a new account.
- If unmarshalling fails, the error is logged and returned. The mq layer therefore does not acknowledge and the message is redelivered on the next round. This matches the legacy system, where JSON parsing sat outside the try block and threw before reaching the ack.
- If the destination address is empty, nothing happens and the message is acknowledged.
- Assemble the template parameters and build the reset link in the form
${BASE_CONSOLE_WEB_URL}/reset-password?token=${code}. - Choose the template based on the new-account flag.
- New account: the first-password template, subject "Create a login password".
- Existing account: the reset template, subject "Reset password".
- If the send fails, the error is logged and swallowed and the message is acknowledged regardless — matching the legacy code, which called ack both in its catch block and on the final line.
Key Files & Functions
| File | Responsibility |
|---|---|
internal/mailconsumer/consumer.go | Consumer.Handle, which implements the parse-failure versus send-failure behaviour described above, plus Consumer.sendForgotPassword, Register, the SendForgotPasswordPayload type and the Mailer interface. The package doc explains the ack and redelivery quirk in detail. |
internal/mailx/mailx.go | Mailer, New, SendForgotPassword, SendNewAccount and ForgotPasswordParams |
cmd/worker/main.go | runMain — constructs the mailer and registers the consumer |
Queue: email, named by RABBITMQ_QUEUE_SENDMAIL and defaulting to email, on the main
profile.
Connections to Other Services
- Receives jobs from cms-api-go's auth and user domains — forgotten passwords and new user invitations.
- SMTP — configured through
MAIL_SMTP_HOST,MAIL_SMTP_PORT,MAIL_SMTP_SECURE,MAIL_SMTP_USERNAME,MAIL_SMTP_PASSWORD,MAIL_SMTP_FROM_NAMEandMAIL_SMTP_FROM_EMAILADDRESS. - Environment variable
BASE_CONSOLE_WEB_URL— the base of the reset link embedded in the email. - The consumer touches neither the database nor the LINE API.
- Deployment caveat — if the mailer fails to initialise at boot,
runMainlogs the error and returns immediately, which means themainprofile starts no consumers at all.