pkg/mailer: support plaintext alt for HTML emails (#5568)

* Added option to use plain text alt to HTML emails. Should make the messages friendlier for spam filters.

* Check that plaintext conversion worked before adding the HTML alt

* Add description of ADD_PLAIN_TEXT_ALT to app.ini

* Added comment clarifying html AddAlternative
This commit is contained in:
Guy Smoilov 2018-12-25 17:08:00 +02:00 committed by 无闻
parent 9b37b1569c
commit 5702e4bc24
3 changed files with 25 additions and 13 deletions

View File

@ -250,6 +250,8 @@ USER =
PASSWD = PASSWD =
; Use text/plain as format of content ; Use text/plain as format of content
USE_PLAIN_TEXT = false USE_PLAIN_TEXT = false
; If sending html emails, then also attach a plaintext alternative to the MIME message, to support older mail clients and make spam filters happier.
ADD_PLAIN_TEXT_ALT = false
[cache] [cache]
; Either "memory", "redis", or "memcache", default is "memory" ; Either "memory", "redis", or "memcache", default is "memory"

View File

@ -39,16 +39,24 @@ func NewMessageFrom(to []string, from, subject, htmlBody string) *Message {
contentType := "text/html" contentType := "text/html"
body := htmlBody body := htmlBody
if setting.MailService.UsePlainText { switchedToPlaintext := false
if setting.MailService.UsePlainText || setting.MailService.AddPlainTextAlt {
plainBody, err := html2text.FromString(htmlBody) plainBody, err := html2text.FromString(htmlBody)
if err != nil { if err != nil {
log.Error(2, "html2text.FromString: %v", err) log.Error(2, "html2text.FromString: %v", err)
} else { } else {
contentType = "text/plain" contentType = "text/plain"
body = plainBody body = plainBody
switchedToPlaintext = true
} }
} }
msg.SetBody(contentType, body) msg.SetBody(contentType, body)
if switchedToPlaintext && setting.MailService.AddPlainTextAlt && !setting.MailService.UsePlainText {
// The AddAlternative method name is confusing - adding html as an "alternative" will actually cause mail
// clients to show it as first priority, and the text "main body" is the 2nd priority fallback.
// See: https://godoc.org/gopkg.in/gomail.v2#Message.AddAlternative
msg.AddAlternative("text/html", htmlBody)
}
return &Message{ return &Message{
Message: msg, Message: msg,
confirmChan: make(chan struct{}), confirmChan: make(chan struct{}),

View File

@ -861,6 +861,7 @@ type Mailer struct {
UseCertificate bool UseCertificate bool
CertFile, KeyFile string CertFile, KeyFile string
UsePlainText bool UsePlainText bool
AddPlainTextAlt bool
} }
var ( var (
@ -876,18 +877,19 @@ func newMailService() {
} }
MailService = &Mailer{ MailService = &Mailer{
QueueLength: sec.Key("SEND_BUFFER_LEN").MustInt(100), QueueLength: sec.Key("SEND_BUFFER_LEN").MustInt(100),
SubjectPrefix: sec.Key("SUBJECT_PREFIX").MustString("[" + AppName + "] "), SubjectPrefix: sec.Key("SUBJECT_PREFIX").MustString("[" + AppName + "] "),
Host: sec.Key("HOST").String(), Host: sec.Key("HOST").String(),
User: sec.Key("USER").String(), User: sec.Key("USER").String(),
Passwd: sec.Key("PASSWD").String(), Passwd: sec.Key("PASSWD").String(),
DisableHelo: sec.Key("DISABLE_HELO").MustBool(), DisableHelo: sec.Key("DISABLE_HELO").MustBool(),
HeloHostname: sec.Key("HELO_HOSTNAME").String(), HeloHostname: sec.Key("HELO_HOSTNAME").String(),
SkipVerify: sec.Key("SKIP_VERIFY").MustBool(), SkipVerify: sec.Key("SKIP_VERIFY").MustBool(),
UseCertificate: sec.Key("USE_CERTIFICATE").MustBool(), UseCertificate: sec.Key("USE_CERTIFICATE").MustBool(),
CertFile: sec.Key("CERT_FILE").String(), CertFile: sec.Key("CERT_FILE").String(),
KeyFile: sec.Key("KEY_FILE").String(), KeyFile: sec.Key("KEY_FILE").String(),
UsePlainText: sec.Key("USE_PLAIN_TEXT").MustBool(), UsePlainText: sec.Key("USE_PLAIN_TEXT").MustBool(),
AddPlainTextAlt: sec.Key("ADD_PLAIN_TEXT_ALT").MustBool(),
} }
MailService.From = sec.Key("FROM").MustString(MailService.User) MailService.From = sec.Key("FROM").MustString(MailService.User)