发送邮件的流程是,先有一个邮件发送器,然后才能发邮件。对于发送器,可以用qq来申请成可以发邮件测试代码
https://jingyan.baidu.com/article/4b07be3cb2f74148b380f3e4.html
邮件SMTP的几个端口:
25:smtp是服务器用来接收和发送邮件的,客户端来发送邮件的。(这个端口是不能更改的)
110:是pop客户端用来接收邮件的
143:imap客户端用来接收邮件的
993:imap的加密端口
465:smtp的加密端口用来发送邮件的
587:另外的smtp端口也是用来发送邮件的
995:pop的加密端口客户端用来接收邮件的
2525:这个不是一个SMTP端口,有时候会用来代替587端口
另外网页收发邮件,一般是http 80端口,可以改成其他的
邮件发送方式有:ssl加密方式 tsl加密方式
参考网址:https://my.oschina.net/u/3768573/blog/1607327
这里面ssl的例子用我公司企业号之后,死活不成功。原来ssl方式加密默认是需要证书的,如果没有证书则需要调过证书认证。就因为一个参数,废了一天真是醉了。
package main import ( "fmt" "net/smtp" "crypto/tls" "net" ) func main() { host := "mail.radacat.com:465" email := "[email protected]" pwd := "RadacatMail2017" // 这里填你的授权码 toEmail := "[email protected],[email protected]" // 目标地址 /* host :="smtp.qq.com:465" email := "[email protected]" pwd := "ywcploawrphjdcif" // 这里填你的授权码 toEmail := "[email protected]" // 目标地址*/ header := make(map[string]string) header["From"] = "test"+"<" +email+">" header["To"] = toEmail header["Subject"] = "邮件标题11111" header["Content-Type"] = "text/html;chartset=UTF-8" message := "" body := "这是一封golang发来的邮件" for k,v :=range header{ message += fmt.Sprintf("%s:%s\r\n",k,v) } message +="\r\n"+body auth := smtp.PlainAuth("", email, pwd, host) fmt.Println("AUTH:",auth) /*err := smtp.SendMail(host,auth,email,[]string{toEmail},[]byte(message)) if err != nil{ fmt.Println("发送失败:",err) return }*/ err := SendMailUsingTLS( host, auth, email, []string{toEmail}, []byte(message), ) if err != nil{ fmt.Println("发送失败:",err) return } return } //return a smtp client func Dial(addr string) (*smtp.Client, error) { //todo 没有就跳过证书,需要参数 &tls.Config{InsecureSkipVerify:true} conn, err := tls.Dial("tcp",addr, nil)
// conn, err := tls.Dial("tcp", addr, &tls.Config{InsecureSkipVerify:true})
if err != nil {
fmt.Println("Dialing Error:", err)
return nil, err } //分解主机端口字符串 host, _, _ := net.SplitHostPort(addr) return smtp.NewClient(conn, host) } //参考net/smtp的func SendMail() //使用net.Dial连接tls(ssl)端口时,smtp.NewClient()会卡住且不提示err //len(to)>1时,to[1]开始提示是密送 func SendMailUsingTLS(addr string, auth smtp.Auth, from string, to []string, msg []byte) (err error) { fmt.Println("start SendMailUsingTLS... ") //create smtp client c, err := Dial(addr) fmt.Println("c:",c) if err != nil { fmt.Println("Create smpt client error:", err) return err } defer c.Close() if auth != nil { if ok, param := c.Extension("AUTH"); ok { fmt.Println("ok:", ok) fmt.Println("param:", param) if err = c.Auth(auth); err != nil { fmt.Println("Error during AUTH:", err) return err } } } if err = c.Mail(from); err != nil { fmt.Println(err) return err } for _, addr := range to { if err = c.Rcpt(addr); err != nil { fmt.Println(err) return err } } w, err := c.Data() if err != nil { fmt.Println(err) return err } _, err = w.Write(msg) if err != nil { fmt.Println(err) return err } err = w.Close() if err != nil { fmt.Println(err) return err } return c.Quit() }
刚开始我使用qq号开通来发送邮件,很顺利。网上随便一搜都是。如下:
func main(){
m := gomail.NewMessage()str := "[email protected],[email protected]" m.SetAddressHeader( "From" , "[email protected]" , "发件人") // 发件人 m.SetHeader( "To" , // 收件人 strings.Split(str , ",")...) m.SetHeader( "Subject" , "Gomail") // 主题 m.SetBody( "text/html" , "Hello <a href = \"http://blog.csdn.net/liang19890820\">test</a>") // 正文 d := gomail.NewPlainDialer( "smtp.qq.com" , 465 , "[email protected]" , "gvjvblygnadudeac") //d := gomail.NewPlainDialer("mail.radacat.com", 465, "[email protected]", "RadacatMail2017") // 发送邮件服务器、端口、发件人账号、发件人密码 if err := d.DialAndSend(m) ; err != nil { panic(err) }}
后来需要使用模板来发送,这个时候又找到了模板的参考案例:
package main import ( "encoding/json" "fmt" "github.com/alecthomas/template" "os" ) func main() { Alarm := `{"aid":122,"count":1}` alarm := make(map[string]interface{}, 0) err := json.Unmarshal([]byte(Alarm), &alarm) if err != nil { fmt.Println(err) } muban1 := `hi, {{template "aid"}}` tmpl, err := template.New("ONE").Parse(muban1) if err != nil { panic(err) } for k, v := range alarm { str, _ := json.Marshal(v) tmpl.New(k).Parse(string(str)) } err = tmpl.Execute(os.Stdout, nil) if err != nil { panic(err) } return }
通过两者结合,出来一个发邮件的函数
package common import ( "encoding/json" "net/smtp" "fmt" "bytes" "strings" "github.com/alecthomas/template" log "github.com/cihub/seelog" "strconv" ) //通过发送器发送邮件 func SendEmailBySender(serverAddr, username ,password string,receiveAddr ,tem ,subject string,a []byte)(err error ) { bods := new(bytes.Buffer) var emails = make([]string ,0) con := strings.Split(serverAddr,":") auth := smtp.PlainAuth("",username,password,con[0]) email := strings.Split(receiveAddr,",") for _,v := range email{ emails = append(emails,v) } alarm := make(map[string]interface{}, 0) err = json.Unmarshal(a,&alarm) if err != nil { fmt.Println(err) } tmpl, err := template.New("template").Parse(tem) if err != nil { fmt.Println("tmpl err : ",tmpl) return } fmt.Println("发邮件之前接收的告警信息 :",alarm) for k,v := range alarm{ str ,err := json.Marshal(v) if err != nil { log.Infof("json.Marshal err (%s)",err) } a,err := strconv.Unquote( string(str)) if err != nil { tmpl.New(k).Parse(string(str)) } tmpl.New(k).Parse(a) } err = tmpl.Execute(bods, nil) if err != nil { panic(err) } content_type := "Content-Type:text/html;charset=utf-8" msg := []byte("To:" + receiveAddr + "\r\nFrom:"+ username + "\r\nSubject:"+ subject + "\r\n" + content_type + "\r\n\r\n"+ bods.String()) err = smtp.SendMail(serverAddr, auth, username, emails, msg) if err != nil{ log.Errorf("发送邮件错误!err (%s)",err) return err }else{ log.Infof("邮件发送成功") return } return }