golang TLS方式发送邮件

发布时间 2023-04-07 14:34:31作者: 单眼皮Boy
package mail

import (
	"crypto/tls"
	"errors"
	"fmt"
	"net/smtp"
	"net/textproto"
)

type loginAuth struct {
	username, password string
}

// LoginAuth is
func LoginAuth(username string, password string) smtp.Auth {
	return &loginAuth{username, password}
}

func (a *loginAuth) Start(server *smtp.ServerInfo) (string, []byte, error) {
	return "LOGIN", []byte{}, nil
}

func (a *loginAuth) Next(fromServer []byte, more bool) ([]byte, error) {
	if more {
		switch string(fromServer) {
		case "Username:":
			return []byte(a.username), nil
		case "Password:":
			return []byte(a.password), nil
		default:
			return nil, errors.New("UNKNOWN SERVER")
		}
	}
	return nil, nil
}

func SendMail(fromEmail string, recepients string, subject, body, mailServer, mailPort, mailUser, mailPassword string) error {
	headers := make(map[string]string)
	headers["From"] = fromEmail
	headers["To"] = recepients
	headers["Subject"] = subject
	headers["Content-Type:text/html;charset=\"UTF-8\""] = ""
	message := ""
	for k, v := range headers {
		message += fmt.Sprintf("%s: %s\r\n", k, v)
	}
	message += body
	tlsconfig := &tls.Config{
		InsecureSkipVerify: false,
		ServerName:         mailServer,
	}

	conn, err := tls.Dial("tcp", mailServer+":"+mailPort, tlsconfig)
	if err != nil {
		err = fmt.Errorf("mail: tls.Dial error: %v", err)
		return err
	}
	c, err := smtp.NewClient(conn, mailServer)
	if err != nil {
		err = fmt.Errorf("mail: smtp.NewClient error. %v", err)
		return err
	}

	if err = c.Auth(LoginAuth(mailUser, mailPassword)); err != nil {
		err = fmt.Errorf("mail: c.Auth error. %v", err)
		return err
	}

	if err = c.Mail(fromEmail); err != nil {
		err = fmt.Errorf("mail: c.Mail error. %v", err)
		return err
	}
	if err = c.Rcpt(recepients); err != nil {
		err = fmt.Errorf("mail: c.Rcpt error. %v", err)
		return err

	}

	w, err := c.Data()
	if err != nil {
		err = fmt.Errorf("mail: c.Data error. %v", err)
		return err
	}

	_, err = w.Write([]byte(message))
	if err != nil {
		err = fmt.Errorf("mail: w.Write error. %v", err)
		return err
	}

	err = w.Close()
	if err != nil {
		err = fmt.Errorf("mail: w.Close error. %v", err)
		return err
	}
	c.Quit()
	return nil

}