134 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			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
 | 
						|
} |