mirror of
https://github.com/1f349/simplemail.git
synced 2025-04-13 15:25:53 +01:00
Improve customisability of headers when using simplemail
This commit is contained in:
parent
0141a7426e
commit
fccaef81bc
@ -22,7 +22,6 @@ func (f *FromAddress) UnmarshalText(b []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f FromAddress) ToMailAddress() *mail.Address {
|
||||
m := mail.Address(f)
|
||||
return &m
|
||||
func (f *FromAddress) ToMailAddress() *mail.Address {
|
||||
return (*mail.Address)(f)
|
||||
}
|
||||
|
50
mail.go
50
mail.go
@ -1,14 +1,12 @@
|
||||
package simplemail
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"github.com/emersion/go-message/mail"
|
||||
"github.com/emersion/go-sasl"
|
||||
"github.com/emersion/go-smtp"
|
||||
"io"
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Mail struct {
|
||||
@ -69,51 +67,17 @@ func isLocalhost(host string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (m *Mail) SendMail(subject string, to []*mail.Address, htmlBody, textBody io.Reader) error {
|
||||
// generate the email in this template
|
||||
buf := new(bytes.Buffer)
|
||||
|
||||
// setup mail headers
|
||||
var h mail.Header
|
||||
h.SetDate(time.Now())
|
||||
h.SetSubject(subject)
|
||||
h.SetAddressList("From", []*mail.Address{m.From.ToMailAddress()})
|
||||
h.SetAddressList("To", to)
|
||||
h.Set("Content-Type", "multipart/alternative")
|
||||
|
||||
// setup html and text alternative headers
|
||||
var hHtml, hTxt mail.InlineHeader
|
||||
hHtml.Set("Content-Type", "text/html; charset=utf-8")
|
||||
hTxt.Set("Content-Type", "text/plain; charset=utf-8")
|
||||
|
||||
createWriter, err := mail.CreateWriter(buf, h)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
inline, err := createWriter.CreateInline()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
partHtml, err := inline.CreatePart(hHtml)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := io.Copy(partHtml, htmlBody); err != nil {
|
||||
return err
|
||||
}
|
||||
partTxt, err := inline.CreatePart(hTxt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := io.Copy(partTxt, textBody); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// SendMail sends a mail message to the provided mail addresses.
|
||||
//
|
||||
// The reader should follow the format of an RFC 822-style email.
|
||||
//
|
||||
// See github.com/emersion/go-smtp.SendMail
|
||||
func (m *Mail) SendMail(to []*mail.Address, mailMessage io.Reader) error {
|
||||
// convert all to addresses to strings
|
||||
toStr := make([]string, len(to))
|
||||
for i := range toStr {
|
||||
toStr[i] = to[i].String()
|
||||
}
|
||||
|
||||
return m.mailCall(toStr, buf)
|
||||
return m.mailCall(toStr, mailMessage)
|
||||
}
|
||||
|
62
preparedmail.go
Normal file
62
preparedmail.go
Normal file
@ -0,0 +1,62 @@
|
||||
package simplemail
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/emersion/go-message/mail"
|
||||
"io"
|
||||
)
|
||||
|
||||
type PreparedMail struct {
|
||||
simpleMail *SimpleMail
|
||||
templateName string
|
||||
Header mail.Header
|
||||
rcpt []*mail.Address
|
||||
data map[string]any
|
||||
}
|
||||
|
||||
func (p *PreparedMail) SendMail() error {
|
||||
buf := new(bytes.Buffer)
|
||||
|
||||
var bufHtml, bufTxt bytes.Buffer
|
||||
p.simpleMail.render(&bufHtml, &bufTxt, p.templateName, p.data)
|
||||
|
||||
// setup html and text alternative headers
|
||||
var hHtml, hTxt mail.InlineHeader
|
||||
hHtml.Set("Content-Type", "text/html; charset=utf-8")
|
||||
hTxt.Set("Content-Type", "text/plain; charset=utf-8")
|
||||
|
||||
createWriter, err := mail.CreateWriter(buf, p.Header)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
inline, err := createWriter.CreateInline()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = copyToPart(inline, hHtml, &bufHtml)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = copyToPart(inline, hTxt, &bufTxt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = inline.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return p.simpleMail.mailSender.SendMail(p.rcpt, buf)
|
||||
}
|
||||
|
||||
func copyToPart(inline *mail.InlineWriter, header mail.InlineHeader, body io.Reader) error {
|
||||
part, err := inline.CreatePart(header)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = io.Copy(part, body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return part.Close()
|
||||
}
|
@ -1,13 +1,13 @@
|
||||
package simplemail
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/emersion/go-message/mail"
|
||||
htmlTemplate "html/template"
|
||||
"io"
|
||||
"io/fs"
|
||||
"log"
|
||||
textTemplate "text/template"
|
||||
"time"
|
||||
)
|
||||
|
||||
type SimpleMail struct {
|
||||
@ -40,8 +40,29 @@ func (m *SimpleMail) render(wrHtml, wrTxt io.Writer, name string, data any) {
|
||||
}
|
||||
}
|
||||
|
||||
func (m *SimpleMail) Send(templateName, subject string, to *mail.Address, data map[string]any) error {
|
||||
var bufHtml, bufTxt bytes.Buffer
|
||||
m.render(&bufHtml, &bufTxt, templateName, data)
|
||||
return m.mailSender.SendMail(subject, []*mail.Address{to}, &bufHtml, &bufTxt)
|
||||
// PrepareSingle constructs the headers for sending an email to the provided mail address.
|
||||
func (m *SimpleMail) PrepareSingle(templateName, subject string, to *mail.Address, data map[string]any) *PreparedMail {
|
||||
return m.PrepareMany(templateName, subject, []*mail.Address{to}, data)
|
||||
}
|
||||
|
||||
// PrepareMany constructs the headers for sending an email to the provided mail addresses.
|
||||
func (m *SimpleMail) PrepareMany(templateName, subject string, to []*mail.Address, data map[string]any) *PreparedMail {
|
||||
p := &PreparedMail{
|
||||
simpleMail: m,
|
||||
templateName: templateName,
|
||||
rcpt: to,
|
||||
data: data,
|
||||
}
|
||||
p.Header.SetDate(time.Now())
|
||||
p.Header.SetSubject(subject)
|
||||
p.Header.SetAddressList("From", []*mail.Address{m.mailSender.From.ToMailAddress()})
|
||||
p.Header.SetAddressList("To", to)
|
||||
p.Header.Set("Content-Type", "multipart/alternative")
|
||||
return p
|
||||
}
|
||||
|
||||
// Send is a simplified version of PrepareSingle which sends the mail without allowing header modifications.
|
||||
func (m *SimpleMail) Send(templateName, subject string, to *mail.Address, data map[string]any) error {
|
||||
p := m.PrepareSingle(templateName, subject, to, data)
|
||||
return p.SendMail()
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user