Email Module
go-module-email
github.com/redelay/go-module-email delivers transactional emails. It subscribes to
email.send events emitted by other modules (verification, auth, custom) and sends them
via the configured sender backend.
Quick start
go get github.com/redelay/go-module-email
import _ "github.com/redelay/go-module-email"
How it works
- Other modules emit
email.sendevents withto,subject, and either abody(pre-rendered HTML) or atemplatename +datamap. - The email module subscribes to these events via the Redelay event bus — consumer registration is auto-wired by the framework; no manual setup is needed.
- It renders the template (if specified) and delivers the email via the configured backend.
Event payload
{
"to": ["[email protected]"],
"subject": "Verify your email",
"template": "verification",
"data": {
"VerificationURL": "https://example.com/verify?token=abc123",
"ExpiresIn": "30m"
}
}
Or with a pre-rendered body:
{
"to": ["[email protected]"],
"subject": "Hello",
"body": "<p>Hello from Redelay!</p>"
}
Full payload fields (all optional except to):
| Field | Type | Description |
|---|---|---|
to | []string | Recipient addresses |
cc | []string | CC addresses |
bcc | []string | BCC addresses |
reply_to | string | Reply-To address |
subject | string | Email subject line |
template | string | Template name to render |
data | any | Template variables |
body | string | Pre-rendered HTML body (used if template unset or rendering fails) |
locale | string | Locale suffix for template selection (template/locale) |
Built-in templates
| Name | Variables | Use case |
|---|---|---|
verification | VerificationURL, ExpiresIn | Email address verification |
welcome | AppName | New user welcome |
password_reset | ResetURL, ExpiresIn | Password reset |
Configuration
| Variable | Default | Description |
|---|---|---|
EMAIL_FROM | [email protected] | Sender address in From header |
EMAIL_FROM_NAME | `` | Display name for the From header |
EMAIL_SENDER | smtp | Backend: smtp, sendgrid, mailgun, mailjet, or ses |
SMTP (default)
| Variable | Default | Description |
|---|---|---|
EMAIL_SMTP_HOST | localhost | SMTP server host |
EMAIL_SMTP_PORT | 25 | SMTP server port |
EMAIL_SMTP_USER | `` | SMTP auth username (optional) |
EMAIL_SMTP_PASSWORD | `` | SMTP auth password (optional) |
SendGrid
| Variable | Default | Description |
|---|---|---|
EMAIL_SENDGRID_API_KEY | `` | SendGrid API key |
Mailgun (SMTP relay)
| Variable | Default | Description |
|---|---|---|
EMAIL_MAILGUN_SMTP_HOST | `` | Mailgun SMTP host (e.g. smtp.mailgun.org) |
EMAIL_MAILGUN_SMTP_PORT | `` | Mailgun SMTP port (e.g. 587) |
EMAIL_MAILGUN_SMTP_USER | `` | Mailgun SMTP username |
EMAIL_MAILGUN_SMTP_PASSWORD | `` | Mailgun SMTP password |
Mailjet (SMTP relay)
| Variable | Default | Description |
|---|---|---|
EMAIL_MAILJET_SMTP_HOST | `` | Mailjet SMTP host |
EMAIL_MAILJET_SMTP_PORT | `` | Mailjet SMTP port |
EMAIL_MAILJET_API_KEY | `` | Mailjet API key |
EMAIL_MAILJET_SECRET_KEY | `` | Mailjet secret key |
Amazon SES (SMTP relay)
| Variable | Default | Description |
|---|---|---|
EMAIL_SES_REGION | us-east-1 | AWS region |
EMAIL_SES_SMTP_PORT | `` | SES SMTP port |
EMAIL_SES_SMTP_USER | `` | SES SMTP credentials (SMTP-specific access key) |
EMAIL_SES_SMTP_PASSWORD | `` | SES SMTP password |
Local development with Mailpit
Set TRANSPORT=memory (no broker required). Point SMTP at Mailpit:
TRANSPORT=memory
EMAIL_SENDER=smtp
EMAIL_SMTP_HOST=localhost
EMAIL_SMTP_PORT=1025
Mailpit UI: http://localhost:8025. All emails are caught locally — nothing is delivered externally.
Package structure
| Package | Purpose |
|---|---|
| root | Module — factory, event consumer, template rendering |
sender | Sender interface + Message struct |
sender/smtp | SMTP delivery using stdlib net/smtp |
sender/sendgrid | SendGrid Web API v3 (stdlib net/http only) |
sender/mailgun | Mailgun via SMTP relay |
sender/mailjet | Mailjet via SMTP relay |
sender/ses | Amazon SES via SMTP relay |
renderer | HTML template renderer using html/template |
templates/ | Built-in HTML email templates |
flowdsl | FlowDSL node subpackage — email-send, email-render-template, email-send-templated |
FlowDSL nodes
The flowdsl/ subpackage provides 3 FlowDSL nodes for email operations. Enable with:
import (
_ "github.com/redelay/go-module-email"
_ "github.com/redelay/go-module-email/flowdsl" // 3 FlowDSL nodes
)
| Node ID | Kind | Description |
|---|---|---|
redelay/email-send | action | Send an email with explicit body |
redelay/email-render-template | transform | Render an HTML template with data |
redelay/email-send-templated | action | Render template and send in one step |
Consuming
email.sendevents in flows. Use the genericredelay/event-sourcenode fromgo-flowdsl/nodeswitheventName: email.send. Per-event source nodes (like the oldredelay/email-send-event) have been removed — one configurable node replaces them all.
Emitting email.send events from your module
EmailSendEvent and EmailSendPayload live in the lightweight go-module-email/events package (it depends only on go-events/typed) — no custom payload type needed:
import (
"github.com/redelay/go-events/typed"
emailevents "github.com/redelay/go-module-email/events"
)
// In your handler:
msg, _ := emailevents.EmailSendEvent.NewMessage(
user.ID.Hex(),
typed.Actor{Type: typed.ActorTypeSystem, ID: "mymodule"},
emailevents.EmailSendPayload{
To: []string{user.Email},
Subject: "Verify your email",
Template: "verification",
Data: map[string]any{
"VerificationURL": verifyURL,
"ExpiresIn": "30m",
},
},
)
deps.EventBus.Publish(ctx, msg)
Custom sender backend
Implement the sender.Sender interface to use any delivery provider:
import "github.com/redelay/go-module-email/sender"
type MySender struct{}
func (s *MySender) Send(ctx context.Context, msg *sender.Message) error {
// deliver msg.To, msg.Subject, msg.Body
return nil
}
Wire it in via email.NewModuleWithSender(mySender) for testing, or register a custom factory.