github.com/mongodb/grip@v0.0.0-20240213223901-f906268d82b9/message/email.go (about) 1 package message 2 3 import ( 4 "fmt" 5 "net/mail" 6 7 "github.com/mongodb/grip/level" 8 ) 9 10 // Email represents the parameters of an email message 11 type Email struct { 12 From string `bson:"from" json:"from" yaml:"from"` 13 Recipients []string `bson:"recipients" json:"recipients" yaml:"recipients"` 14 Subject string `bson:"subject" json:"subject" yaml:"subject"` 15 Body string `bson:"body" json:"body" yaml:"body"` 16 // PlainTextContents dictates the Content-Type of the email. If true, 17 // it will text/plain; otherwise, it is text/html. This value is overridden 18 // by the presence of a "Content-Type" header in Headers. 19 PlainTextContents bool `bson:"is_plain_text" json:"is_plain_text" yaml:"is_plain_text"` 20 21 // Headers adds additional headers to the email body, ignoring any 22 // named "To", "From", "Subject", or "Content-Transfer-Encoding" 23 // (which should be set with the above fields) 24 Headers map[string][]string `bson:"headers" json:"headers" yaml:"headers"` 25 } 26 27 type emailMessage struct { 28 data Email 29 Base `bson:"metadata" json:"metadata" yaml:"metadata"` 30 } 31 32 // NewEmailMessage returns a composer for emails 33 func NewEmailMessage(l level.Priority, e Email) Composer { 34 m := MakeEmailMessage(e) 35 _ = m.SetPriority(l) 36 37 return m 38 } 39 40 // MakeEmailMessage creates a composer for emails without a priority set 41 func MakeEmailMessage(e Email) Composer { 42 return &emailMessage{ 43 data: e, 44 } 45 } 46 47 func (e *emailMessage) Loggable() bool { 48 if len(e.data.From) != 0 { 49 if _, err := mail.ParseAddress(e.data.From); err != nil { 50 return false 51 } 52 } 53 54 if len(e.data.Recipients) == 0 { 55 return false 56 } 57 for i := range e.data.Recipients { 58 _, err := mail.ParseAddress(e.data.Recipients[i]) 59 if err != nil { 60 return false 61 } 62 } 63 if len(e.data.Subject) == 0 { 64 return false 65 } 66 if len(e.data.Body) == 0 { 67 return false 68 } 69 70 // reject empty headers 71 for _, v := range e.data.Headers { 72 if len(v) == 0 { 73 return false 74 } 75 } 76 77 return true 78 } 79 80 func (e *emailMessage) Raw() interface{} { 81 return &e.data 82 } 83 84 func (e *emailMessage) String() string { 85 const ( 86 tmpl = `To: %s; %sBody: %s` 87 headerTmpl = "%s: %s\n" 88 ) 89 90 headers := "Headers: " 91 for k, v := range e.data.Headers { 92 headers += fmt.Sprintf(headerTmpl, k, v) 93 } 94 if len(e.data.Headers) == 0 { 95 headers = "" 96 } else { 97 headers += "; " 98 } 99 100 to := "" 101 for i, recp := range e.data.Recipients { 102 to += recp 103 if i != (len(e.data.Recipients) - 1) { 104 to += ", " 105 } 106 } 107 108 return fmt.Sprintf(tmpl, to, headers, e.data.Body) 109 }