如何在没有任何 smtp 服务器的情况下在 golang 中发送电子邮件
How to send emails in golang without any smtp server
我想从用 golang 编写的服务器应用程序发送群发邮件。我只是不想使用任何第三方 smtp 服务器来避免使用配额限制。
没有 smtp 服务器如何发送电子邮件?标准库中的 smtp 包可以帮助我吗?我看到的所有使用 smtp 包的示例都需要第三方 smtp 服务器来发送电子邮件。
您的问题类似于 - 我可以在没有网络服务器的情况下向用户显示网页吗?是的,如果您能够编写自己的网络服务器,您就可以。
你会在 Go 上编写 SMTP 服务器吗?是的。 Google 显示了 "golang smtp server" 查询的几个解决方案。所以我很确定您可以将 SMTP 服务器功能集成到您的应用程序中。
但正如评论者所说 - 您的大部分邮件(如果不是全部)将直接进入大部分服务的垃圾邮件文件夹。
只有一种方法可以在不直接与 SMTP 服务器通信的情况下发送 e-mail 消息:将此操作委托给其他程序。
选择什么程序,本身就是一个开放而广泛的问题,因为有很多程序可以发送邮件。
另一方面,如果我们谈论 POSIX 系统,例如 GNU/Linux- 或 *BSD-based 操作系统,它们 通常 带有二进制 /usr/sbin/sendmail
或有时 /usr/bin/sendmail
由真正的 Sendmail package or by another MTA which exist in abundance—ranging from full-blown MTAs such as Postfix or Exim 提供给 narrow-scoped "null-clients" 例如 ssmtp
或 nullmailer
.
此程序通常使用 -t
command-line 选项调用,这使得它从邮件本身的 To
headers 中读取邮件收件人的地址.
基本上调用 /usr/sbin/sendmail -t
并将完整消息的文本通过管道传输到其标准输入是 PHP's mail()
function 所做的,FWIW。
虽然您可以直接使用 os/exec
、net/mail
和 net/textproto
标准包进行此调用,但流行的 gomail
包提供了一种更简单的方法:它的 Message
类型提供了 WriteTo()
方法,可以写入 运行 Sendmail 实例,像这样(从我的一个真实程序中复制):
const sendmail = "/usr/sbin/sendmail"
func submitMail(m *gomail.Message) (err error) {
cmd := exec.Command(sendmail, "-t")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
pw, err := cmd.StdinPipe()
if err != nil {
return
}
err = cmd.Start()
if err != nil {
return
}
var errs [3]error
_, errs[0] = m.WriteTo(pw)
errs[1] = pw.Close()
errs[2] = cmd.Wait()
for _, err = range errs {
if err != nil {
return
}
}
return
}
实际上,依靠 MTA 来传递邮件的一个优势是 full-blown MTA 支持邮件排队:也就是说,如果 MTA 无法立即发送您的邮件(例如,由于网络原因)中断等)所以它会将消息保存在一个特殊的目录中,然后会定期尝试一次又一次地传递它直到成功或(通常很长,比如 4-5 天)超时到期。
我想从用 golang 编写的服务器应用程序发送群发邮件。我只是不想使用任何第三方 smtp 服务器来避免使用配额限制。
没有 smtp 服务器如何发送电子邮件?标准库中的 smtp 包可以帮助我吗?我看到的所有使用 smtp 包的示例都需要第三方 smtp 服务器来发送电子邮件。
您的问题类似于 - 我可以在没有网络服务器的情况下向用户显示网页吗?是的,如果您能够编写自己的网络服务器,您就可以。
你会在 Go 上编写 SMTP 服务器吗?是的。 Google 显示了 "golang smtp server" 查询的几个解决方案。所以我很确定您可以将 SMTP 服务器功能集成到您的应用程序中。
但正如评论者所说 - 您的大部分邮件(如果不是全部)将直接进入大部分服务的垃圾邮件文件夹。
只有一种方法可以在不直接与 SMTP 服务器通信的情况下发送 e-mail 消息:将此操作委托给其他程序。
选择什么程序,本身就是一个开放而广泛的问题,因为有很多程序可以发送邮件。
另一方面,如果我们谈论 POSIX 系统,例如 GNU/Linux- 或 *BSD-based 操作系统,它们 通常 带有二进制 /usr/sbin/sendmail
或有时 /usr/bin/sendmail
由真正的 Sendmail package or by another MTA which exist in abundance—ranging from full-blown MTAs such as Postfix or Exim 提供给 narrow-scoped "null-clients" 例如 ssmtp
或 nullmailer
.
此程序通常使用 -t
command-line 选项调用,这使得它从邮件本身的 To
headers 中读取邮件收件人的地址.
基本上调用 /usr/sbin/sendmail -t
并将完整消息的文本通过管道传输到其标准输入是 PHP's mail()
function 所做的,FWIW。
虽然您可以直接使用 os/exec
、net/mail
和 net/textproto
标准包进行此调用,但流行的 gomail
包提供了一种更简单的方法:它的 Message
类型提供了 WriteTo()
方法,可以写入 运行 Sendmail 实例,像这样(从我的一个真实程序中复制):
const sendmail = "/usr/sbin/sendmail"
func submitMail(m *gomail.Message) (err error) {
cmd := exec.Command(sendmail, "-t")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
pw, err := cmd.StdinPipe()
if err != nil {
return
}
err = cmd.Start()
if err != nil {
return
}
var errs [3]error
_, errs[0] = m.WriteTo(pw)
errs[1] = pw.Close()
errs[2] = cmd.Wait()
for _, err = range errs {
if err != nil {
return
}
}
return
}
实际上,依靠 MTA 来传递邮件的一个优势是 full-blown MTA 支持邮件排队:也就是说,如果 MTA 无法立即发送您的邮件(例如,由于网络原因)中断等)所以它会将消息保存在一个特殊的目录中,然后会定期尝试一次又一次地传递它直到成功或(通常很长,比如 4-5 天)超时到期。