如何在Go语言中通过Exim发送邮件(不使用SMTP)?
在Go中通过Exim发送邮件(无需SMTP)
你现在用的gomail.v2主要是针对SMTP协议的,但Exim作为本地邮件传输代理(MTA),支持直接通过命令行或管道接收邮件内容,完全不需要走SMTP流程。下面给你两种实用的实现方式:
方法一:直接调用Exim命令行发送
Exim支持通过-t参数从邮件内容的头信息里自动识别收件人,我们可以直接构建符合RFC标准的邮件内容,然后通过标准输入传给Exim:
package main import ( "bytes" "fmt" "os/exec" ) func main() { // 构建完整的邮件内容,头和正文之间要留空行 var emailContent bytes.Buffer emailContent.WriteString("From: me@example.com\n") emailContent.WriteString("To: you@example.com\n") emailContent.WriteString("Bcc: youbcc@example.com, anotherbcc@example.com\n") emailContent.WriteString("Subject: 测试邮件(直接调用Exim)\n") emailContent.WriteString("Content-Type: text/plain; charset=utf-8\n\n") emailContent.WriteString("这是通过Exim直接发送的邮件正文,不需要SMTP服务器!") // 执行Exim命令,-t表示从邮件头读取收件人列表 cmd := exec.Command("/usr/sbin/exim", "-t") cmd.Stdin = &emailContent // 捕获错误输出,方便排查问题 var stderr bytes.Buffer cmd.Stderr = &stderr if err := cmd.Run(); err != nil { fmt.Printf("邮件发送失败: %v,错误详情: %s\n", err, stderr.String()) return } fmt.Println("邮件发送成功!") }
方法二:结合Gomail构建邮件 + Exim发送
如果你习惯用gomail.v2来处理复杂邮件(比如HTML内容、附件),可以先用Gomail构建好邮件结构,再把生成的邮件内容传给Exim,这样兼顾便捷性和本地投递的需求:
package main import ( "bytes" "fmt" "gopkg.in/gomail.v2" "os/exec" ) func main() { // 用Gomail构建邮件,和你原来的代码逻辑一致 m := gomail.NewMessage() m.SetHeader("From", "me@example.com") m.SetHeader("To", "you@example.com") m.SetAddressHeader("Bcc", "youbcc@example.com", "Bcc收件人") m.SetHeader("Bcc", "anotherbcc@example.com") m.SetHeader("Subject", "测试邮件(Gomail + Exim)") m.SetBody("text/html", "<h1>Hello!</h1><p>这是用Gomail构建的HTML邮件,通过Exim发送。</p>") // 可以添加附件 // m.Attach("document.pdf") // 将Gomail的邮件内容写入缓冲区 var emailBuffer bytes.Buffer if err := m.WriteTo(&emailBuffer); err != nil { fmt.Printf("构建邮件失败: %v\n", err) return } // 调用Exim发送邮件 cmd := exec.Command("/usr/sbin/exim", "-t") cmd.Stdin = &emailBuffer var stderr bytes.Buffer cmd.Stderr = &stderr if err := cmd.Run(); err != nil { fmt.Printf("发送失败: %v,错误信息: %s\n", err, stderr.String()) return } fmt.Println("邮件发送成功!") }
注意事项
- 确保你的Go程序有执行
/usr/sbin/exim的权限,部分系统可能需要将程序加入特定用户组(比如mail组),或者配置Exim允许本地用户投递邮件。 - 邮件内容的格式要符合RFC规范,尤其是头信息和正文之间的空行,否则Exim可能无法正确解析。
- 如果你的系统中Exim被链接为
sendmail(很多Linux发行版默认这么做),可以把命令换成exec.Command("/usr/sbin/sendmail", "-t"),效果完全一样。
内容的提问来源于stack exchange,提问作者Garvit Jain
相关产品推荐
相关产品推荐

