Files
ppgo_job/notify/email.go
wen.gong 06b31819d2 Add mail to send SSL encrypted go to port 465
Send mail encrypted with port 25 or port 465 ssl, depending on the configuration file app.conf
2018-11-26 15:02:18 +08:00

191 lines
3.6 KiB
Go

/************************************************************
** @Description: notify
** @Author: george hao
** @Date: 2018-08-08 12:59
** @Last Modified by: gwalker
** @Last Modified time: 2018-11-26 14:57
*************************************************************/
package notify
import (
"crypto/tls"
"fmt"
"github.com/astaxie/beego"
"net"
"net/smtp"
"strings"
"time"
)
type PEmailConfig struct {
Host string
Port string
User string
Pwd string
From string
}
type PEmail struct {
Config *PEmailConfig
Subject string
Body string
To string
Format string
}
var (
mailChan chan *PEmail
config *PEmailConfig
)
func init() {
poolSize, _ := beego.AppConfig.Int("email.pool")
host := beego.AppConfig.String("email.host")
port := beego.AppConfig.String("email.port")
user := beego.AppConfig.String("email.user")
pwd := beego.AppConfig.String("email.password")
from := beego.AppConfig.String("email.from")
config = &PEmailConfig{
Host: host,
From: from,
Port: port,
User: user,
Pwd: pwd,
}
//创建通道
mailChan = make(chan *PEmail, poolSize)
go func() {
for {
select {
case m, ok := <-mailChan:
if !ok {
return
}
if err := m.SendToEmail(); err != nil {
beego.Error("SendMail:", err.Error())
}
}
}
}()
}
func SendToChan(to, subject, body, mailtype string) bool {
email := &PEmail{
Config: config,
Body: body,
Subject: subject,
Format: mailtype,
To: to,
}
select {
case mailChan <- email:
return true
case <-time.After(time.Second * 3):
return false
}
}
func (pe *PEmail) SendToEmail() error {
auth := smtp.PlainAuth("", pe.Config.User, pe.Config.Pwd, pe.Config.Host)
contentType := GetContentTypeString(pe.Format)
msg := []byte("To: " + pe.To + "\r\nFrom: " + pe.Config.User +
"\r\nSubject: " + pe.Subject + "\r\n" + contentType + "\r\n\r\n" + pe.Body)
sendTo := strings.Split(pe.To, ";")
var err error
if pe.Config.Port == "25" {
err = SendMailUsing25(pe.Config.Host,pe.Config.Port,auth,pe.Config.User,sendTo,msg)
} else if pe.Config.Port == "465" {
err = SendMailUsing465(pe.Config.Host,pe.Config.Port,auth,pe.Config.User,sendTo,msg)
} else{
err = fmt.Errorf("%s","other ports are not supported,please check the app.conf configuration file")
}
return err
}
func GetContentTypeString ( format string ) string {
var contentType string
if format == "" {
contentType = "Content-Type: text/plain" + "; charset=UTF-8"
} else {
contentType = "Content-Type: text/" + format + "; charset=UTF-8"
}
return contentType
}
func SendMailUsing25(addr string, port string, auth smtp.Auth, from string, to []string, msg []byte) (err error) {
err = smtp.SendMail(addr+":"+port, auth, from, to, msg)
return err
}
func SendMailUsing465(addr string,port string, auth smtp.Auth, from string, to []string, msg []byte) (err error) {
c, err := Dial(addr+":"+port)
if err != nil {
return err
}
defer c.Close()
if auth != nil {
if ok, _ := c.Extension("AUTH"); ok {
if err = c.Auth(auth); err != nil {
return err
}
}
}
if err = c.Mail(from); err != nil {
return err
}
for _, addr := range to {
if err = c.Rcpt(addr); err != nil {
fmt.Print(err)
return err
}
}
w, err := c.Data()
if err != nil {
return err
}
_, err = w.Write(msg)
if err != nil {
return err
}
err = w.Close()
if err != nil {
return err
}
return c.Quit()
}
func Dial(addr string) (*smtp.Client, error) {
conn, err := tls.Dial("tcp", addr, nil)
if err != nil {
return nil, err
}
//分解主机端口字符串
host, _, _ := net.SplitHostPort(addr)
return smtp.NewClient(conn, host)
}