(subject string, receiver string, content string)
| 20 | } |
| 21 | |
| 22 | func SendEmail(subject string, receiver string, content string) error { |
| 23 | if SMTPFrom == "" { // for compatibility |
| 24 | SMTPFrom = SMTPAccount |
| 25 | } |
| 26 | id, err2 := generateMessageID() |
| 27 | if err2 != nil { |
| 28 | return err2 |
| 29 | } |
| 30 | if SMTPServer == "" && SMTPAccount == "" { |
| 31 | return fmt.Errorf("SMTP 服务器未配置") |
| 32 | } |
| 33 | encodedSubject := fmt.Sprintf("=?UTF-8?B?%s?=", base64.StdEncoding.EncodeToString([]byte(subject))) |
| 34 | mail := []byte(fmt.Sprintf("To: %s\r\n"+ |
| 35 | "From: %s<%s>\r\n"+ |
| 36 | "Subject: %s\r\n"+ |
| 37 | "Date: %s\r\n"+ |
| 38 | "Message-ID: %s\r\n"+ // 添加 Message-ID 头 |
| 39 | "Content-Type: text/html; charset=UTF-8\r\n\r\n%s\r\n", |
| 40 | receiver, SystemName, SMTPFrom, encodedSubject, time.Now().Format(time.RFC1123Z), id, content)) |
| 41 | auth := smtp.PlainAuth("", SMTPAccount, SMTPToken, SMTPServer) |
| 42 | addr := fmt.Sprintf("%s:%d", SMTPServer, SMTPPort) |
| 43 | to := strings.Split(receiver, ";") |
| 44 | var err error |
| 45 | if SMTPPort == 465 || SMTPSSLEnabled { |
| 46 | tlsConfig := &tls.Config{ |
| 47 | InsecureSkipVerify: true, |
| 48 | ServerName: SMTPServer, |
| 49 | } |
| 50 | conn, err := tls.Dial("tcp", fmt.Sprintf("%s:%d", SMTPServer, SMTPPort), tlsConfig) |
| 51 | if err != nil { |
| 52 | return err |
| 53 | } |
| 54 | client, err := smtp.NewClient(conn, SMTPServer) |
| 55 | if err != nil { |
| 56 | return err |
| 57 | } |
| 58 | defer client.Close() |
| 59 | if err = client.Auth(auth); err != nil { |
| 60 | return err |
| 61 | } |
| 62 | if err = client.Mail(SMTPFrom); err != nil { |
| 63 | return err |
| 64 | } |
| 65 | receiverEmails := strings.Split(receiver, ";") |
| 66 | for _, receiver := range receiverEmails { |
| 67 | if err = client.Rcpt(receiver); err != nil { |
| 68 | return err |
| 69 | } |
| 70 | } |
| 71 | w, err := client.Data() |
| 72 | if err != nil { |
| 73 | return err |
| 74 | } |
| 75 | _, err = w.Write(mail) |
| 76 | if err != nil { |
| 77 | return err |
| 78 | } |
| 79 | err = w.Close() |
no test coverage detected