golang 使用ssl连接smtp发送邮件

发送邮件的流程是,先有一个邮件发送器,然后才能发邮件。对于发送器,可以用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 := "lvxx@xxx.com"  // 目标地址

/* host :="smtp.qq.com:465"
   email  := "2930026384@qq.com"
   pwd := "yxxx"  // 这里填你的授权码
   toEmail := "1161115315@qq.com"  // 目标地址*/

   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 := "lvxx@XXXX.com,11611as315@qq.com" 
m.SetAddressHeader("From", "123ada@qq.com", "发件人") // 发件人
 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, "2930026384@qq.com", "gvjvblygnadudeac") //d := gomail.NewPlainDialer("mail.xxxx.com", 465, "admin@xxx.com", "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
}

 

 

 

 

 

 

Golang提供了smtp包,可以用于构建SMTP邮件解析服务。SMTP(简单邮件传输协议)是用于电子邮件传输的标准协议。使用SMTP包,我们可以编写一个程序,用于接收和解析传入的电子邮件。 首先,我们需要导入smtp包,并创建一个监听SMTP服务器的实例。使用Listen函数,我们可以指定监听的端口和地址。然后,我们可以调用Accept方法,等待客户端连接。 一旦接收到连接,我们可以使用来自smtp包的Parse方法解析传入的邮件。Parse方法接收一个io.Reader类型的参数,我们可以使用它来从连接中读取邮件内容。解析后的邮件将被返回为Mail类型的结构体,其中包含发件人、收件人、主题和正文等信息。 我们可以根据需要对解析出的邮件进行处理。例如,可以提取发件人、收件人和主题等信息,以进行进一步的逻辑操作。我们还可以从Mail类型的结构体中获取正文和附件等内容。 在处理完邮件后,我们可以通过调用Close方法来关闭与客户端的连接。 在实际使用中,我们可以将这个SMTP邮件解析服务与其他功能结合起来,例如自动回复、自动转发或将邮件保存到数据库中等。通过利用Golang的并发特性,我们可以实现同时处理多个邮件的能力,从而提高邮件处理的效率。 总之,利用Golangsmtp包,我们可以快速搭建一个SMTP邮件解析服务。无论是构建自己的邮件系统,还是对接第三方服务,该解析服务都可以帮助我们方便地处理和管理传入的电子邮件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值