邮件推送 Go 调用示例

以下代码示例,Go 语言(版本为1.16)通过 SMTP 发送邮件:1. 目前服务端支持的 SSL 协议和加密套件如下,请选择适合的 SSL 版本:ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM。

相关产品
邮件推送 产品页,含版本规格、价格与购买入口。

以下代码示例,Go 语言(版本为1.16)通过 SMTP 发送邮件:1. 目前服务端支持的 SSL 协议和加密套件如下,请选择适合的 SSL 版本:ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM。

以下代码示例,Go 语言(版本为1.16)通过 SMTP 发送邮件:1. 目前服务端支持的 SSL 协议和加密套件如下,请选择适合的 SSL 版本:ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:RC4-MD5:RC4-SHA;2. 服务地址和端口请参见 SMTP 服务地址。以下是代码示例:// Package main 提供腾讯云邮件推送(SES)SMTP 协议发信的 Go 语言示例。//// 本代码演示了如何通过 SMTP 协议(端口 465,SSL/TLS 加密)向腾讯云邮件推送服务// 发起发信请求。整体流程分为以下几步:// 1. 准备发信参数(发信人、收件人、抄送、密送、主题、正文等);// 2. 按 RFC 822 格式拼装邮件 Header 与 Body(Body 使用 Base64 编码);// 3. 通过 tls.Dial 与 SMTP 服务器建立加密连接;// 4. 通过 PlainAuth 完成身份认证;// 5. 依次执行 MAIL FROM、RCPT TO、DATA 等 SMTP 命令完成投递。//// 使用前请先在腾讯云邮件推送控制台完成以下准备工作:// – 创建并验证发信域名(Sender Domain);// – 创建发信地址(Sender Address),并开启 SMTP 发信;// – 在控制台「SMTP 密码」处生成专用密码(注意:不是腾讯云账号密码);// – 确认发信地址有可用的发信额度。//// 依赖:标准库 net/smtp、crypto/tls,无需引入第三方包。package mainimport ( "crypto/tls" "encoding/base64" "fmt" "log" "net" "net/smtp")// Test465 演示通过 465 端口(SSL/TLS)发送一封 HTML 格式邮件。//// 流程:// 1. 配置 SMTP 服务器地址、端口、发信账号、SMTP 密码;// 2. 构造邮件头(From / To / Cc / Bcc / Subject / Content-Type 等);// 3. 将邮件正文 Base64 编码后拼接到 Header 之后(Header 与 Body 之间需要一个空行);// 4. 使用 smtp.PlainAuth 创建 PLAIN 认证对象;// 5. 调用 SendMailWithTLS 通过 TLS 连接完成投递。//// 返回值:发送成功返回 nil,失败返回具体错误。func Test465() error { // SMTP 服务器地址,腾讯云邮件推送固定为 smtp.qcloudmail.com host := "smtp.qcloudmail.com" // SMTP 端口:465 表示 SSL/TLS 加密连接; // 如需使用 STARTTLS,可改为 25 端口,但代码中的 tls.Dial 也需相应调整为 net.Dial + StartTLS。 port := 465 // email:控制台创建并验证通过的发信地址(Sender Address),必须与 SMTP 密码所属账号一致。 email := "abc@cd.com" // password:在控制台「SMTP 设置」中为该发信地址单独生成的 SMTP 密码, // 不是腾讯云账号登录密码,也不是 API 密钥。 password := "****" // 收件人地址(必填,至少一个) toEmail := "test@test123.com" // 抄送地址(可选) ccEmail := "cc@test123.com" // 密送地址(可选) bccEmail := "bcc@test123.com" // 构造邮件 Header。SMTP 协议要求 Header 字段以 "Key: Value\\r\\n" 形式书写, // 所有 Header 结束后需要一个空行("\\r\\n")再跟 Body。 header := make(map[string]string) // From 推荐写成 "显示名 <发信地址>" 的形式,显示名会作为收件箱中展示的发件人昵称。 header["From"] = "test " + "<" + email + ">" header["To"] = toEmail header["Cc"] = ccEmail header["Bcc"] = bccEmail // 邮件主题;如包含中文,建议进行 RFC 2047 编码(=?UTF-8?B?…?=),本示例为纯英文示例所以未编码。 header["Subject"] = "test subject" // Content-Type 指定正文类型为 HTML,并声明字符集为 UTF-8。 header["Content-Type"] = "text/html; charset=UTF-8" // Content-Transfer-Encoding 指定正文的传输编码方式,这里用 base64 // 可避免中文/特殊字符在 SMTP 传输过程中被截断或损坏。 header["Content-Transfer-Encoding"] = "base64" // HTML 格式正文示例 body := "<!DOCTYPE html>\\n<html>\\n<head>\\n<meta charset=\\"utf-8\\">\\n<title>hello world</title>\\n</head>\\n<body>\\n " + "<h1>我的第一个标题</h1>\\n <p>我的第一个段落。</p>\\n</body>\\n</html>" // 如需发送纯文本邮件,可注释掉上面的 HTML 配置,并启用以下两行: //header["Content-Type"] = "text/plain; charset=UTF-8" //body := "test body" // 拼装最终的 SMTP 报文:先把 Header 全部拼成 "Key: Value\\r\\n", // 再用空行分隔,最后接上 Base64 编码后的 Body。 message := "" for k, v := range header { message += fmt.Sprintf("%s: %s\\r\\n", k, v) } message += "\\r\\n" + base64.StdEncoding.EncodeToString([]byte(body)) // 创建 PLAIN 认证对象。 // 第 1 个参数 identity 通常留空,第 2 个为用户名(即发信地址), // 第 3 个为 SMTP 密码,第 4 个为 host(用于服务端校验)。 auth := smtp.PlainAuth( "", email, password, host, ) // 调用 TLS 版发信函数,传入服务器地址、认证对象、发件人、收件人列表与原始报文。 // 注意:to 列表用于 SMTP 的 RCPT TO 命令,决定邮件实际投递到哪些邮箱; // 如需让抄送/密送真实收到邮件,必须把 ccEmail / bccEmail 也加入此列表。 err := SendMailWithTLS( fmt.Sprintf("%s:%d", host, port), auth, email, []string{toEmail}, []byte(message), ) if err != nil { fmt.Println("Send email error:", err) } else { fmt.Println("Send mail success!") } return err}// Dial 与 SMTP 服务器建立 TLS 加密连接,并返回一个可用的 *smtp.Client。//// 参数:// – addr:服务器地址,格式为 "host:port",例如 "smtp.qcloudmail.com:465"。//// 说明:// – 标准库 smtp.Dial 默认使用明文连接,对于 465 端口必须先建立 TLS 通道再封装成 SMTP 客户端,// 因此本函数使用 tls.Dial 替代 net.Dial。// – 第二个参数为 *tls.Config,传 nil 表示使用默认配置(会校验服务端证书)。// 如需跳过证书校验(不推荐生产使用),可传 &tls.Config{InsecureSkipVerify: true}。func Dial(addr string) (*smtp.Client, error) { conn, err := tls.Dial("tcp", addr, nil) if err != nil { log.Println("tls.Dial Error:", err) return nil, err } // smtp.NewClient 需要 host(不含端口)用于 EHLO/HELO 握手。 host, _, _ := net.SplitHostPort(addr) return smtp.NewClient(conn, host)}// SendMailWithTLS 通过 TLS 加密的 SMTP 连接完成一次完整的邮件投递。//// 参数:// – addr:SMTP 服务器地址,格式 "host:port"。// – auth:SMTP 认证对象,可由 smtp.PlainAuth 创建;如不需认证可传 nil。// – from:MAIL FROM 命令使用的发件人地址,应与认证账号一致。// – to: RCPT TO 命令使用的收件人列表,包含主送、抄送、密送的所有真实收件人。// – msg: 完整的邮件报文(Header + 空行 + Body),格式需符合 RFC 822。//// 处理步骤:// 1. 通过 Dial 建立 TLS + SMTP 连接;// 2. 若服务端支持 AUTH 扩展,则执行身份认证;// 3. 依次执行 MAIL FROM、RCPT TO、DATA 命令;// 4. 写入邮件正文并关闭数据流;// 5. 调用 QUIT 命令优雅关闭会话。//// 任何一步失败都会立即返回对应错误。func SendMailWithTLS(addr string, auth smtp.Auth, from string, to []string, msg []byte) (err error) { // 1. 建立 TLS 加密连接,得到 SMTP 客户端 c, err := Dial(addr) if err != nil { log.Println("Create smtp client error:", err) return err } // 确保连接最终被关闭,避免连接泄漏 defer c.Close() // 2. 如果传入了 auth,并且服务端通过 EHLO 声明支持 AUTH 扩展,则执行认证 if auth != nil { if ok, _ := c.Extension("AUTH"); ok { if err = c.Auth(auth); err != nil { log.Println("Error during AUTH", err) return err } } } // 3. 发送 MAIL FROM 命令,告知服务器发件人 if err = c.Mail(from); err != nil { return err } // 4. 依次发送 RCPT TO 命令,告知服务器每一个收件人 for _, addr := range to { if err = c.Rcpt(addr); err != nil { return err } } // 5. 发送 DATA 命令并获取写入流,用于写入邮件正文(Header + Body) w, err := c.Data() if err != nil { return err } _, err = w.Write(msg) if err != nil { return err } // 关闭写入流,标志正文输入结束(SMTP 协议中以 "\\r\\n.\\r\\n" 表示结束) err = w.Close() if err != nil { return err } // 6. 发送 QUIT 命令,与服务器优雅地结束会话 return c.Quit()}// main 是入口,直接调用 Test465 触发一次发信。// 实际接入业务时,建议把发信参数(账号、密码、收件人等)抽离为配置或函数入参,// 并对 Test465 中的错误进行更细粒度的处理与重试。func main() { Test465()}

赞 (0)
上一篇 4天前
下一篇 4天前