go qq邮箱发送
简述
Go 提供一个smtp(简单邮件传输协议)库作为其网络包的一部分,“net/smpt"公开了一些可以立即使用的功能
Gomail - 一个比较成熟的第三包,提供一个快捷、简单的解决方案,可以轻松地发送电子邮件。Gomail包下载地址。下载完放在src/gopkg.in目录下
发送邮件主要思路
两种方法的使用
-
smtp包
- 发送信息(不包括附加文件)
func sendEMail() error { senderAddr := "1843121593@qq.com" receviceAddr := "1843121593@qq.com" authcode = "" //这个需要自己的授权码 auth := smtp.PlainAuth("", senderAddr, authCode, "smtp.qq.com") to := []string{receviceAddr} nickname := "test" //会自动修改为发件人的名字 subject := "卡巴内" //设置主题 contentType := "Content-Type:text/plain;charset=UTF-8\r\n" body := "this is email body" // 支持群发 msg := []byte("To: " + strings.Join(to, ",") + "\r\nFrom: " + nickname + "<" + senderAddr + ">\r\nSubject: " + subject + "\r\n" + contentType + "\r\n\r\n" + body) err := smtp.SendMail("smtp.qq.com:25", auth, senderAddr, to, msg) if err != nil { err = fmt.Errorf("发送失败%v", err) log.Println(err) return err } return nil }
- 发送文件
package main import ( "bytes" "fmt" "log" "strings" "encoding/base64" "io/ioutil" "net/smtp" ) senderAddr := "1843121593@qq.com" receviceAddr := "1843121593@qq.com" authcode = "" //这个需要自己的授权码 type Mail interface{ Auth() Send(message Message) error } // 验证 type SendMail struct{ user string password string // 授权码 host string // 服务器名称 port string // 端口 auth smtp.Auth //验证函数 } // 附件 type Attachment struct{ name string // 附件名字 contentType string // 附件的类型 withFile bool // ? } // 邮件内容 type Message struct{ from string // 源地址 to []string //目的地址 cc []string bcc []string subject string // 主题 body string // 文件内容 contentType string // 内容的类型 attachment Attachment } // 申请客户端能够发送权限 func (mail *SendMail)Auth(){ mail.auth = smtp.PlainAuth("",mail.user,mail.password,mail.host) } // 将消息头写入缓冲区 func (mail SendMail) writeHeader(buffer *bytes.Buffer,Header map[string]string)string{ header := "" for key,value := range Header{ header +=key + ":" +value + "\r\n" } header += "\r\n" buffer.WriteString(header) return header } // 读取文件 func (mail SendMail)writeFile(buffer *bytes.Buffer,fileName string)error{ file,err:= ioutil.ReadFile(fileName) if err!=nil{ log.Println(err) return err } log.Println("len(file)",len(file)) log.Println("进行base64编码") payload := make([]byte,base64.StdEncoding.EncodedLen(len(file))) //返回n字节数据进行base64编码后的最大长度 // log.Println("pyload:",payload) base64.StdEncoding.Encode(payload,file) //base64编码 log.Println("写入缓存") buffer.WriteString("\r\n") for index,line :=0,len(payload);index<line;index++{ // 写入缓存 buffer.WriteByte(payload[index]) if (index+1)%76==0{ buffer.WriteString("\r\n") } } return nil } // 发送消息 func (mail SendMail)Send(message Message)(err error){ mail.Auth() // 创建一个缓冲区 buffer := bytes.NewBuffer(nil) boundary :="GoBoundary" // 设置邮件的头部信息 Header := make(map[string]string) Header["From"] = message.from Header["To"] = strings.Join(message.to,";") //将字符串数组转化为字符串 Header["Cc"] = strings.Join(message.cc,";") Header["Bcc"] = strings.Join(message.bcc,";") Header["Subject"] = message.subject Header["Content-Type"] = "multipart/mixed;boundary="+boundary Header["Mime-Version"] = "1.0" Header["Date"] = time.Now().String() //以上的这些信息都是要填的 mail.writeHeader(buffer,Header) // 设置body值 body := "\r\n--" + boundary + "\r\n" body += "Content-Type:"+message.contentType+"\r\n" body += "\r\n" + message.body + "\r\n" buffer.WriteString(body) if message.attachment.withFile{ attachment := "\r\n--"+boundary + "\r\n" attachment += "Content-Transfer-Encoding:base64\r\n" //指明编码转换格式:base64 attachment += "Content-Disposition:attachment\r\n" //规定以什么方式下载 attachment += "Content-Type:"+message.attachment.contentType+";name=\""+message.attachment.name+"\r\n" buffer.WriteString(attachment) // 当内容超过缓存区的容量的时候,会发生panic defer func(){ if e:= recover();e!=nil{ err = e.(error) //强制转化一下类型 log.Println(e) } }() } log.Println("读取文件") if err = mail.writeFile(buffer,message.attachment.name);err!=nil{ log.Println(err) return } buffer.WriteString("\r\n") log.Println("buffer",buffer.String()) err = smtp.SendMail(mail.host+":"+mail.port,mail.auth,message.from,message.to,buffer.Bytes()) if err!=nil{ log.Println(err) return } log.Println("发送成功") return } func main() { fmt.Println("go邮箱发送") var mail Mail mail = &SendMail{user:senderAddr,password:authCode,host:"smtp.qq.com",port:"25"} message := Message{from: senderAddr, to: []string{receviceAddr}, cc: []string{}, bcc: []string{}, subject: "HELLO WORLD", body: "", contentType: "text/plain;charset=utf-8", attachment: Attachment{ name: "000008-1572019208ea18.jpg", contentType: "image/jpg", withFile: true, }, } mail.Send(message) }
-
gomail使用
- 发送消息
func sendEMailNotIncludeFile()error{ senderAddr := "1843121593@qq.com" receviceAddr := "1843121593@qq.com" authcode = "" //这个需要自己的授权码 // 创建消息体,不要认为Header完全看作是请求头,Header包含了邮件的头部信息 m := gomail.NewMessage() m.SetAddressHeader("From:",senderAddr,"没有彩虹的阳光") dst := m.FormatAddress(receviceAddr,"无季") m.SetHeader("To",dst) m.SetHeader("Subject","卡巴内瑞") m.SetBody("text/html","<a href=\"https://www.cnblogs.com/MyUniverse\">MyUnicerse</a>") //设置邮件发送的内容 d := gomail.NewPlainDialer("smtp.qq.com",25,senderAddr,authCode) // 创建连接 if err := d.DialAndSend(m);err!=nil{ log.Println(err) return err } return nil }
- 发送文件
// 使用框架发送 func SendMailIncludeFile(){ senderAddr := "1843121593@qq.com" receviceAddr := "1843121593@qq.com" authcode = "" //这个需要自己的授权码 attchAddr = "" //上传文件的地址 m:=gomail.NewMessage() m.SetAddressHeader("From",senderAddr,"无季") m.SetHeader("To",m.FormatAddress(receviceAddr,"无季")) m.SetHeader("Subject","GOMaIL") m.SetBody("text/html","Hello <a href = \"https://www.cnblogs.com/MyUniverse\">MyUnicerse</a>") m.Attach(attachAddr) d := gomail.NewPlainDialer("smtp.qq.com",465,senderAddr,attchAddr) if err := d.DialAndSend(m);err!=nil{ panic(err) } }
-
authCode的获取方法
-
特大注意
- 我们这样发送邮箱是属于第三方,会被限制一天发送的数量的。一旦被限制之后会报出535:授权码错误、运行超时等,注意这些错误有可能不是代码本身的错误。是被限制了发送的数量
-
参考资料