mail_sender.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. package main
  2. import (
  3. "fmt"
  4. "net/smtp"
  5. "strings"
  6. "time"
  7. )
  8. type MailRequest struct {
  9. sendto []string
  10. title string
  11. content string
  12. }
  13. type MailSender struct {
  14. queue chan *MailRequest
  15. }
  16. const (
  17. LOOP_DELAY = 3
  18. LOOP_QUEUE_SIZE = 10
  19. PUSH_TIMEOUT = 3
  20. )
  21. func NewMailSender() *MailSender {
  22. return &MailSender{
  23. queue: make(chan *MailRequest, 100),
  24. }
  25. }
  26. func (s *MailSender) Loop() {
  27. timer := time.NewTimer(time.Second * LOOP_DELAY)
  28. timeouted := false
  29. for {
  30. list := make([]*MailRequest, 0)
  31. //一次取10条记录
  32. for i := 0; i < LOOP_QUEUE_SIZE; i++ {
  33. timer.Reset(time.Second * LOOP_DELAY)
  34. select {
  35. case req, ok := <-s.queue:
  36. timeouted = false
  37. timer.Stop()
  38. if ok {
  39. list = append(list, req)
  40. }
  41. case <-timer.C:
  42. timeouted = true
  43. }
  44. //如果不足10条也返回
  45. if timeouted {
  46. break
  47. }
  48. }
  49. //发送邮件
  50. if len(list) > 0 {
  51. s.Send(list)
  52. }
  53. }
  54. }
  55. func (s *MailSender) Send(list []*MailRequest) {
  56. if len(list) == 0 {
  57. return
  58. }
  59. //取SMTP配置
  60. cfg := SysCfg.GetMulti([]string{"smtp_host", "smtp_port", "smtp_user", "smtp_pwd", "smtp_sender"})
  61. auth := smtp.PlainAuth("", cfg["smtp_user"], cfg["smtp_pwd"], cfg["smtp_host"])
  62. address := fmt.Sprintf("%s:%s", cfg["smtp_host"], cfg["smtp_port"])
  63. //循环发送
  64. for _, req := range list {
  65. data := "From: " + cfg["smtp_user"] + "\r\nSender: " + cfg["smtp_sender"] + "\r\nTo: " + strings.Join(req.sendto, ";") + "\r\nContent-Type: text/html;charset=utf-8\r\nSubject: " + req.title + "\r\n\r\n" + req.content
  66. err := smtp.SendMail(address, auth, cfg["smtp_user"], req.sendto, []byte(data))
  67. if err != nil {
  68. SYSLOG("ERROR", fmt.Sprintf("邮件发送失败:%s,邮件内容如下:%s", err.Error(), data))
  69. }
  70. }
  71. }
  72. func (s *MailSender) Push(req *MailRequest) {
  73. timer := time.NewTimer(time.Second * PUSH_TIMEOUT)
  74. select {
  75. case s.queue <- req:
  76. timer.Stop()
  77. case <-timer.C:
  78. }
  79. }