Reference

Email Module

Transactional email delivery for Redelay: SMTP, SendGrid, Mailgun, Mailjet, and SES backends, HTML templating, event-driven delivery.

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

shell
go get github.com/redelay/go-module-email
go
import _ "github.com/redelay/go-module-email"

How it works

  1. Other modules emit email.send events with to, subject, and either a body (pre-rendered HTML) or a template name + data map.
  2. 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.
  3. It renders the template (if specified) and delivers the email via the configured backend.

Event payload

json
{
  "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:

json
{
  "to": ["[email protected]"],
  "subject": "Hello",
  "body": "<p>Hello from Redelay!</p>"
}

Full payload fields (all optional except to):

FieldTypeDescription
to[]stringRecipient addresses
cc[]stringCC addresses
bcc[]stringBCC addresses
reply_tostringReply-To address
subjectstringEmail subject line
templatestringTemplate name to render
dataanyTemplate variables
bodystringPre-rendered HTML body (used if template unset or rendering fails)
localestringLocale suffix for template selection (template/locale)

Built-in templates

NameVariablesUse case
verificationVerificationURL, ExpiresInEmail address verification
welcomeAppNameNew user welcome
password_resetResetURL, ExpiresInPassword reset

Configuration

VariableDefaultDescription
EMAIL_FROM[email protected]Sender address in From header
EMAIL_FROM_NAME``Display name for the From header
EMAIL_SENDERsmtpBackend: smtp, sendgrid, mailgun, mailjet, or ses

SMTP (default)

VariableDefaultDescription
EMAIL_SMTP_HOSTlocalhostSMTP server host
EMAIL_SMTP_PORT25SMTP server port
EMAIL_SMTP_USER``SMTP auth username (optional)
EMAIL_SMTP_PASSWORD``SMTP auth password (optional)

SendGrid

VariableDefaultDescription
EMAIL_SENDGRID_API_KEY``SendGrid API key

Mailgun (SMTP relay)

VariableDefaultDescription
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)

VariableDefaultDescription
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)

VariableDefaultDescription
EMAIL_SES_REGIONus-east-1AWS 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:

shell
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

PackagePurpose
rootModule — factory, event consumer, template rendering
senderSender interface + Message struct
sender/smtpSMTP delivery using stdlib net/smtp
sender/sendgridSendGrid Web API v3 (stdlib net/http only)
sender/mailgunMailgun via SMTP relay
sender/mailjetMailjet via SMTP relay
sender/sesAmazon SES via SMTP relay
rendererHTML template renderer using html/template
templates/Built-in HTML email templates
flowdslFlowDSL node subpackage — email-send, email-render-template, email-send-templated

FlowDSL nodes

The flowdsl/ subpackage provides 3 FlowDSL nodes for email operations. Enable with:

go
import (
    _ "github.com/redelay/go-module-email"
    _ "github.com/redelay/go-module-email/flowdsl"   // 3 FlowDSL nodes
)
Node IDKindDescription
redelay/email-sendactionSend an email with explicit body
redelay/email-render-templatetransformRender an HTML template with data
redelay/email-send-templatedactionRender template and send in one step

Consuming email.send events in flows. Use the generic redelay/event-source node from go-flowdsl/nodes with eventName: email.send. Per-event source nodes (like the old redelay/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:

go
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:

go
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.