如何用Golang自建的域名邮箱发邮件到QQ邮箱?

问题如上大标题。
我已经知道客户端和服务器之间的SMTP通信过程,但是服务器和服务器之间如何用SMTP通信就不太知道了。
这两者的区别主要是在用户登录的时候,前者使用用户名和密码就行了,后者通过MX记录来查看来访IP是是真实的域名所有者(根据我查到的资料是这样的)。但是RFC821和RFC1869上似乎都没有相关内容。
这是服务器返回的错误 535 Error: authentication failed
相关代码如下

package main

import (
    "crypto/tls"
    "fmt"
    "net/smtp"
)

// SendEmail 发送邮件
func main() {
    conn, err := tls.Dial("tcp", "smtp.qq.com:465", nil)
    if err != nil {
        fmt.Println("ERROR CODE: 1;" + err.Error())
        return
    }
    c, err := smtp.NewClient(conn, "smtp.qq.com")
    if err != nil {
        fmt.Println("ERROR CODE: 2;" + err.Error())
        return
    }
    err = c.Hello("mail.mydomain.me")
    if err != nil {
        fmt.Println("ERROR CODE: 3;" + err.Error())
        return
    }

    //****************************猜测问题所在
    a := smtp.PlainAuth("", "one@mail.mydomain.me", "", "smtp.qq.com")
    err = c.Auth(a)
    if err != nil {
        fmt.Println("ERROR CODE: 4;" + err.Error())//在这里报错!
        return
    }
    //****************************
    err = c.Mail("one@mail.mydomain.me")
    if err != nil {
        fmt.Println("ERROR CODE: 5;" + err.Error())
        return
    }
    err = c.Rcpt("17xxxxxx05@qq.com")
    if err != nil {
        fmt.Println("ERROR CODE: 6;" + err.Error())
        return
    }
    w, err := c.Data()
    if err != nil {
        fmt.Println("ERROR CODE: 7;" + err.Error())
        return
    }

    header := make(map[string]string)
    header["From"] = "mydomain.me"
    header["TO"] = "17xxxxxx05@qq.com"
    header["Subject"] = "TEST"
    header["Content-Type"] = "text/html;chartset=UTF-8"

    var smtpMsg string
    for k, v := range header {
        smtpMsg += k + ":" + v + "\r\n"
    }

    // 将正文拼接
    smtpMsg += "\r\n" + "body test"

    _, err = w.Write([]byte(smtpMsg))
    if err != nil {
        fmt.Println("ERROR CODE: 8;" + err.Error())
        return
    }
    err = w.Close()
    if err != nil {
        fmt.Println("ERROR CODE: 9;" + err.Error())
        return
    }
    err = c.Quit()
    if err != nil {
        err = c.Close()
        if err != nil {
            fmt.Println("ERROR CODE: 10;" + err.Error())
            return
        }
        fmt.Println("ERROR CODE: 11;" + err.Error())
        return
    }
}

我已经设置了相关的DNS解析

阅读 5.3k
2 个回答
a := smtp.PlainAuth("", "one@mail.mydomain.me", "", "smtp.qq.com")

这里的smtp.qq.com应该是你自建的域名邮箱服务器吧?流程应该是先登录到你自己的邮箱服务器,再进行发送邮件的操作。

如果你已经自建好邮件服务器,其实这里只需要把写发送邮箱改成你自建邮件服务对应URI即可(当然相应的认证信息肯定也需要你适配),至于邮件服务器间如何交换信息,并不在这个问题包含的范围内,你可以认为是透明的,或者说一个黑箱处理。

你只需要调用本地邮件服务的接口,按规定填入合适信息,本地邮件服务器如果服务正常,就自动会发出相应邮件啦。

其实你应该更关心你自建邮件服务器是否正常运行,提供的远程发送邮件服务是否正确,相应的调用方法是什么?

如果你go语言程序和邮件服务器在一个主机上,甚至可以本地发送邮件。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题