Use port 80
You can use the Go language to send emails over SMTP. This code is verified on Go version 1.16.5.
Note
To use TLS encryption on port 465, see the section below. Do not use the code for port 80 for this purpose.
package main
import (
"fmt"
"net/smtp"
"strings"
"time"
)
func SendToMail(user, password, host, subject, date, body, mailtype, replyToAddress string, to, cc, bcc []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"
}
cc_address := strings.Join(cc, ";")
bcc_address := strings.Join(bcc, ";")
to_address := strings.Join(to, ";")
msg := []byte("To: " + to_address + "\r\nFrom: " + user + "\r\nSubject: " + subject+ "\r\nDate: " + date + "\r\nReply-To: " + replyToAddress + "\r\nCc: " + cc_address + "\r\nBcc: " + bcc_address + "\r\n" + content_type + "\r\n\r\n" + body)
send_to := MergeSlice(to, cc)
send_to = MergeSlice(send_to, bcc)
err := smtp.SendMail(host, auth, user, send_to, msg)
return err
}
func main() {
user := "The sender address created in the console"
password := "The SMTP password set in the console"
host := "smtpdm.aliyun.com:80"
to := []string{"recipient_address","recipient_address_1"}
cc := []string{"cc_address","cc_address_1"}
bcc := []string{"bcc_address","bcc_address_1"}
subject := "test Golang to sendmail"
date := fmt.Sprintf("%s", time.Now().Format(time.RFC1123Z))
mailtype :="html"
replyToAddress:="a***@example.net"
body := "<html><body><h3>Test send to email</h3></body></html>"
fmt.Println("send email")
err := SendToMail(user, password, host, subject,date, body, mailtype, replyToAddress, to, cc, bcc)
if err != nil {
fmt.Println("Send mail error!")
fmt.Println(err)
} else {
fmt.Println("Send mail success!")
}
}
func MergeSlice(s1 []string, s2 []string) []string {
slice := make([]string, len(s1)+len(s2))
copy(slice, s1)
copy(slice[len(s1):], s2)
return slice
}Note
If you use Go version 1.9.2, an "unencrypted connection" error may occur because this version requires encrypted authentication. To resolve this issue, use LOGIN authentication by adding the following code.
type loginAuth struct {
username, password string
}
func LoginAuth(username, password string) smtp.Auth {
return &loginAuth{username, password}
}
func (a *loginAuth) Start(server *smtp.ServerInfo) (string, []byte, error) {
// return "LOGIN", []byte{}, nil
return "LOGIN", []byte(a.username), nil
}
func (a *loginAuth) Next(fromServer []byte, more bool) ([]byte, error) {
if more {
switch string(fromServer) {
case "Username:":
return []byte(a.username), nil
case "Password:":
return []byte(a.password), nil
}
}
return nil, nil
}Modify the call method as follows:
auth := LoginAuth(user, password)Use port 465
package main
import (
"crypto/tls"
"fmt"
"log"
"net"
"net/smtp"
)
func main() {
host := "smtpdm.aliyun.com"
port := 465
email := "test***@example.net"
password := "TExxxxxst"
toEmail := "test1***@example.net"
header := make(map[string]string)
header["From"] = "test" + "<" + email + ">"
header["To"] = toEmail
header["Subject"] = "Email Title"
header["Content-Type"] = "text/html; charset=UTF-8"
body := "This is a test email!"
message := ""
for k, v := range header {
message += fmt.Sprintf("%s: %s\r\n", k, v)
}
message += "\r\n" + body
auth := smtp.PlainAuth(
"",
email,
password,
host,
)
err := SendMailUsingTLS(
fmt.Sprintf("%s:%d", host, port),
auth,
email,
[]string{toEmail},
[]byte(message),
)
if err != nil {
panic(err)
} else {
fmt.Println("Send mail success!")
}
}
//return a smtp client
func Dial(addr string) (*smtp.Client, error) {
conn, err := tls.Dial("tcp", addr, nil)
if err != nil {
log.Println("Dialing Error:", err)
return nil, err
}
// Split the host and port from the string.
host, _, _ := net.SplitHostPort(addr)
return smtp.NewClient(conn, host)
}
// See the SendMail() function in net/smtp.
// When you use net. Dial to connect to a TLS (SSL) port, smtp.NewClient() may hang without returning an error.
// If len(to) is greater than 1, recipients from to[1] onwards are treated as BCC recipients.
func SendMailUsingTLS(addr string, auth smtp.Auth, from string,
to []string, msg []byte) (err error) {
//create smtp client
c, err := Dial(addr)
if err != nil {
log.Println("Create smpt client error:", err)
return err
}
defer c.Close()
if auth != nil {
if ok, _ := c.Extension("AUTH"); ok {
if err = c.Auth(auth); err != nil {
log.Println("Error during AUTH", err)
return err
}
}
}
if err = c.Mail(from); err != nil {
return err
}
for _, addr := range to {
if err = c.Rcpt(addr); err != nil {
return err
}
}
w, err := c.Data()
if err != nil {
return err
}
_, err = w.Write(msg)
if err != nil {
return err
}
err = w.Close()
if err != nil {
return err
}
return c.Quit()
}