github.com/sotirispl/buffalo@v0.11.1/mail/smtp_sender.go (about)

     1  package mail
     2  
     3  import (
     4  	"io"
     5  	"strconv"
     6  
     7  	"github.com/pkg/errors"
     8  	gomail "gopkg.in/mail.v2"
     9  )
    10  
    11  //SMTPSender allows to send Emails by connecting to a SMTP server.
    12  type SMTPSender struct {
    13  	Dialer *gomail.Dialer
    14  }
    15  
    16  //Send a message using SMTP configuration or returns an error if something goes wrong.
    17  func (sm SMTPSender) Send(message Message) error {
    18  	gm := gomail.NewMessage()
    19  
    20  	gm.SetHeader("From", message.From)
    21  	gm.SetHeader("To", message.To...)
    22  	gm.SetHeader("Subject", message.Subject)
    23  	gm.SetHeader("Cc", message.CC...)
    24  	gm.SetHeader("Bcc", message.Bcc...)
    25  
    26  	sm.addBodies(message, gm)
    27  	sm.addAttachments(message, gm)
    28  
    29  	for field, value := range message.Headers {
    30  		gm.SetHeader(field, value)
    31  	}
    32  
    33  	err := sm.Dialer.DialAndSend(gm)
    34  
    35  	if err != nil {
    36  		return errors.WithStack(err)
    37  	}
    38  
    39  	return nil
    40  }
    41  
    42  func (sm SMTPSender) addBodies(message Message, gm *gomail.Message) {
    43  	if len(message.Bodies) == 0 {
    44  		return
    45  	}
    46  
    47  	mainBody := message.Bodies[0]
    48  	gm.SetBody(mainBody.ContentType, mainBody.Content, gomail.SetPartEncoding(gomail.Unencoded))
    49  
    50  	for i := 1; i < len(message.Bodies); i++ {
    51  		alt := message.Bodies[i]
    52  		gm.AddAlternative(alt.ContentType, alt.Content, gomail.SetPartEncoding(gomail.Unencoded))
    53  	}
    54  }
    55  
    56  func (sm SMTPSender) addAttachments(message Message, gm *gomail.Message) {
    57  	for _, at := range message.Attachments {
    58  		settings := gomail.SetCopyFunc(func(w io.Writer) error {
    59  			if _, err := io.Copy(w, at.Reader); err != nil {
    60  				return err
    61  			}
    62  
    63  			return nil
    64  		})
    65  
    66  		gm.Attach(at.Name, settings)
    67  	}
    68  }
    69  
    70  //NewSMTPSender builds a SMTP mail based in passed config.
    71  func NewSMTPSender(host string, port string, user string, password string) (SMTPSender, error) {
    72  	iport, err := strconv.Atoi(port)
    73  
    74  	if err != nil {
    75  		return SMTPSender{}, errors.New("invalid port for the SMTP mail")
    76  	}
    77  
    78  	dialer := &gomail.Dialer{
    79  		Host: host,
    80  		Port: iport,
    81  	}
    82  
    83  	if user != "" {
    84  		dialer.Username = user
    85  		dialer.Password = password
    86  	}
    87  
    88  	return SMTPSender{
    89  		Dialer: dialer,
    90  	}, nil
    91  }