Tüm Ürünler
Search
Belge Merkezi

Direct Mail:Go ile SMTP Kullanımı: Örnek Kod

Son Güncelleme:Oct 04, 2026

Direct Mail SMTP hizmetini kullanarak bir Go uygulamasından e-posta gönderin. İki eksiksiz örnek; PLAIN veya LOGIN kimlik doğrulamasıyla düz bağlantı için bağlantı noktası 80'i, örtük TLS için ise bağlantı noktası 465'i kapsar.

Direct Mail iki SMTP uç noktası sunar. PLAIN veya LOGIN kimlik doğrulamasıyla düz bağlantı kurmak için 80 numaralı bağlantı noktasını kullanın. Herhangi bir SMTP komutundan önce TLS el sıkışmasının gerçekleştiği örtük TLS için 465 numaralı bağlantı noktasını kullanın. Her iki örnek de Go 1.16.5 üzerinde doğrulanmıştır ve SMTP sunucusu olarak smtpdm.aliyun.com adresini kullanır.

Ön Koşullar

Başlamadan önce aşağıdakilere sahip olduğunuzdan emin olun:

  • Direct Mail konsolunda yapılandırılmış ve doğrulanmış bir gönderen adresi

  • Bu gönderen adresine ait SMTP parolası

80 Numaralı Bağlantı Noktasını Kullanma

Aşağıdaki örnek; Alıcı (To), Bilgi (CC) ve Gizli Kopya (BCC) alanlarına sahip bir HTML e-postası gönderir. MergeSlice işlevi, bu üç alıcı listesini tek bir SMTP zarf alıcı listesinde birleştirir. E-posta başlıklarında ne gösterildiğinden bağımsız olarak mesajın hangi posta kutularına teslim edileceğini SMTP RCPT TO komutu belirlediğinden bu adım gereklidir.

main() işlevindeki yer tutucu dizeleri, Direct Mail konsolundaki gönderen adresiniz ve SMTP parolanızla değiştirin.

Not

Şifreli bir bağlantı üzerinden gönderim yapmak için aşağıdaki 465 numaralı bağlantı noktası örneğini kullanın. TLS bağlantıları için 80 numaralı bağlantı noktası kodunu kullanmayın.

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
}

Go 1.9.2 uyumluluk notu

Not

Go 1.9.2 şifreli kimlik doğrulama gerektirir ve düz bir PlainAuth çağrısını "unencrypted connection" (şifrelenmemiş bağlantı) hatasıyla reddeder. Bu sorunu çözmek için smtp.PlainAuth çağrısını aşağıdaki özel LoginAuth uygulamasıyla değiştirin.

Dosyanıza aşağıdaki LoginAuth uygulamasını ekleyin:

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
}

Ardından, main() içindeki auth satırını aşağıdakiyle değiştirin:

auth := LoginAuth(user, password)

465 Numaralı Bağlantı Noktasını Kullanma

465 numaralı bağlantı noktası örtük TLS kullanır: TLS el sıkışması herhangi bir SMTP komutundan önce gerçekleşir. Bu nedenle net/smtp paketinin yerleşik SendMail işlevi doğrudan kullanılamaz. Örnek; tls.Dial kullanarak bir TLS bağlantısı açan özel bir Dial işlevi ve SMTP oturumunu manuel olarak yöneten bir SendMailUsingTLS işlevi tanımlar.

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

// Dial opens an implicit TLS connection and returns an 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 address string.
    host, _, _ := net.SplitHostPort(addr)
    return smtp.NewClient(conn, host)
}

// SendMailUsingTLS sends an email over an implicit TLS connection.
// 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 the 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()
}