You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

124 lines
2.8 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. // Copyright 2014 The Gogs Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package mailer
  5. import (
  6. "fmt"
  7. "net/smtp"
  8. "strings"
  9. "github.com/gogits/gogs/modules/log"
  10. "github.com/gogits/gogs/modules/setting"
  11. )
  12. type Message struct {
  13. To []string
  14. From string
  15. Subject string
  16. Body string
  17. User string
  18. Type string
  19. Massive bool
  20. Info string
  21. }
  22. // create mail content
  23. func (m Message) Content() string {
  24. // set mail type
  25. contentType := "text/plain; charset=UTF-8"
  26. if m.Type == "html" {
  27. contentType = "text/html; charset=UTF-8"
  28. }
  29. // create mail content
  30. content := "From: " + m.From + "<" + m.User +
  31. ">\r\nSubject: " + m.Subject + "\r\nContent-Type: " + contentType + "\r\n\r\n" + m.Body
  32. return content
  33. }
  34. var mailQueue chan *Message
  35. func NewMailerContext() {
  36. mailQueue = make(chan *Message, setting.Cfg.MustInt("mailer", "SEND_BUFFER_LEN", 10))
  37. go processMailQueue()
  38. }
  39. func processMailQueue() {
  40. for {
  41. select {
  42. case msg := <-mailQueue:
  43. num, err := Send(msg)
  44. tos := strings.Join(msg.To, "; ")
  45. info := ""
  46. if err != nil {
  47. if len(msg.Info) > 0 {
  48. info = ", info: " + msg.Info
  49. }
  50. log.Error(fmt.Sprintf("Async sent email %d succeed, not send emails: %s%s err: %s", num, tos, info, err))
  51. } else {
  52. log.Trace(fmt.Sprintf("Async sent email %d succeed, sent emails: %s%s", num, tos, info))
  53. }
  54. }
  55. }
  56. }
  57. // Direct Send mail message
  58. func Send(msg *Message) (int, error) {
  59. log.Trace("Sending mails to: %s", strings.Join(msg.To, "; "))
  60. host := strings.Split(setting.MailService.Host, ":")
  61. // get message body
  62. content := msg.Content()
  63. if len(msg.To) == 0 {
  64. return 0, fmt.Errorf("empty receive emails")
  65. } else if len(msg.Body) == 0 {
  66. return 0, fmt.Errorf("empty email body")
  67. }
  68. auth := smtp.PlainAuth("", setting.MailService.User, setting.MailService.Passwd, host[0])
  69. if msg.Massive {
  70. // send mail to multiple emails one by one
  71. num := 0
  72. for _, to := range msg.To {
  73. body := []byte("To: " + to + "\r\n" + content)
  74. err := smtp.SendMail(setting.MailService.Host, auth, msg.From, []string{to}, body)
  75. if err != nil {
  76. return num, err
  77. }
  78. num++
  79. }
  80. return num, nil
  81. } else {
  82. body := []byte("To: " + strings.Join(msg.To, ";") + "\r\n" + content)
  83. // send to multiple emails in one message
  84. err := smtp.SendMail(setting.MailService.Host, auth, msg.From, msg.To, body)
  85. if err != nil {
  86. return 0, err
  87. } else {
  88. return 1, nil
  89. }
  90. }
  91. }
  92. // Async Send mail message
  93. func SendAsync(msg *Message) {
  94. go func() {
  95. mailQueue <- msg
  96. }()
  97. }
  98. // Create html mail message
  99. func NewHtmlMessage(To []string, From, Subject, Body string) Message {
  100. return Message{
  101. To: To,
  102. From: From,
  103. Subject: Subject,
  104. Body: Body,
  105. Type: "html",
  106. }
  107. }