如何使用Go发送电子邮件

huangapple go评论84阅读模式
英文:

How to send an e-mail from Go

问题

我正在尝试在Golang中发送电子邮件,但遇到了很多问题。我在Go中是新手,所以也许这很简单,但我在文档中找不到答案。

这是我想做的事情:

  1. 从STDIN获取电子邮件
  2. 解析电子邮件(获取发件人、收件人、主题、附件等)
  3. 发送这封电子邮件(将其再次放入本地 postfix 队列)

我已经完成了第1和第2步,但在第3步遇到了问题。

这是我现在的代码:

package main 

import (
  "fmt"
  "github.com/jhillyerd/go.enmime"
  // "github.com/sendgrid/sendgrid-go"
  "net/smtp"
  "github.com/jordan-wright/email"
  "os"
  "net/mail"
  "io/ioutil"
  "bytes"
)

func main() {

  mail_stdin, err := ioutil.ReadAll(os.Stdin)
  if err != nil {
    return
  }

  // Convert type to io.Reader
  buf := bytes.NewBuffer(mail_stdin)

  msg, err := mail.ReadMessage(buf)
  if err != nil {
    return
  }

  mime, err := enmime.ParseMIMEBody(msg)
  if err != nil {
    return
  }

  // 保存附件
  for _, value := range mime.Attachments {
    fmt.Println(value.FileName())
   
    err := ioutil.WriteFile(value.FileName(), value.Content(), 0664)
    if err != nil {
      //panic(err)
      return
    }
  }

  fmt.Printf("From: %v\n", msg.Header.Get("From"))
  fmt.Printf("Subject: %v\n", mime.GetHeader("Subject"))
  fmt.Printf("Text Body: %v chars\n", len(mime.Text))
  fmt.Printf("HTML Body: %v chars\n", len(mime.Html))
  fmt.Printf("Inlines: %v\n", len(mime.Inlines))
  fmt.Printf("Attachments: %v\n", len(mime.Attachments))
  fmt.Println(mime.Attachments)
  fmt.Println(mime.OtherParts)
  fmt.Printf("Attachments: %v\n", mime.Attachments)
}

我已经使用 net/smtp、sendgrid-go 和 jordan-wright/email 进行了一些测试。
我想做的就是将电子邮件(不更改任何内容)从服务器发送到队列中。大多数模块都需要进行身份验证,但我只想简单地使用 sendmail 发送,就像我可以在 bash 中这样做一样:

# echo "test" | mail {address}
英文:

I'm trying to send an e-mail in Golang and I have a lot of problems with it. I'm new in Go so maybe this is very simply but I cannot find the answer on the doc.

This is what I want to do:

  1. get an e-mail from the STDIN
  2. parse the e-mail (getting from, to, subject, attachments and so on)
  3. send this e-mail (put it again to the queue in local postfix)

I did 1 and 2 but I have a problem with 3th one.

This is what I have now:

package main 
import (
"fmt"
"github.com/jhillyerd/go.enmime"
//"github.com/sendgrid/sendgrid-go"
"net/smtp"
"github.com/jordan-wright/email"
"os"
"net/mail"
"io/ioutil"
"bytes"
)
func main() {
mail_stdin, err := ioutil.ReadAll(os.Stdin)
if err != nil {
return
}
// Convert type to io.Reader
buf := bytes.NewBuffer(mail_stdin)
msg, err := mail.ReadMessage(buf)
if err != nil {
return
}
mime, err := enmime.ParseMIMEBody(msg)
if err != nil {
return
}
# saving attachments
for _, value := range mime.Attachments {
fmt.Println(value.FileName())
err := ioutil.WriteFile(value.FileName(), value.Content(), 0664)
if err != nil {
//panic(err)
return
}
fmt.Printf("From: %v\n", msg.Header.Get("From"))
fmt.Printf("Subject: %v\n", mime.GetHeader("Subject"))
fmt.Printf("Text Body: %v chars\n", len(mime.Text))
fmt.Printf("HTML Body: %v chars\n", len(mime.Html))
fmt.Printf("Inlines: %v\n", len(mime.Inlines))
fmt.Printf("Attachments: %v\n", len(mime.Attachments))
fmt.Println(mime.Attachments)
fmt.Println(mime.OtherParts)
fmt.Printf("Attachments: %v\n", mime.Attachments)
}

I already did few tests using: net/smtp, sendgrid-go and jordan-wright/email.
All I want to do is to send an e-mail (without changing anything) from the server to the queue again. Most of those modules needs to have Auth, but I just want to simply send is using sendmail, in the same way as I can do this from the bash:

# echo "test" | mail {address}

答案1

得分: 2

使用net/smtp包,你可以相对容易地实现这个功能...假设你有一个运行中的 SMTP 服务器,可以在没有身份验证的情况下连接到它。我猜你想要实现的功能可能更容易通过像 Gmail 这样简单的方式来完成(https://www.digitalocean.com/community/tutorials/how-to-use-google-s-smtp-server)。

无论如何,下面是几个代码示例,涵盖了两种情况:

c, err := smtp.Dial("mail.example.com:25")
if err != nil {
    log.Fatal(err)
}
defer c.Close()
// 设置发件人和收件人。
c.Mail("sender@example.org")
c.Rcpt("recipient@example.net")
// 发送邮件正文。
wc, err := c.Data()
if err != nil {
    log.Fatal(err)
}
defer wc.Close()
buf := bytes.NewBufferString("This is the email body.")
if _, err = buf.WriteTo(wc); err != nil {
    log.Fatal(err)
}

另外,这里有一个使用简单身份验证的 Go Playground 示例:http://play.golang.org/p/ATDCgJGKZ3,除非你已经在你的开发机上运行了一个 SMTP 服务器,按照这样的方式进行操作可能会更容易一些。

英文:

Using net/smtp you can do this fairly easily... Assuming you have an smtp server running that you can connect to without authentication. I would guess for what you're trying to accomplish it's actually a lot easier to do through something simple like your gmail ( https://www.digitalocean.com/community/tutorials/how-to-use-google-s-smtp-server )

Anyway, here's a couple code samples to cover either case;

    c, err := smtp.Dial("mail.example.com:25")
if err != nil {
log.Fatal(err)
}
defer c.Close()
// Set the sender and recipient.
c.Mail("sender@example.org")
c.Rcpt("recipient@example.net")
// Send the email body.
wc, err := c.Data()
if err != nil {
log.Fatal(err)
}
defer wc.Close()
buf := bytes.NewBufferString("This is the email body.")
if _, err = buf.WriteTo(wc); err != nil {
log.Fatal(err)
}

Alternatively here's a go playground example that uses simple auth; http://play.golang.org/p/ATDCgJGKZ3 unless you've already got an smtp server running on your dev box following something like that will probably be a lot easier.

huangapple
  • 本文由 发表于 2015年7月7日 23:18:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/31272725.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定