Now renders a .md file to use as the text and HTML versions of emails.

master
Zed A. Shaw 4 weeks ago
parent 9302a97f4d
commit 5ff799f5e7
  1. 46
      common/email/api.go
  2. 5
      common/email/data.go
  3. 1
      config/settings.go
  4. 3
      config_example.json
  5. 3
      emails/signup.html
  6. 4
      emails/signup.md
  7. 3
      features/email/api.go
  8. 3
      tools/cmd/qmgr/main.go

@ -6,17 +6,14 @@ import (
"context" "context"
"log" "log"
"github.com/redis/go-redis/v9" "github.com/redis/go-redis/v9"
"github.com/gofiber/template/html/v2" "github.com/yuin/goldmark"
"MY/webapp/config" "MY/webapp/config"
"path/filepath"
"text/template"
"os"
"strings" "strings"
) )
var HTMLTemplates *html.Engine
func init() {
HTMLTemplates = html.New("./emails", ".html")
}
func NewSender(ctx context.Context) (Sender){ func NewSender(ctx context.Context) (Sender){
client := redis.NewClient(&redis.Options{ client := redis.NewClient(&redis.Options{
Addr: config.Settings.Redis.HostPort, Addr: config.Settings.Redis.HostPort,
@ -55,6 +52,33 @@ func (sender *Sender) Close() {
sender.redis_client.Close() sender.redis_client.Close()
} }
func (router *Router) Render(tmpl_path string, data any) (string, string, error) {
tmpl_path = filepath.Join(config.Settings.Email.Templates, tmpl_path)
// load the markdown file
md_file, err := os.ReadFile(tmpl_path)
if err != nil { return "", "", err }
// template it
tmpl, err := template.New(tmpl_path).Parse(string(md_file))
if err != nil { return "", "", err }
out := new(strings.Builder)
err = tmpl.Execute(out, data)
if err != nil { return "", "", err }
text_out := out.String()
// convert to html
out.Reset()
err = goldmark.Convert([]byte(text_out), out)
if err != nil { return "", "", err }
html_out := out.String()
// return the template .md as plain text and .html as html
return string(text_out), string(html_out), nil
}
func (router *Router) DeliverEmail(msg EmailMessage) error { func (router *Router) DeliverEmail(msg EmailMessage) error {
email_msg := mail.NewMsg() email_msg := mail.NewMsg()
err := email_msg.From(msg.From) err := email_msg.From(msg.From)
@ -65,10 +89,6 @@ func (router *Router) DeliverEmail(msg EmailMessage) error {
email_msg.Subject(msg.Subject) email_msg.Subject(msg.Subject)
out := new(strings.Builder)
err = HTMLTemplates.Render(out, msg.HTMLTemplate, msg.Data)
email_msg.SetBodyString(mail.TypeTextHTML, out.String())
if config.Settings.Email.XMailer != "" { if config.Settings.Email.XMailer != "" {
email_msg.SetGenHeader(mail.HeaderXMailer, config.Settings.Email.XMailer) email_msg.SetGenHeader(mail.HeaderXMailer, config.Settings.Email.XMailer)
} }
@ -77,8 +97,12 @@ func (router *Router) DeliverEmail(msg EmailMessage) error {
email_msg.SetGenHeader(mail.HeaderUserAgent, config.Settings.Email.UserAgent) email_msg.SetGenHeader(mail.HeaderUserAgent, config.Settings.Email.UserAgent)
} }
text, html, err := router.Render(msg.Template, nil)
if err != nil { return err } if err != nil { return err }
email_msg.SetBodyString(mail.TypeTextHTML, html)
email_msg.AddAlternativeString(mail.TypeTextPlain, text)
err = router.smtp_client.DialAndSendWithContext(router.ctx, email_msg) err = router.smtp_client.DialAndSendWithContext(router.ctx, email_msg)
if err != nil { return err } if err != nil { return err }

@ -4,15 +4,15 @@ import (
"github.com/redis/go-redis/v9" "github.com/redis/go-redis/v9"
"github.com/wneessen/go-mail" "github.com/wneessen/go-mail"
"context" "context"
) )
type EmailMessage struct { type EmailMessage struct {
To string To string
From string From string
Subject string Subject string
Template string
Data any Data any
TextTemplate string
HTMLTemplate string
} }
type Sender struct { type Sender struct {
@ -24,5 +24,6 @@ type Router struct {
redis_client *redis.Client redis_client *redis.Client
smtp_client *mail.Client smtp_client *mail.Client
ctx context.Context ctx context.Context
} }

@ -28,6 +28,7 @@ type config struct {
XMailer string XMailer string
UserAgent string UserAgent string
RedisQueue string RedisQueue string
Templates string
} }
} }

@ -19,6 +19,7 @@
"Port": 1025, "Port": 1025,
"XMailer": "nunya-business", "XMailer": "nunya-business",
"UserAgent": "nunya-business", "UserAgent": "nunya-business",
"RedisQueue": "email" "RedisQueue": "email",
"Templates": "emails"
} }
} }

@ -1,3 +0,0 @@
<h1>Welcome!</h1>
<p>You signed up!</p>

@ -0,0 +1,4 @@
Welcome
=======
Welcome to my website!

@ -11,8 +11,7 @@ func PostApiEmailSend(c *fiber.Ctx) error {
To: c.FormValue("To"), To: c.FormValue("To"),
From: c.FormValue("From"), From: c.FormValue("From"),
Subject: c.FormValue("Subject"), Subject: c.FormValue("Subject"),
TextTemplate: c.FormValue("Template"), Template: c.FormValue("Template"),
HTMLTemplate: c.FormValue("Template"),
}) })
return c.Redirect("/email/") return c.Redirect("/email/")

@ -15,8 +15,7 @@ func main() {
To: "tina.recip@example.com", To: "tina.recip@example.com",
From: "toni.sender@example.com", From: "toni.sender@example.com",
Subject: "This is my first mail.", Subject: "This is my first mail.",
TextTemplate: "signup", Template: "signup",
HTMLTemplate: "signup",
} }
sender := email.NewSender(ctx) sender := email.NewSender(ctx)

Loading…
Cancel
Save