This example shows how to wire mailer into a small service, step by step.
flowchart LR
S1["1 · NewMailerSMTP<br/>(transport)"] --> S2["2 · NewMailService<br/>+ Start()"]
S2 --> S3["3 · Build message<br/>(validated)"] --> S4["4 · Enqueue()"] --> S5["5 · Stop()<br/>(drain + wait)"]
RequireTLS makes delivery fail rather than send credentials over an unencrypted
connection. On port 587 the client upgrades with STARTTLS; use port 465 (or
ImplicitTLS: true) for implicit TLS.
backend, err := mailer.NewMailerSMTP(mailer.MailerSMTPConf{
SMTPHost: "smtp.example.com",
SMTPPort: 587,
Username: os.Getenv("SMTP_USER"),
Password: os.Getenv("SMTP_PASS"),
RequireTLS: true,
})
if err != nil {
log.Fatal(err)
}ctx, cancel := context.WithCancel(context.Background())
defer cancel()
service, err := mailer.NewMailService(&mailer.MailServiceConfig{
Ctx: ctx,
WorkerCount: 4,
QueueSize: 64,
Mailer: backend,
})
if err != nil {
log.Fatal(err)
}
service.Start()content, err := mailer.NewMailContentBuilder().
WithFromName("Operations").
WithFromAddress("ops@example.com").
WithToName("Customer").
WithToAddress("customer@example.com").
WithMimeType(mailer.MimeTypeTextHTML).
WithSubject("Welcome").
WithBody("<p>Thanks for signing up.</p>").
Build()
if err != nil {
log.Fatal(err) // validation error (*mailer.MailerError)
}if err := service.Enqueue(content); err != nil {
// ErrServiceStopped, or a context error if the context was cancelled.
log.Print(err)
}Stop closes the queue, drains any messages still queued, and waits for the
workers to finish before returning.
service.Stop()This pattern suits CLI tools, HTTP handlers, and background jobs that need to offload email sending to a worker pool. See the runnable example/main.go for a complete program.