【问题标题】:Sending Office 365 email [duplicate]发送 Office 365 电子邮件 [重复]
【发布时间】:2020-10-22 20:44:45
【问题描述】:

我有下面的 main.go 代码来解析 HTML 模板并通过电子邮件发送:

package main

import (
  "bytes"
  "fmt"
  "net/smtp"
  "text/template"
)

func main() {
  // Sender data.
  from := "from@gmail.com"
  password := "<Email Password>"

  // Receiver email address.
  to := []string{
    "sender@example.com",
  }

  // smtp server configuration.
  smtpHost := "smtp.gmail.com"
  smtpPort := "587"

  // Authentication.
  auth := smtp.PlainAuth("", from, password, smtpHost)

  t, _ := template.ParseFiles("template.html")

  var body bytes.Buffer

  mimeHeaders := "MIME-version: 1.0;\nContent-Type: text/html; charset=\"UTF-8\";\n\n"
  body.Write([]byte(fmt.Sprintf("Subject: This is a test subject \n%s\n\n", mimeHeaders)))

  t.Execute(&body, struct {
    Name    string
    Message string
  }{
    Name:    "Hasan yousef",
    Message: "This is a test message in a HTML template",
  })

  // Sending email.
  err := smtp.SendMail(smtpHost+":"+smtpPort, auth, from, to, body.Bytes())
  if err != nil {
    fmt.Println(err)
    return
  }
  fmt.Println("Email Sent!")
}

使用以下模板:

<!-- template.html -->
<!DOCTYPE html>
<html>
<body>
    <h3>Name:</h3><span>{{.Name}}</span><br/><br/>
    <h3>Email:</h3><span>{{.Message}}</span><br/>
</body>
</html>

效果很好。

我尝试对我的Office 365 电子邮件执行相同操作:

smtpHost := "smtp.office365.com"
smtpPort := "587" 

但是没用,报如下错误:

504 5.7.4 Unrecognized authentication type [ZR0P278CA0020.CHEP278.PROD.OUTLOOK.COM]

在 Gmail 中,我启用了 using unsecure app 以使 smtp.PlainAuth 工作正常,在 Office 365 中我知道它的 Encryption method: TLS or STARTTLS 但不知道如何将其合并到我的代码中?

【问题讨论】:

  • 如果您的问题是关于 TLS/STARTTLS,那么请删除所有与 HTML 模板解析无关的细节。
  • 感谢@Marc 在您链接的帮助下,我找到了答案。赞赏。

标签: go


【解决方案1】:

我找到了正确答案,在此分享以造福社区:

package main

import (
    "bytes"
    "crypto/tls"
    "errors"
    "fmt"
    "net"
    "net/smtp"
    "text/template"
)

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(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
        default:
            return nil, errors.New("Unknown from server")
        }
    }
    return nil, nil
}

func main() {

    // Sender data.
    from := "O365 logging name"
    password := "O365 logging pasword"

    // Receiver email address.
    to := []string{
        "receiver email",
    }

    // smtp server configuration.
    smtpHost := "smtp.office365.com"
    smtpPort := "587"

    conn, err := net.Dial("tcp", "smtp.office365.com:587")
    if err != nil {
        println(err)
    }

    c, err := smtp.NewClient(conn, smtpHost)
    if err != nil {
        println(err)
    }

    tlsconfig := &tls.Config{
        ServerName: smtpHost,
    }

    if err = c.StartTLS(tlsconfig); err != nil {
        println(err)
    }

    auth := LoginAuth(from, password)

    if err = c.Auth(auth); err != nil {
        println(err)
    }

    t, _ := template.ParseFiles("template.html")

    var body bytes.Buffer

    mimeHeaders := "MIME-version: 1.0;\nContent-Type: text/html; charset=\"UTF-8\";\n\n"
    body.Write([]byte(fmt.Sprintf("Subject: This is a test subject \n%s\n\n", mimeHeaders)))

    t.Execute(&body, struct {
        Name    string
        Message string
    }{
        Name:    "Hasan Yousef",
        Message: "This is a test message in a HTML template",
    })

    // Sending email.
    err = smtp.SendMail(smtpHost+":"+smtpPort, auth, from, to, body.Bytes())
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println("Email Sent!")
}

使用以下模板作为奖励:)

<!-- template.html -->
<!DOCTYPE html>
<html>
<body>
    <h3>Name:</h3><span>{{.Name}}</span><br/><br/>
    <h3>Email:</h3><span>{{.Message}}</span><br/>
</body>
</html>

gomail 实体库负责处理所有这些:

package main

import (
    "io"
    "text/template"

    "github.com/go-gomail/gomail"
)

func main() {

    // Sender data.
    from := "Office 365 login name"
    password := "Office 365 password"
    smtpHost := "smtp.office365.com"
    smtpPort := 587

    m := gomail.NewMessage()
    m.SetHeader("From", "sendor@company.com")
    m.SetHeader("To", "r1@company.com", "r2@company.com")
    m.SetAddressHeader("Cc", "cc1@company.com", "Dan")
    m.SetHeader("Subject", "Hello!")
    //  m.SetBody("text/html", "Hello <b>Bob</b> and <i>Cora</i>!")
    //  m.SetBody("text/plain", "Hello Bob and Cora!")
    m.Attach("template.html")

    t, _ := template.ParseFiles("template.html")
    m.AddAlternativeWriter("text/html", func(w io.Writer) error {
        return t.Execute(w, struct {
            Name    string
            Message string
        }{
            Name:    "Hasan Yousef",
            Message: "This is a test message in a HTML template",
        })
    })

    d := gomail.NewDialer(smtpHost, smtpPort, from, password)

    // Send the email to Bob, Cora and Dan.
    if err := d.DialAndSend(m); err != nil {
        panic(err)
    }
}

【讨论】:

  • 那么解决方案到底是什么?您基本上只是在帖子中添加了一堆代码。目前尚不清楚是什么改变使问题消失了。附带说明一下,考虑使用标准包中的 mimenet/textproto 包,而不是手工制作消息头(一旦您需要在其中放置非 ASCII 字母,它就会中断)。
猜你喜欢
  • 2022-09-24
  • 1970-01-01
  • 1970-01-01
  • 2022-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-04
  • 1970-01-01
相关资源
最近更新 更多