发送邮件的流程是,先有一个邮件发送器,然后才能发邮件。对于发送器,可以用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.xx.com:465"
email := "admin@xxx"
pwd := "xxxx" // 这里填你的授权码
toEmail := "[email protected]" // 目标地址
/* host :="smtp.qq.com:465"
email := "[email protected]"
pwd := "yxxx" // 这里填你的授权码
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 test") // 正文 d := gomail.NewPlainDialer("smtp.qq.com", 465, "[email protected]", "gvjvblygnadudeac") //d := gomail.NewPlainDialer("mail.xxxx.com", 465, "[email protected]", "xxx") // 发送邮件服务器、端口、发件人账号、发件人密码
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
}