golang发送邮件
package main
import (
"bytes"
"crypto/tls"
"errors"
"fmt"
"io"
"net"
"net/smtp"
"os"
"path/filepath"
"strconv"
"time"
)
func main() {
var (
err error
message string
)
sender := "[email protected]"
password := "password"
recipient := "[email protected]"
smtpHost := "smtp.163.com"
smtpPort := 465
tcpTimeout := 5 * time.Second
subject := "Test Subject"
body := "This is the body of the email."
attachmentPath := "aa/test.txt"
if attachmentPath == "" {
message = CreateMessage(sender, recipient, subject, body)
} else {
message, err = CreateMessageWithAttachment(sender, recipient, subject, body, attachmentPath)
if err != nil {
fmt.Println("设置邮件消息失败: ", err)
return
}
}
if smtpPort == 25 {
err = SendEmailNormal(sender, password, smtpHost, message, recipient, smtpPort, tcpTimeout)
} else {
err = SendEmailWithTls(sender, password, smtpHost, message, recipient, smtpPort, tcpTimeout)
}
if err != nil {
fmt.Println("邮件发送失败:", err)
return
}
fmt.Println("邮件发送成功")
}
func CreateMessage(sender, recipient, subject, body string) string {
message := fmt.Sprintf("From: %s\r\n", sender)
message += fmt.Sprintf("To: %s\r\n", recipient)
message += fmt.Sprintf("Subject: %s\r\n", subject)
message += "\r\n" + body
return message
}
func CreateMessageWithAttachment(sender, recipient, subject, body, attachmentPath string) (string, error) {
var msg bytes.Buffer
io.WriteString(&msg, "From: "+sender+"\r\n")
io.WriteString(&msg, "To: "+recipient+"\r\n")
io.WriteString(&msg, "Subject: "+subject+"\r\n")
io.WriteString(&msg, "MIME-version: 1.0;\r\n")
io.WriteString(&msg, "Content-Type: multipart/mixed; boundary=foobar\r\n\r\n")
io.WriteString(&msg, "--foobar\r\n")
io.WriteString(&msg, "Content-Type: text/plain; charset=\"utf-8\"\r\n\r\n")
io.WriteString(&msg, body+"\r\n")
attachmentFile, err := os.Open(attachmentPath)
if err != nil {
return "", err
}
defer attachmentFile.Close()
io.WriteString(&msg, "--foobar\r\n")
io.WriteString(&msg, "Content-Type: application/octet-stream\r\n")
io.WriteString(&msg, "Content-Disposition: attachment; filename=\""+filepath.Base(attachmentPath)+"\"\r\n\r\n")
io.Copy(&msg, attachmentFile)
io.WriteString(&msg, "\r\n")
io.WriteString(&msg, "--foobar--\r\n")
return msg.String(), nil
}
func SendEmailWithTls(username, password, smtpHost, message, recipient string, smtpPort int, tcpTimeout time.Duration) error {
auth := smtp.PlainAuth("", username, password, smtpHost)
dialer := &net.Dialer{
Timeout: tcpTimeout,
}
conn, err := tls.DialWithDialer(dialer, "tcp", smtpHost+":"+strconv.Itoa(smtpPort), &tls.Config{
InsecureSkipVerify: true,
})
if err != nil {
return errors.New("DialWithDialer err: " + err.Error())
}
defer conn.Close()
client, err := smtp.NewClient(conn, smtpHost)
if err != nil {
return errors.New("NewClient err: " + err.Error())
}
defer client.Quit()
err = client.Auth(auth)
if err != nil {
return errors.New("Auth err: " + err.Error())
}
err = client.Mail(username)
if err != nil {
return err
}
err = client.Rcpt(recipient)
if err != nil {
return err
}
data, err := client.Data()
if err != nil {
return err
}
defer data.Close()
_, err = data.Write([]byte(message))
if err != nil {
return err
}
return nil
}
func SendEmailNormal(username, password, smtpHost, message, recipient string, smtpPort int, tcpTimeout time.Duration) error {
auth := smtp.PlainAuth("", username, password, smtpHost)
conn, err := net.DialTimeout("tcp", smtpHost+":"+strconv.Itoa(smtpPort), tcpTimeout)
if err != nil {
return errors.New("DialTimeout err: " + err.Error())
}
defer conn.Close()
client, err := smtp.NewClient(conn, smtpHost)
if err != nil {
return errors.New("NewClient err: " + err.Error())
}
defer client.Quit()
err = client.StartTLS(&tls.Config{
InsecureSkipVerify: true,
})
if err != nil {
return errors.New("StartTLS err: " + err.Error())
}
err = client.Auth(auth)
if err != nil {
return errors.New("Auth err: " + err.Error())
}
err = client.Mail(username)
if err != nil {
return err
}
err = client.Rcpt(recipient)
if err != nil {
return err
}
data, err := client.Data()
if err != nil {
return err
}
defer data.Close()
_, err = data.Write([]byte(message))
if err != nil {
return err
}
return nil
}