转https://studygolang.com/articles/2098
核心代码:smtp.SendMail(host, auth, user, send_to, msg),auth := smtp.PlainAuth("", user, password, hp[0])
可行方案:使用企业邮箱的SMTP发送邮件,host :="smtp.exmail.qq.com:25",因此需要一个企业邮箱的账号和密码
直接上代码:
main.go
package main
import (
"fmt"
"net/smtp"
"strings"
)
func SendToMail(user, password, host, to, subject, body, mailtype string) error {
hp := strings.Split(host, ":")
auth := smtp.PlainAuth("", user, password, hp[0])
var content_type string
if mailtype == "html" {
content_type = "Content-Type: text/" + mailtype + "; charset=UTF-8"
} else {
content_type = "Content-Type: text/plain" + "; charset=UTF-8"
}
msg := []byte("To: " + to + "\r\nFrom: " + user + ">\r\nSubject: " + "\r\n" + content_type + "\r\n\r\n" + body)
send_to := strings.Split(to, ";")
err := smtp.SendMail(host, auth, user, send_to, msg)
return err
}
func main() {
user := "yang**@yun*.com"
password := "***"
host := "smtp.exmail.qq.com:25"
to := "[email protected]"
subject := "使用Golang发送邮件"
body := `
"Test send to email"
`
fmt.Println("send email")
err := SendToMail(user, password, host, to, subject, body, "html")
if err != nil {
fmt.Println("Send mail error!")
fmt.Println(err)
} else {
fmt.Println("Send mail success!")
}
}
遇到的问题:
1、body := ``,这里用的是反单引号,而非单引号;
2、err != nil,golang的nil在概念上和其它语言的null、None、nil、NULL一样,都指代零值或空值。nil是预先说明的标识符,也即通常意义上的关键字。在golang中,nil只能赋值给指针、channel、func、interface、map或slice类型的变量。如果未遵循这个规则,则会引发panic。对此官方有明确的说明:http://pkg.golang.org/pkg/builtin/#Type
3、参数auth,auth := smtp.PlainAuth("", user, password, hp[0])
4、强制类型转换,msg := []byte("To: " + to + "\r\nFrom: " + user + ">\r\nSubject: " + "\r\n" + content_type + "\r\n\r\n" + body)
5、多个邮箱:send_to := strings.Split(to, ";")
带附件方法2
package main
import (
"net/smtp"
"bytes"
"time"
"io/ioutil"
"encoding/base64"
"strings"
"log"
)
// define email interface, and implemented auth and send method
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 main() {
var mail Mail
mail = &SendMail{user: "[email protected]", password: "password", host: "smtp.mxhichina.com", port: "25"}
message := Message{from: "[email protected]",
to: []string{"[email protected]"},
cc: []string{},
bcc: []string{},
subject: "HELLO WORLD",
body: "",
contentType: "text/plain;charset=utf-8",
attachment: Attachment{
name: "test.jpg",
contentType: "image/jpg",
withFile: true,
},
}
mail.Send(message)
}
func (mail *SendMail) Auth() {
mail.auth = smtp.PlainAuth("", mail.user, mail.password, mail.host)
}
func (mail SendMail) Send(message Message) 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 := "\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"
attachment += "Content-Disposition:attachment\r\n"
attachment += "Content-Type:" + message.attachment.contentType + ";name=\"" + message.attachment.name + "\"\r\n"
buffer.WriteString(attachment)
defer func() {
if err := recover(); err != nil {
log.Fatalln(err)
}
}()
mail.writeFile(buffer, message.attachment.name)
}
buffer.WriteString("\r\n--" + boundary + "--")
smtp.SendMail(mail.host+":"+mail.port, mail.auth, message.from, message.to, buffer.Bytes())
return nil
}
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
}
// read and write the file to buffer
func (mail SendMail) writeFile(buffer *bytes.Buffer, fileName string) {
file, err := ioutil.ReadFile(fileName)
if err != nil {
panic(err.Error())
}
payload := make([]byte, base64.StdEncoding.EncodedLen(len(file)))
base64.StdEncoding.Encode(payload, file)
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")
}
}
}