海运的博客

golang通过qq mail smtp ssl发送邮件

发布时间:April 15, 2018 // 分类: // No Comments

转自:https://www.oschina.net/code/snippet_166520_34694

package main
 
import (
    "crypto/tls"
    "fmt"
    "log"
    "net"
    "net/smtp"
)
 
func main() {
    host := "smtp.qq.com"
    port := 465
    email := "xxx@qq.com"
    password := "xxx"
    toEmail := "xxx@qq.com"
 
    header := make(map[string]string)
    header["From"] = "test" + "<" + email + ">"
    header["To"] = toEmail
    header["Subject"] = "邮件标题"
    header["Content-Type"] = "text/html; charset=UTF-8"
 
    body := "我是一封电子邮件!golang发出."
 
    message := ""
    for k, v := range header {
        message += fmt.Sprintf("%s: %s\r\n", k, v)
    }
    message += "\r\n" + body
 
    auth := smtp.PlainAuth(
        "",
        email,
        password,
        host,
    )
 
    err := SendMailUsingTLS(
        fmt.Sprintf("%s:%d", host, port),
        auth,
        email,
        []string{toEmail},
        []byte(message),
    )
 
    if err != nil {
        panic(err)
    }
}
 
//return a smtp client
func Dial(addr string) (*smtp.Client, error) {
    conn, err := tls.Dial("tcp", addr, nil)
    if err != nil {
        log.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) {
 
    //create smtp client
    c, err := Dial(addr)
    if err != nil {
        log.Println("Create smpt client error:", err)
        return err
    }
    defer c.Close()
 
    if auth != nil {
        if ok, _ := c.Extension("AUTH"); ok {
            if err = c.Auth(auth); err != nil {
                log.Println("Error during AUTH", err)
                return err
            }
        }
    }
 
    if err = c.Mail(from); err != nil {
        return err
    }
 
    for _, addr := range to {
        if err = c.Rcpt(addr); err != nil {
            return err
        }
    }
 
    w, err := c.Data()
    if err != nil {
        return err
    }
 
    _, err = w.Write(msg)
    if err != nil {
        return err
    }
 
    err = w.Close()
    if err != nil {
        return err
    }
 
    return c.Quit()
}

标签:none

评论已关闭

分类
最新文章
最近回复
  • liyk: 这个方法获取的IPv6大概20分钟之后就会失效,默认路由先消失,然后Global IPV6再消失
  • 海运: 不好意思,没有。
  • zongboa: 您好,請問一下有immortalwrt設定guest Wi-Fi的GUI教學嗎?感謝您。
  • 海运: 恩山有很多。
  • swsend: 大佬可以分享一下固件吗,谢谢。
  • Jimmy: 方法一 nghtp3步骤需要改成如下才能编译成功: git clone https://git...
  • 海运: 地址格式和udpxy一样,udpxy和msd_lite能用这个就能用。
  • 1: 怎么用 编译后的程序在家里路由器内任意一台设备上运行就可以吗?比如笔记本电脑 m参数是笔记本的...
  • 孤狼: ups_status_set: seems that UPS [BK650M2-CH] is ...
  • 孤狼: 擦。。。。apcupsd会失联 nut在冲到到100的时候会ONBATT进入关机状态,我想想办...