Go实战--通过net/smtp发送邮件(The way to go)

来源:互联网 发布:苹果电脑 mac地址 编辑:程序博客网 时间:2024/04/30 17:44

生命不止,继续 go go go !!!

这篇要跟大家分享的是,如果使用go发送邮件。

其实,很简单,在net/smtp中为我们提供了相关的功能,用就可以了,但是是遇到了很多坑儿,这里与大家分享。

何为smtp

SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。SMTP协议属于TCP/IP协议簇,它帮助每台计算机在发送或中转信件时找到下一个目的地。通过SMTP协议所指定的服务器,就可以把E-mail寄到收信人的服务器上了,整个过程只要几分钟。SMTP服务器则是遵循SMTP协议的发送邮件服务器,用来发送或中转发出的电子邮件。

例如,在Linux系统中我们就可以通过SMTP进行发送邮件,脚本如下:

mail -s "Test Subject" 874560965@qq.com < /dev/null

有可能遇到如下错误:
send-mail: fatal: parameter inet_interfaces: no local interface found for ::1
解决方案:

vim  /etc/postfix/main.cf

发现配置为:

inet_interfaces = localhostinet_protocols = all

改成:

inet_interfaces = allinet_protocols = all

重新启动

service postfix start

好,这里就不过多介绍Linux系统发送邮件了!

net/smtp

Package smtp implements the Simple Mail Transfer Protocol as defined in RFC 5321.

SendMail方法
“`go
func SendMail(addr string, a Auth, from string, to []string, msg []byte) error

相信你一定注意到第二个参数Auth了,这是一个结构体:Auth is implemented by an SMTP authentication mechanism

type Auth interface {
// Start begins an authentication with a server.
// It returns the name of the authentication protocol
// and optionally data to include in the initial AUTH message
// sent to the server. It can return proto == “” to indicate
// that the authentication should be skipped.
// If it returns a non-nil error, the SMTP client aborts
// the authentication attempt and closes the connection.
Start(server *ServerInfo) (proto string, toServer []byte, err error)

    // Next continues the authentication. The server has just sent    // the fromServer data. If more is true, the server expects a    // response, which Next should return as toServer; otherwise    // Next should return toServer == nil.    // If Next returns a non-nil error, the SMTP client aborts    // the authentication attempt and closes the connection.    Next(fromServer []byte, more bool) (toServer []byte, err error)

}

那么我们怎样获得这个auth呢,这时候需要介绍 PlainAuth了。** PlainAuth方法**```gofunc PlainAuth(identity, username, password, host string) Auth<div class="se-preview-section-delimiter"></div>

应用

不再过多的废话了,直接上代码再分析:

package mainimport (    "fmt"    "net/smtp"    "strings")func main() {    auth := smtp.PlainAuth("", "953637695@qq.com", "password", "smtp.qq.com")    to := []string{"874560965@qq.com"}    nickname := "test"    user := "953637695@qq.com"    subject := "test mail"    content_type := "Content-Type: text/plain; charset=UTF-8"    body := "This is the email body."    msg := []byte("To: " + strings.Join(to, ",") + "\r\nFrom: " + nickname +        "<" + user + ">\r\nSubject: " + subject + "\r\n" + content_type + "\r\n\r\n" + body)    err := smtp.SendMail("smtp.qq.com:25", auth, user, to, msg)    if err != nil {        fmt.Printf("send mail error: %v", err)    }}

上面的代码是使用953637695@qq.com向874560965@qq.com发送一封邮件,但是过了好长一段时间,你会收到这样的反馈:
send mail error: 535 Error
http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=28&&no=1001256
你开始怀疑你的代码有问题,又开始怀疑你的qq邮箱的密码有问题,但是最终都无功而返。这个时候需要对你的qq邮箱进行设置。

解决方案就是把password改为授权码!!!!!
什么是授权码?
授权码是QQ邮箱推出的,用于登录第三方客户端的专用密码。
适用于登录以下服务:POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务。

###**应用**不再过多的废话了,直接上代码再分析:```gopackage mainimport (    "fmt"    "net/smtp"    "strings")func main() {    auth := smtp.PlainAuth("", "953637695@qq.com", "password", "smtp.qq.com")    to := []string{"874560965@qq.com"}    nickname := "test"    user := "953637695@qq.com"    subject := "test mail"    content_type := "Content-Type: text/plain; charset=UTF-8"    body := "This is the email body."    msg := []byte("To: " + strings.Join(to, ",") + "\r\nFrom: " + nickname +        "<" + user + ">\r\nSubject: " + subject + "\r\n" + content_type + "\r\n\r\n" + body)    err := smtp.SendMail("smtp.qq.com:25", auth, user, to, msg)    if err != nil {        fmt.Printf("send mail error: %v", err)    }}

上面的代码是使用953637695@qq.com向874560965@qq.com发送一封邮件,但是过了好长一段时间,你会收到这样的反馈:
send mail error: 535 Error
http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=28&&no=1001256
你开始怀疑你的代码有问题,又开始怀疑你的qq邮箱的密码有问题,但是最终都无功而返。这个时候需要对你的qq邮箱进行设置。

解决方案就是把password改为授权码!!!!!
什么是授权码?
授权码是QQ邮箱推出的,用于登录第三方客户端的专用密码。
适用于登录以下服务:POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务。

qq邮箱设置

进入邮箱,点击设置
这里写图片描述

进入账户
这里写图片描述

点击开启
这里写图片描述

手机验证,获得授权码

1 0