Generate pseudo-random Message-Id header for each outgoing emails
This commit is contained in:
parent
3a1d08661b
commit
754922b250
|
@ -2,11 +2,21 @@ package mail
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
|
"net/mail"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
gomail "gopkg.in/mail.v2"
|
gomail "gopkg.in/mail.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrUnexpectedEmailAddressFormat = errors.New("unexpected email address format")
|
||||||
|
)
|
||||||
|
|
||||||
type SendFunc func(*SendOption)
|
type SendFunc func(*SendOption)
|
||||||
|
|
||||||
type SendOption struct {
|
type SendOption struct {
|
||||||
|
@ -124,6 +134,20 @@ func (m *Mailer) Send(funcs ...SendFunc) error {
|
||||||
message.SetHeader(h.Field, h.Values...)
|
message.SetHeader(h.Field, h.Values...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
froms := message.GetHeader("From")
|
||||||
|
|
||||||
|
var sendDomain string
|
||||||
|
|
||||||
|
if len(froms) > 0 {
|
||||||
|
sendDomain, err = extractEmailDomain(froms[0])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
messageID := generateMessageID(sendDomain)
|
||||||
|
message.SetHeader("Message-Id", messageID)
|
||||||
|
|
||||||
message.SetBody(opt.Body.Type, opt.Body.Content, opt.Body.PartSetting)
|
message.SetBody(opt.Body.Type, opt.Body.Content, opt.Body.PartSetting)
|
||||||
|
|
||||||
for _, b := range opt.AlternativeBodies {
|
for _, b := range opt.AlternativeBodies {
|
||||||
|
@ -158,3 +182,26 @@ func (m *Mailer) openConnection() (gomail.SendCloser, error) {
|
||||||
|
|
||||||
return conn, nil
|
return conn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func extractEmailDomain(email string) (string, error) {
|
||||||
|
address, err := mail.ParseAddress(email)
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.Wrapf(err, "could not parse email address '%s'", email)
|
||||||
|
}
|
||||||
|
|
||||||
|
addressParts := strings.SplitN(address.Address, "@", 2)
|
||||||
|
if len(addressParts) != 2 { // nolint: gomnd
|
||||||
|
return "", errors.WithStack(ErrUnexpectedEmailAddressFormat)
|
||||||
|
}
|
||||||
|
|
||||||
|
domain := addressParts[1]
|
||||||
|
|
||||||
|
return domain, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateMessageID(domain string) string {
|
||||||
|
// Based on https://www.jwz.org/doc/mid.html
|
||||||
|
timestamp := strconv.FormatInt(time.Now().UnixNano(), 36)
|
||||||
|
random := strconv.FormatInt(rand.Int63(), 36)
|
||||||
|
return fmt.Sprintf("<%s.%s@%s>", timestamp, random, domain)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue