GO(golang)语言使用SMTP发送电子邮件,简单和复杂带附件cc,bcc

转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")
        }
    }
}

 

你可能感兴趣的:(Go)