// Package email provides email sending functionality. package email import ( "bytes" "fmt" "html/template" "os" "path/filepath" "strconv" "strings" "time" "github.com/jaytaylor/html2text" "github.com/vanng822/go-premailer/premailer" ) var templates *template.Template type Mailer interface { Send(Message) error } // Message struct holds all parts of a specific email Message. type Message struct { From Email To Email Subject string Template string Content any html string text string } // parse parses the corrsponding template and content func (m *Message) parse() error { buf := new(bytes.Buffer) if err := templates.ExecuteTemplate(buf, m.Template, m.Content); err != nil { return err } prem, err := premailer.NewPremailerFromString(buf.String(), premailer.NewOptions()) if err != nil { return err } html, err := prem.Transform() if err != nil { return err } m.html = html text, err := html2text.FromString(html, html2text.Options{PrettyTables: true}) if err != nil { return err } m.text = text return nil } // Email struct holds email address and recipient name. type Email struct { Name string Address string } // NewEmail returns an email address. func NewEmail(name string, address string) Email { return Email{ Name: name, Address: address, } } func parseTemplates() error { templates = template.New("").Funcs(fMap) return filepath.Walk("./templates", func(path string, info os.FileInfo, err error) error { if strings.Contains(path, ".html") { _, err = templates.ParseFiles(path) return err } return err }) } var fMap = template.FuncMap{ "formatAsDate": formatAsDate, "formatAsDuration": formatAsDuration, } func formatAsDate(t time.Time) string { year, month, day := t.Date() return fmt.Sprintf("%d.%d.%d", day, month, year) } func formatAsDuration(t time.Time) string { dur := time.Until(t) hours := int(dur.Hours()) mins := int(dur.Minutes()) v := "" if hours != 0 { v += strconv.Itoa(hours) + " hours and " } v += strconv.Itoa(mins) + " minutes" return v }