servcvgen/email.go

134 lines
3.5 KiB
Go

package main
import (
"bytes"
"crypto/tls"
"fmt"
"html/template"
"log"
"strings"
"time"
cfg "github.com/jesusperez/cfgsrv"
// "text/template"
"github.com/toorop/go-dkim"
mail "github.com/xhit/go-simple-mail/v2"
)
func email(cfg *cfg.Config, tplType string, tplPath string, attachPath string, attachName string, request Mail, bodyData interface{}) error {
server := mail.NewSMTPClient()
// SMTP Server
server.Host = cfg.MailHost
server.Port = cfg.MailPort
server.Username = cfg.MailUser
server.Password = cfg.MailPswd
server.Encryption = mail.EncryptionSTARTTLS
// Since v2.3.0 you can specified authentication type:
// - PLAIN (default)
// - LOGIN
// - CRAM-MD5
// - None
server.Authentication = mail.AuthPlain
// Variable to keep alive connection
server.KeepAlive = true
// Timeout for connect to SMTP Server
server.ConnectTimeout = 10 * time.Second
// Timeout for send the data and wait respond
server.SendTimeout = 10 * time.Second
// Set TLSConfig to provide custom TLS configuration. For example,
// to skip TLS verification (useful for testing):
server.TLSConfig = &tls.Config{InsecureSkipVerify: true}
// SMTP client
smtpClient,err := server.Connect()
if err != nil{
return err
}
// New email simple html with inline and CC
email := mail.NewMSG()
email.SetFrom(request.Sender).AddTo(strings.Join(request.To,","))
if len(request.Cc) > 0 {
email.AddCc(strings.Join(request.Cc,","))
}
if len(request.Bcc) > 0 {
email.AddBcc(strings.Join(request.Bcc,","))
}
email.SetSubject(request.Subject)
// email.SetListUnsubscribe("<mailto:unsubscribe@example.com?subject=https://example.com/unsubscribe>").
// email.AddHeader("Date",time.Now().Format(time.RFC1123Z))
var body bytes.Buffer
if len(tplPath) > 0 {
t, _ := template.ParseFiles(tplPath)
// body.Write([]byte(msg))
//body.Write([]byte(fmt.Sprintf("%s \n%s\n\n", subject,mimeHeaders)))
t.Execute(&body, bodyData)
request.Body = body
}
contentType := mail.TextPlain
switch(tplType) {
case "text":
contentType = mail.TextPlain
case "html":
contentType = mail.TextHTML
}
var privateKey []byte
// if len(cfg.MailCertPath) > 0 {
// var err error
// privateKey, err = loadPath(cfg.MailCertPath)
// if err != nil {
// return err
// }
// }
// you can add dkim signature to the email.
// to add dkim, you need a private key already created one.
if privateKey != nil && len(privateKey) > 0 {
options := dkim.NewSigOptions()
options.PrivateKey = privateKey
options.Domain = cfg.MailCertDom
options.Selector = "default"
options.SignatureExpireIn = 3600
options.Headers = []string{"from", "date", "mime-version", "received", "received"}
options.AddSignatureTimestamp = true
options.Canonicalization = "relaxed/relaxed"
msg := []byte(request.Body.String())
errdkim := dkim.Sign(&msg, options)
if errdkim != nil {
return errdkim
}
email.SetBody(contentType, string(msg))
} else {
email.SetBody(contentType, request.Body.String())
}
if len(attachPath) > 0 {
email.Attach(&mail.File{FilePath: attachPath, Name: attachName, Inline: true})
}
// also you can add body from []byte with SetBodyData, example:
// email.SetBodyData(mail.TextHTML, []byte(htmlBody))
// or alternative part
// email.AddAlternativeData(mail.TextHTML, []byte(htmlBody))
// always check error after send
if email.Error != nil{
log.Fatal(email.Error)
}
// Sending email.
// Call Send and pass the client
err = email.Send(smtpClient)
if err != nil {
fmt.Printf("Error send mail: %v",err)
return err
}
fmt.Println("Email Sent!")
return nil
}