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