go - 发送 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
但不知道如何将它合并到我的代码中?
解决方案
我找到了正确的答案,为了社区的利益在这里分享:
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)
}
}
推荐阅读
- laravel - Stripe PHP 使用 Stripe-cli 调试 SignatureVerificationException 的最佳方法
- sql - SQL 根据 id 获取值
- sqlite - SQlite FTS 表未填充
- javascript - 获取 node.js 服务器的公共 ssl 证书
- dart - 如果未将响应写入,共享 HTTP 服务器不处理
- c# - .NET Core 3.0 控制台应用程序无法读取文件,抛出 UnauthorizedAccessException
- azure - I can´t pull image from azure ACR
- ios - 缩略图图像不显示在 iPhone 或 iPad 上,但在 Android 上显示
- javascript - React - 打印导入组件函数的内容
- javascript - Highstock 显示不一致