mailer.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  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/base"
  10. "github.com/gogits/gogs/modules/log"
  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.User + "<" + m.From +
  31. ">\r\nSubject: " + m.Subject + "\r\nContent-Type: " + contentType + "\r\n\r\n" + m.Body
  32. return content
  33. }
  34. // Direct Send mail message
  35. func Send(msg Message) (int, error) {
  36. log.Trace("Sending mails to: %s", strings.Join(msg.To, "; "))
  37. host := strings.Split(base.MailService.Host, ":")
  38. // get message body
  39. content := msg.Content()
  40. auth := smtp.PlainAuth("", base.MailService.User, base.MailService.Passwd, host[0])
  41. if len(msg.To) == 0 {
  42. return 0, fmt.Errorf("empty receive emails")
  43. }
  44. if len(msg.Body) == 0 {
  45. return 0, fmt.Errorf("empty email body")
  46. }
  47. if msg.Massive {
  48. // send mail to multiple emails one by one
  49. num := 0
  50. for _, to := range msg.To {
  51. body := []byte("To: " + to + "\r\n" + content)
  52. err := smtp.SendMail(base.MailService.Host, auth, msg.From, []string{to}, body)
  53. if err != nil {
  54. return num, err
  55. }
  56. num++
  57. }
  58. return num, nil
  59. } else {
  60. body := []byte("To: " + strings.Join(msg.To, ";") + "\r\n" + content)
  61. // send to multiple emails in one message
  62. err := smtp.SendMail(base.MailService.Host, auth, msg.From, msg.To, body)
  63. if err != nil {
  64. return 0, err
  65. } else {
  66. return 1, nil
  67. }
  68. }
  69. }
  70. // Async Send mail message
  71. func SendAsync(msg Message) {
  72. // TODO may be need pools limit concurrent nums
  73. go func() {
  74. num, err := Send(msg)
  75. tos := strings.Join(msg.To, "; ")
  76. info := ""
  77. if err != nil {
  78. if len(msg.Info) > 0 {
  79. info = ", info: " + msg.Info
  80. }
  81. // log failed
  82. log.Error(fmt.Sprintf("Async sent email %d succeed, not send emails: %s%s err: %s", num, tos, info, err))
  83. return
  84. }
  85. log.Trace(fmt.Sprintf("Async sent email %d succeed, sent emails: %s%s", num, tos, info))
  86. }()
  87. }
  88. // Create html mail message
  89. func NewHtmlMessage(To []string, From, Subject, Body string) Message {
  90. return Message{
  91. To: To,
  92. From: From,
  93. Subject: Subject,
  94. Body: Body,
  95. Type: "html",
  96. }
  97. }