Go smtp发送邮件,带附件


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: "chunyunzeng@hotmail.com", password: "password", host: "smtp.mxhichina.com", port: "25"}
	message := Message{from: "chunyunzeng@hotmail.com",
		to: []string{"850808158@qq.com"},
		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 := "
--" + boundary + "
"
	body += "Content-Type:" + message.contentType + "
"
	body += "
" + message.body + "
"
	buffer.WriteString(body)

	if message.attachment.withFile {
		attachment := "
--" + boundary + "
"
		attachment += "Content-Transfer-Encoding:base64
"
		attachment += "Content-Disposition:attachment
"
		attachment += "Content-Type:" + message.attachment.contentType + ";name="" + message.attachment.name + ""
"
		buffer.WriteString(attachment)
		defer func() {
			if err := recover(); err != nil {
				log.Fatalln(err)
			}
		}()
		mail.writeFile(buffer, message.attachment.name)
	}

	buffer.WriteString("
--" + 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 + "
"
	}
	header += "
"
	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("
")
	for index, line := 0, len(payload); index < line; index++ {
		buffer.WriteByte(payload[index])
		if (index+1)%76 == 0 {
			buffer.WriteString("
")
		}
	}
}

原文地址:https://www.cnblogs.com/zengchunyun/p/9485444.html