go-common/app/job/main/videoup-report/dao/email/email.go
2019-04-22 18:49:16 +08:00

140 lines
3.5 KiB
Go

package email
import (
"context"
"encoding/json"
"fmt"
"strings"
"time"
"go-common/app/job/main/videoup-report/model/email"
"go-common/library/log"
"go-common/library/queue/databus/report"
gomail "gopkg.in/gomail.v2"
)
//SendMail send the email
func (d *Dao) SendMail(tpl *email.Template) {
var err error
headers := tpl.Headers
if len(headers[email.FROM]) == 0 || len(headers[email.TO]) == 0 || len(headers[email.SUBJECT]) == 0 {
log.Error("email lack From/To/Subject: emailTemplate(%+v)", *tpl)
return
}
if len(tpl.ContentType) == 0 {
tpl.ContentType = "text/plain"
}
log.Info("start send mail: emailTemplate(%+v)", *tpl)
msg := gomail.NewMessage()
msg.SetHeaders(headers)
msg.SetBody(tpl.ContentType, tpl.Body)
result := email.EmailResOK
if err = d.email.DialAndSend(msg); err != nil {
result = email.EmailResFail
log.Error("s.email.DialAndSend error(%v) emailTemplate(%+v)", err, tpl)
}
d.sendEmailLog(tpl, headers[email.TO], headers[email.CC], result)
//retry
if err != nil {
address := headers[email.TO]
if len(headers[email.CC]) > 0 {
address = append(address, headers[email.CC]...)
msg.SetHeader(email.CC)
}
for _, addr := range address {
msg.SetHeader(email.TO, addr)
result = email.EmailResOK
if err = d.email.DialAndSend(msg); err != nil {
result = email.EmailResFail
log.Error("s.email.DialAndSend error(%v) to(%s) emailTemplate(%+v)", err, addr, tpl)
}
d.sendEmailLog(tpl, []string{addr}, []string{}, result)
time.Sleep(time.Second * 5)
}
}
}
func (d *Dao) sendEmailLog(tpl *email.Template, to []string, cc []string, result string) {
if tpl == nil || len(tpl.Headers) <= 0 || len(tpl.Headers[email.SUBJECT]) <= 0 {
log.Error("sendEmailLog tpl nil | no headers, tpl(%+v)", tpl)
return
}
address := fmt.Sprintf("to: %s", strings.Join(to, ","))
if len(cc) > 0 {
address = fmt.Sprintf("%s\ncc: %s", address, strings.Join(cc, ","))
}
item := &report.ManagerInfo{
Uname: tpl.Username,
UID: tpl.UID,
Business: email.LogBusEmail,
Type: email.LogTypeEmailJob,
Oid: tpl.AID,
Action: tpl.Type,
Ctime: time.Now(),
Content: map[string]interface{}{
"subject": tpl.Headers[email.SUBJECT][0],
"body": tpl.Body,
"address": address,
"department": tpl.Department,
"result": result,
},
}
report.Manager(item)
log.Info("sendEmailLog template(%+v) result(%s) log.content(%+v)", tpl, result, item.Content)
}
//PushToRedis start to push email to redis according to speed
func (d *Dao) PushToRedis(c context.Context, tpl *email.Template) (isFast bool, key string, err error) {
if tpl == nil {
return
}
//探查发邮件速度快慢
isFast = d.detector.Detect(tpl.UID)
//超限名单只能被回落或下一次超限名单替代
if d.detector.IsFastUnique(tpl.UID) {
key = email.MailFastKey
d.fastChan <- 1
} else {
key = email.MailKey
}
if err = d.PushRedis(c, tpl, key); err != nil {
log.Error("PushToRedis d.PushRedis error(%v) key(%s), tpl(%+v) ", err, key, tpl)
}
return
}
//Start get email from redis and send
func (d *Dao) Start(key string) (err error) {
var (
bs []byte
tpl = &email.Template{}
)
bs, err = d.PopRedis(context.TODO(), key)
if err != nil || bs == nil {
time.Sleep(5 * time.Second)
return
}
err = json.Unmarshal(bs, tpl)
if err != nil {
log.Error("email Start json.unmarshal error(%v) template(%s)", err, string(bs))
return
}
//控制邮件发送频率
st := <-d.controlChan
d.SendMail(tpl)
time.Sleep(time.Second * 5)
d.controlChan <- st
return
}