github.com/gogf/gf@v1.16.9/net/gsmtp/gsmtp.go (about) 1 // Copyright GoFrame Author(https://goframe.org). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/gogf/gf. 6 7 // Package gsmtp provides a simple SMTP client to access remote mail server. 8 // 9 // Eg: 10 // s := smtp.New("smtp.exmail.qq.com:25", "notify@a.com", "password") 11 // glog.Println(s.SendMail("notify@a.com", "ulric@b.com;rain@c.com", "subject", "body, <font color=red>red</font>")) 12 package gsmtp 13 14 import ( 15 "encoding/base64" 16 "fmt" 17 "net/smtp" 18 "strings" 19 ) 20 21 // SMTP is the structure for smtp connection 22 type SMTP struct { 23 Address string 24 Username string 25 Password string 26 } 27 28 // New creates and returns a new SMTP object. 29 func New(address, username, password string) *SMTP { 30 return &SMTP{ 31 Address: address, 32 Username: username, 33 Password: password, 34 } 35 } 36 37 var ( 38 // contentEncoding is the BASE64 encoding object for mail content. 39 contentEncoding = base64.NewEncoding("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/") 40 ) 41 42 // SendMail connects to the server at addr, switches to TLS if 43 // possible, authenticates with the optional mechanism a if possible, 44 // and then sends an email from address <from>, to addresses <to>, with 45 // message msg. 46 // 47 // The parameter <contentType> specifies the content type of the mail, eg: html. 48 func (s *SMTP) SendMail(from, tos, subject, body string, contentType ...string) error { 49 var ( 50 server = "" 51 address = "" 52 hp = strings.Split(s.Address, ":") 53 ) 54 if s.Address == "" || len(hp) > 2 { 55 return fmt.Errorf("server address is either empty or incorrect: %s", s.Address) 56 } else if len(hp) == 1 { 57 server = s.Address 58 address = server + ":25" 59 } else if len(hp) == 2 { 60 if (hp[0] == "") || (hp[1] == "") { 61 return fmt.Errorf("server address is either empty or incorrect: %s", s.Address) 62 } 63 server = hp[0] 64 address = s.Address 65 } 66 var ( 67 tosArr []string 68 arr = strings.Split(tos, ";") 69 ) 70 for _, to := range arr { 71 // TODO: replace with regex 72 if strings.Contains(to, "@") { 73 tosArr = append(tosArr, to) 74 } 75 } 76 if len(tosArr) == 0 { 77 return fmt.Errorf("tos if invalid: %s", tos) 78 } 79 80 if !strings.Contains(from, "@") { 81 return fmt.Errorf("from is invalid: %s", from) 82 } 83 84 header := map[string]string{ 85 "From": from, 86 "To": strings.Join(tosArr, ";"), 87 "Subject": fmt.Sprintf("=?UTF-8?B?%s?=", contentEncoding.EncodeToString([]byte(subject))), 88 "MIME-Version": "1.0", 89 "Content-Type": "text/plain; charset=UTF-8", 90 "Content-Transfer-Encoding": "base64", 91 } 92 if len(contentType) > 0 && contentType[0] == "html" { 93 header["Content-Type"] = "text/html; charset=UTF-8" 94 } 95 message := "" 96 for k, v := range header { 97 message += fmt.Sprintf("%s: %s\r\n", k, v) 98 } 99 message += "\r\n" + contentEncoding.EncodeToString([]byte(body)) 100 return smtp.SendMail( 101 address, 102 smtp.PlainAuth("", s.Username, s.Password, server), 103 from, 104 tosArr, 105 []byte(message), 106 ) 107 }