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  }