首页 > 解决方案 > 发送 Office 365 电子邮件

问题描述

我有下面的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但不知道如何将它合并到我的代码中?

标签: go

解决方案


我找到了正确的答案,为了社区的利益在这里分享:

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)
    }
}

推荐阅读