package mail import ( "crypto/tls" "log" "strings" "sync" "time" "app.yhyue.com/moapp/jybase/common" "app.yhyue.com/moapp/jybase/gomail" ) type GmailAuth struct { SmtpHost string //邮箱服务器 SmtpPort int //邮箱端口 User string //用户 Pwd string //密码 PoolChan chan *gomail.Dialer PoolSize int ReTry int } var locker = &sync.Mutex{} func getDialer(flag bool, auth *GmailAuth, to string) *gomail.Dialer { if auth.PoolChan == nil { locker.Lock() defer locker.Unlock() if auth.PoolChan == nil { if auth.PoolSize == 0 { auth.PoolSize = 1 } auth.PoolChan = make(chan *gomail.Dialer, auth.PoolSize) for i := 0; i < auth.PoolSize; i++ { dialer := gomail.NewPlainDialer(auth.SmtpHost, auth.SmtpPort, auth.User, auth.Pwd) // 发送邮件服务器、端口、发件人账号、发件人密码 dialer.TLSConfig = &tls.Config{ServerName: auth.SmtpHost, InsecureSkipVerify: true} auth.PoolChan <- dialer } } } if flag { log.Println(auth.User, to, "发送邮件getDialer:get new gomail Dialer") dialer := gomail.NewPlainDialer(auth.SmtpHost, auth.SmtpPort, auth.User, auth.Pwd) // 发送邮件服务器、端口、发件人账号、发件人密码 dialer.TLSConfig = &tls.Config{ServerName: auth.SmtpHost, InsecureSkipVerify: true} auth.PoolChan <- dialer } return <-auth.PoolChan } // 发送普通 func GSendMail(from, to, cc, bcc, subject, body, fname, rename string, auth *GmailAuth) bool { m := gomail.NewMessage() m.SetAddressHeader("From", auth.User, from) // 发件人 m.SetHeader("To", strings.Split(to, ",")...) // 收件人 if cc != "" { m.SetHeader("Cc", m.FormatAddress(cc, "收件人")) //抄送 } if bcc != "" { m.SetHeader("Bcc", m.FormatAddress(bcc, "收件人")) // 暗送 } m.SetHeader("Subject", subject) // 主题 m.SetBody("text/html", body) // 正文 if fname != "" { h := map[string][]string{"Content-Type": {"text/plain; charset=UTF-8"}} m.Attach(fname, gomail.Rename(rename), gomail.SetHeader(h)) //添加附件 //m.Attach(fname) //添加附件 } reTry := auth.ReTry if reTry == 0 { reTry = 3 } return gSend(reTry, auth, m, to) } // 电销 多人 func GSendMail_dx(from, to, cc, bcc, subject, body, fname, rename string, auth *GmailAuth) bool { m := gomail.NewMessage() m.SetAddressHeader("From", auth.User, from) // 发件人 m.SetHeader("To", strings.Split(to, ",")...) // 收件人 if cc != "" { m.SetHeader("Cc", strings.Split(cc, ",")...) //抄送 } if bcc != "" { m.SetHeader("Bcc", m.FormatAddress(bcc, "收件人")) // 暗送 } m.SetHeader("Subject", subject) // 主题 m.SetBody("text/html", body) // 正文 if fname != "" { h := map[string][]string{"Content-Type": {"text/plain; charset=UTF-8"}} m.Attach(fname, gomail.Rename(rename), gomail.SetHeader(h)) //添加附件 //m.Attach(fname) //添加附件 } reTry := auth.ReTry if reTry == 0 { reTry = 3 } return gSend(reTry, auth, m, to) } // 如果附件是byte,用这个 func GSendMail_B(from, to, cc, bcc, subject, body, fname string, fb []byte, auth *GmailAuth) bool { m := gomail.NewMessage() m.SetAddressHeader("From", auth.User, from) // 发件人 m.SetHeader("To", m.FormatAddress(to, "收件人")) // 收件人 if cc != "" { m.SetHeader("Cc", m.FormatAddress(cc, "收件人")) //抄送 } if bcc != "" { m.SetHeader("Bcc", m.FormatAddress(bcc, "收件人")) // 暗送 } m.SetHeader("Subject", subject) // 主题 m.SetBody("text/html", body) // 正文 if fname != "" { h := map[string][]string{"Content-Type": {"text/plain; charset=UTF-8"}} m.Attach_new(fb, gomail.Rename(fname), gomail.SetHeader(h)) //添加附件 //m.Attach(fname) //添加附件 } reTry := auth.ReTry if reTry == 0 { reTry = 1 } return gSend(reTry, auth, m, to) } // 如果附件是byte,用这个,这个是为企业级服务修改的 // 20191206 @ren to用|分隔的是抄送用,分隔的是并列 func GSendMail_Bq(from, to, cc, bcc, subject, body, fname string, fb []byte, auth *GmailAuth) bool { m := gomail.NewMessage() m.SetAddressHeader("From", auth.User, from) // 发件人 tos := strings.Split(to, "|") if len(tos) > 0 { tos1 := strings.Split(tos[0], ",") m.SetHeader("To", tos1...) // 收件人 } if len(tos) > 1 { tos2 := strings.Split(tos[1], ",") if cc != "" { tos2 = append(tos2, cc) } m.SetHeader("Cc", tos2...) // 收件人 } else { if cc != "" { m.SetHeader("Cc", m.FormatAddress(cc, "收件人")) //抄送 } } if len(tos) > 2 { tos3 := strings.Split(tos[2], ",") if bcc != "" { tos3 = append(tos3, cc) } m.SetHeader("Bcc", tos3...) // 收件人 } else { if bcc != "" { m.SetHeader("Bcc", m.FormatAddress(bcc, "收件人")) // 暗送 } } m.SetHeader("Subject", subject) // 主题 m.SetBody("text/html", body) // 正文 if fname != "" { h := map[string][]string{"Content-Type": {"text/plain; charset=UTF-8"}} m.Attach_new(fb, gomail.Rename(fname), gomail.SetHeader(h)) //添加附件 //m.Attach(fname) //添加附件 } reTry := auth.ReTry if reTry == 0 { reTry = 1 } return gSend(reTry, auth, m, to) } // 发送普通这个是为企业级服务修改的 // 20191206 @ren to用|分隔的是抄送,分隔的是并列 func GSendMail_q(from, to, cc, bcc, subject, body, fname, rename string, auth *GmailAuth) bool { m := gomail.NewMessage() m.SetAddressHeader("From", auth.User, from) // 发件人 tos := strings.Split(to, "|") if len(tos) > 0 { tos1 := strings.Split(tos[0], ",") m.SetHeader("To", tos1...) // 收件人 } if len(tos) > 1 { tos2 := strings.Split(tos[1], ",") if cc != "" { tos2 = append(tos2, cc) } m.SetHeader("Cc", tos2...) // 收件人 } else { if cc != "" { m.SetHeader("Cc", m.FormatAddress(cc, "收件人")) //抄送 } } if len(tos) > 2 { tos3 := strings.Split(tos[2], ",") if bcc != "" { tos3 = append(tos3, cc) } m.SetHeader("Bcc", tos3...) // 收件人 } else { if bcc != "" { m.SetHeader("Bcc", m.FormatAddress(bcc, "收件人")) // 暗送 } } m.SetHeader("Subject", subject) // 主题 m.SetBody("text/html", body) // 正文 if fname != "" { h := map[string][]string{"Content-Type": {"text/plain; charset=UTF-8"}} m.Attach(fname, gomail.Rename(rename), gomail.SetHeader(h)) //添加附件 //m.Attach(fname) //添加附件 } reTry := auth.ReTry if reTry == 0 { reTry = 3 } return gSend(reTry, auth, m, to) } func gSend(retry int, auth *GmailAuth, m *gomail.Message, to string) bool { defer common.Catch() dialer := getDialer(false, auth, to) defer func() { auth.PoolChan <- dialer }() status := false for i := 0; i < retry; i++ { if err := dialer.DialAndSend(m); err != nil { dialer = getDialer(true, auth, to) if retry > 0 { log.Println(auth.User, to, "第", i+1, "次发送邮件gSend error:", err) time.Sleep(200 * time.Millisecond) } } else { status = true break } } return status } // 先取模后轮询获取一个mail实例 func PollingMail(email string, array []*GmailAuth, f func(g *GmailAuth) bool) bool { if len(array) == 0 { return false } index := len(email) % len(array) if f(array[index]) { return true } for i := 0; i < len(array); i++ { if i == index { continue } else if f(array[i]) { return true } } return false }