package mail import ( "crypto/tls" "encoding/base64" "io" "apigo.cc/gojs" "apigo.cc/gojs/goja" "github.com/jaytaylor/html2text" "github.com/ssgo/u" "gopkg.in/gomail.v2" ) type SendOption struct { Cc []string Bcc []string Html bool Attachments []Attachment Embeds []Attachment } func (obj *Mailbox) Send(vm *goja.Runtime, to []string, subject, content string, option *SendOption) error { logger := gojs.GetLogger(vm) msg := gomail.NewMessage() if obj.senderName != "" { msg.SetHeader("From", msg.FormatAddress(obj.username, obj.senderName)) } else { msg.SetHeader("From", obj.username) } msg.SetHeader("To", to...) msg.SetHeader("Subject", subject) useHtml := false if option != nil { if len(option.Cc) > 0 { msg.SetHeader("Cc", option.Cc...) } if len(option.Bcc) > 0 { msg.SetHeader("Bcc", option.Bcc...) } if len(option.Attachments) > 0 { for _, attachment := range option.Attachments { if attachment.Path != "" { if u.FileExists(attachment.Path) { msg.Attach(attachment.Path) } else { logger.Error("mail attachment file not exists", "filename", attachment.Path, "to", to, "subject", subject) } } else if attachment.Data != "" { if attachment.Name == "" { attachment.Name = "attachment" } if attachment.ContentType == "" { attachment.ContentType = "text/plain" } buf, err := base64.StdEncoding.DecodeString(attachment.Data) if err != nil { buf = []byte(attachment.Data) } msg.Attach(attachment.Name, gomail.SetCopyFunc(func(w io.Writer) error { _, err := w.Write(buf) return err }), gomail.SetHeader(map[string][]string{ "Content-Type": {attachment.ContentType}, })) } } } if len(option.Embeds) > 0 { for _, attachment := range option.Embeds { if attachment.Path != "" { if u.FileExists(attachment.Path) { msg.Attach(attachment.Path) } else { logger.Error("mail embed file not exists", "filename", attachment.Path, "to", to, "subject", subject) } } else if attachment.Data != "" { if attachment.Name == "" { attachment.Name = "image" } if attachment.ContentType == "" { attachment.ContentType = "image/png" } buf, err := base64.StdEncoding.DecodeString(attachment.Data) if err != nil { buf = []byte(attachment.Data) } msg.Embed(attachment.Name, gomail.SetCopyFunc(func(w io.Writer) error { _, err := w.Write(buf) return err }), gomail.SetHeader(map[string][]string{ "Content-Type": {attachment.ContentType}, "Content-ID": {"<" + attachment.Name + ">"}, })) } } } useHtml = option.Html } if useHtml { msg.SetBody("text/html", content) textContent, err := html2text.FromString(content, html2text.Options{TextOnly: true, PrettyTables: true}) if err != nil { logger.Error("convert html to text failed", "err", err, "to", to, "subject", subject, "content", content) textContent = content } msg.AddAlternative("text/plain", textContent) } else { msg.SetBody("text/plain", content) } conn := gomail.NewDialer(obj.smtpHost, obj.smtpPort, obj.username, obj.password) switch obj.smtpPort { case 465: conn.SSL = true case 587: conn.TLSConfig = &tls.Config{ ServerName: obj.smtpHost, InsecureSkipVerify: false, } } // conn.Auth = smtp.PlainAuth("", obj.username, obj.password, obj.smtpHost) err := conn.DialAndSend(msg) if err != nil { logger.Error("send mail failed", "err", err.Error(), "to", to, "subject", "from", obj.username, subject, "content", content) } else { logger.Info("send mail success", "to", to, "from", obj.username, "subject", subject) } return err }