Go:实现SMTP邮件发送订阅功能(包含163邮箱、163企业邮箱、谷歌gmail邮箱)

需求很简单,就是用户输入自己的邮箱后,使用官方邮箱给用户发送替邮件模版

在这里插入图片描述

目录

  • 前置
    • 邮件模版
    • 邮箱开启SMTP服务
      • 163邮箱
      • 163企业邮箱
      • 谷歌gmail邮箱
      • 腾讯企业邮箱-失败
      • 其他邮箱-未操作
  • 邮件发送核心代码
    • config.yaml配置
    • 读取邮件相关配置
    • 发送邮件
  • 附录

前置

邮件模版

邮件模版类似如下图发来的欢迎加入的模版
在这里插入图片描述

这里我们使用html格式存储模版,上图源码如下

<html lang="en-US" xmlns:th="http://www.w3.org/1999/xhtml">
<head><meta charset="UTF-8"><title>email</title><style>a{color: #ECC94B !important;}.foot-text{color: rgba(0, 0, 0, 0.50) !important;}.im{color:rgba(0,0,0,0.86) !important;}.center {display: flex;justify-content: center;align-items: center;}</style>
</head>
<body style="background-color: white;">
<div style="width: 640px;height: auto;border-radius: 5px;margin: 0 auto;position: relative; padding-bottom: 80px; padding-top: 20px"><div><img width="640" src="file:///Users/yanzhixing/Downloads/My/文档/HatchfulExport-All/linkedin_banner_image_2.png" alt=""></div><div style="color: rgba(0,0,0,0.86);font-family: 'Roboto','Century Gothic', 'Trebuchet MS', 'Hiragino Sans GB', 微软雅黑, 'Microsoft Yahei', Tahoma, Helvetica, Arial, 'SimSun', sans-serif;font-size: 16px;margin: 10px auto 0px"><h2 style="font-size: 20px;font-weight: 700; color: #000">Dear KunZhi Fans,</h2><div><p style="margin: 16px 0; ">Welcome to the family! We are glad to have you on board as a subscriber to my blog.</p ><p style="font-weight: 600; color: #000;">Get the latest on <a style="color: #000" href="https://kunzhi.blog.csdn.net/">CSDN</a> and give me a follow if you haven't already.</p><p style="margin: 16px 0"><p style="font-weight: 600; color: #000">🧑🏻 About Me</p><p style="margin-bottom: 8px">Former Alibaba programmer, now working for a blockchain company. He is a blogger in the domestic Internet circle, an expert blogger on Alibaba Cloud, and the manager of CSDN Hangzhou City Community. Welcome to communicate and win-win cooperation.</p></p ><div style="margin: 16px 0"><p style="font-weight: 600; color: #000;">📇 Contact Me</p><p style=" margin-bottom: 8px">Should you have any questions, require assistance, or want to dive deeper into any aspect, you can reach out to me through various channels:</p><div><p style="margin-bottom: 0; display: flex; margin-bottom: 4px"><span style="margin: 0 8px"></span><span>Wechat: Follow me <a style="color: #ECC94B;text-decoration: none " target="_blank">kunzhi96</a> to communicate and learn together.</span><div class="center"><img width="200" src="file:///Users/yanzhixing/Downloads/My/私人/微信二维码.png" alt=""></div></p><p style="margin: 0; display: flex; margin-bottom: 4px"><span style="margin: 0 8px"></span><span>CSDN Blog: Visit my blog -<a style="color: #ECC94B; text-decoration: none" target="_blank" href="https://kunzhi.blog.csdn.net/">鲲志说</a> for in-depth information about my learning content and technology sharing.</span></p><p style="margin: 0; display: flex; margin-bottom: 4px"><span style="margin: 0 8px"></span><span> Email: Feel free to contact us via email at <span style="color: #ECC94B; opacity: 1;">XXX@163.com</span> for any inquiries, feedback, or support needs.</span></p></div><p style="margin-bottom: 0px">I'm excited to embark on this journey with you.</p></div ><p>Warm regards,</p><p>Kun Zhi</p><div style="background-color: #F7F7F7; padding: 40px; text-align:center;"><p style="font-size: 24px;font-weight: 700; color: #000;  margin-bottom: 24px; margin-top: 0">KunZhi</p><p style="margin-bottom: 8px; margin-top: 0">This email was send to <span style="color: #ECC94B; opacity: 1;">xxx@gmail.com</span></p><p style="margin-bottom: 24px; margin-top: 0">You’ve received it because you’ve subscribed to our newsletter.</p><div><a style="color: rgba(0, 0, 0, 0.50); text-decoration: underline" href="unsubscribe_url/unsubscribe?email=unsubscribe_email" class="foot-text">Unsubscribe</a></div></div></div></div>
</div>
</body>
</html>

邮箱开启SMTP服务

选择好官方邮箱来开启smtp服务,这里我测试验证了163邮箱、163企业邮箱、谷歌gmail邮箱和腾讯企业邮箱(但腾讯企业邮箱未成功,后续会说明)

163邮箱

  1. 登录163邮箱(一定不要登录到简易版啊)

  2. 登录后如下图所示,点击上面导航栏的设置
    在这里插入图片描述

  3. 按照下图顺序点击 POP3/SMTP/IMAP
    在这里插入图片描述

  4. 开启SMTP服务

如下图我已经是开启状态了
在这里插入图片描述
5. 新增授权密码
如上图,我们如果需要使用SMTP服务,就一定要使用授权码,而且这个密码只出现一次,一定要记得保存好,保存好先留着,我们后面会用到

6.服务器地址及端口

我们使用的是SMTP服务,则对应的服务器地址是smtp.163.com,端口为25,后面都会用到
在这里插入图片描述

自此,163邮箱的smtp服务开启完毕,可直接跳到邮件发送源码处继续即可


163企业邮箱

  1. 登录163企业邮箱

可以看到登录的是网易灵犀办公界面
在这里插入图片描述

  1. 登录后如下图所示,点击上面导航栏的设置-账号与安全-客户端设置
    在这里插入图片描述
  2. 进入客户端设置

可看到如下图

  • 选择IMAP协议
  • 开启并设置客户端授权密码
    在这里插入图片描述
  1. 新增授权密码
    如上图,生成授权码,而且这个密码只出现一次,一定要记得保存好,保存好先留着,我们后面会用到。

可以看到163企业邮箱不同的是,有一个到期时间,也就意味着,到期了,我们需要更换授权码,这一点需要谨记

  1. 服务器地址及端口

我们使用的是SMTP服务,则对应的服务器地址是smtphz.qiye.163.com,端口为25,后面都会用到
在这里插入图片描述

自此,163企业邮箱的smtp服务开启完毕,可直接跳到邮件发送源码处继续即可


谷歌gmail邮箱

  1. 登录 谷歌gmail邮箱
  2. 点击设置-查看所有设置
    在这里插入图片描述
  3. 点击转发和 POP/IMAP 标签页,如下图进行启用设置,并保存更改
    在这里插入图片描述
  4. 创建和使用应用专用密码
  • 前往您的 Google 帐号-选择安全性

  • 在“登录 Google”下方,选择两步验证
    在这里插入图片描述

  • 在页面底部,选择应用专用密码,进行点击
    在这里插入图片描述

  • 输入一个名称,以帮助您记住在什么情况下使用应用专用密码,如我的kunzhi-test
    在这里插入图片描述

  • 选择创建后,会出现如下弹窗。设备的应用专用密码即生成了,是指在设备上生成的 16 个字符的代码。也就是授权码,而且这个密码只出现一次,一定要记得保存好,保存好先留着,我们后面会用到。在这里插入图片描述

  • 选择完成,记得应用名称对应的密码即可
    在这里插入图片描述

  1. 服务器地址及端口

我们使用的是SMTP服务,则对应的服务器地址是smtp.gmail.com,端口为587,后面都会用到
在这里插入图片描述
自此,谷歌gmail邮箱的smtp服务开启完毕,可直接跳到邮件发送源码处继续即可


腾讯企业邮箱-失败

腾讯企业邮箱失败的原因是因为一直没有找到授权码在哪里进行设置,同时使用邮箱的密码作为授权码也无法发送邮件,所以一直没有实现,但是前面的操作步骤可以放出来供大家参考,如果有人找到了腾讯企业邮箱的操作方法请一定要评论区给出解法。

  • 企业微信管理后台

  • 开启腾讯企业邮箱的POP/SMTP/IMAP服务
    在这里插入图片描述

  • 企业邮箱服务器及端口号设置

其他邮箱-未操作

这个链接的操作我并未实际执行,需要的可以参考

  • 发件服务设置-包含:阿里云邮箱设置、Outlook邮箱设置

邮件发送核心代码

config.yaml配置

这里是发送邮件的邮箱相关配置,这里就使用到之前只出现一次的授权码了,以及对应的服务器地址和端口

email:
# 163邮箱template_dir: /test.htmlsmtp_server: smtp.163.comsmtp_port: 25smtp_user: KunZhismtp_password: 授权码from_email: XXXX@163.com# 腾讯企业邮箱# smtp_server: smtp.exmail.qq.com# smtp_port: 465# smtp_user: KunZhi# smtp_password: 授权码# from_email: XXXX# 163企业邮箱# smtp_server: smtphz.qiye.163.com# smtp_port: 25# smtp_user: KunZhi# smtp_password: 授权码# from_email: XXXX# gmail
#   smtp_server: smtp.gmail.com
#   smtp_port: 587
#   smtp_user: KunZhi
#   smtp_password: 授权码
#   from_email: XXXX@gmail.com

这里的smtp_user如下图,就是展示的发件人名称
在这里插入图片描述

读取邮件相关配置

	//读取邮件相关配置err = sendWelcomeEmail(Cfg{SenderAddress:  viper.GetString("email.from_email"),SenderName:     viper.GetString("email.smtp_user"),SenderPwd:      viper.GetString("email.smtp_password"),MailServerHost: viper.GetString("email.smtp_server"),MailServerPort: viper.GetString("email.smtp_port"),}, viper.GetString("email.from_email"), toEmail, unsubscribeUrl)if err != nil {errors.Errorf("Failed to send email: ", toEmail, err)responseData := gin.H{"message": "Failed to send email: " + toEmail,"code":    -1,}c.JSON(http.StatusOK, responseData)return err}

发送邮件


func sendWelcomeEmail(cfg Cfg, template string, recipientEmail, unsubscribeUrl string) error {currentDir, err2 := os.Getwd()if err2 != nil {log.Fatalf("Failed to get current working directory: %v", err2)}//获取邮件模版htmlContent, err3 := ioutil.ReadFile(currentDir + viper.GetString("email.template_dir"))if err3 != nil {fmt.Println("Failed to read HTML file:", err3)return err3}// 邮件标题subject := "Your Journey Begins Here"message := string(htmlContent)// 需要替换邮件模版中的字符串映射replacements := map[string]string{"xxx@gmail.com":     recipientEmail,"header_img":        viper.GetString("img.header_img"),}// 替换字符串for oldStr, newStr := range replacements {message = strings.Replace(message, oldStr, newStr, -1) // -1 表示替换所有匹配项}// 连接到 SMTP 服务器并发送电子邮件auth := smtp.PlainAuth("", cfg.SenderAddress, cfg.SenderPwd, cfg.MailServerHost)to := []string{recipientEmail}msg := []byte("To: " + recipientEmail + "\r\n" +"Subject: " + subject + "\r\n" +"From: " + cfg.SenderName + " <" + cfg.SenderAddress + ">\r\n" +"MIME-Version: 1.0\r\n" +"Content-Type: text/html; charset=utf-8\r\n" + // 将内容类型设置为 HTML"\r\n" + message)//发送邮件err := smtp.SendMail(cfg.MailServerHost+":"+cfg.MailServerPort, auth, cfg.SenderAddress, to, msg)if err != nil {fmt.Println("failed to send email:", err)return err}return nil
}

如上代码,可以实现SMTP邮件发送订阅功能,如有任何问题欢迎私聊或评论区留言


附录

  • 163帮助中心
  • 163邮箱无法发送邮件发生退信问题 550 User has no permission以及554, DT:SPM的解决办法
  • 163企业邮箱帮助中心-灵犀办公客户端的设置方法
  • 谷歌邮箱-使用应用专用密码登录

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/96443.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++中迭代器的使用

C中的迭代器是一种用于遍历容器&#xff08;如数组、向量、列表、映射等&#xff09;中元素的工具。迭代器提供了一种通用的方式来访问容器中的数据&#xff0c;而不依赖于容器的具体实现。 以下是C中迭代器的基本使用方法和示例&#xff1a; 1.迭代器类型&#xff1a; C标准…

使用关键字interface来声明使用接口-PHP8知识详解

继承特性简化了对象、类的创建&#xff0c;增加了代码的可重用性。但是php8只支持单继承&#xff0c;如果想实现多继承&#xff0c;就需要使用接口。PHP8可以实现多个接口。 接口类通过关键字interface来声明&#xff0c;接口中不能声明变量&#xff0c;只能使用关键字const声明…

tcpdump(一)基础理论知识

一 抓包分析技术初探 说明&#xff1a; 本篇章跟tcp/ip的知识没有关系,只是讲解tcpdump工具背景补充&#xff1a; 抓包是做报文分析的第一步敬畏心&#xff1a; 隔行如隔山,不要想当然 ① 背景 ② 抓包技术名词 1、捋顺这些技术的来龙去脉甚至八卦;2、这样我们在后续课程…

绘制散点图、曲线图、折线图和环形图失败, 设置迭代次数和进度无法保存图片

错误❌ 分别input设置&#xff08;我想知道微积分的力量&#xff09; 设1个人&#xff0c;他有每天3种方案&#xff0c;每天进步千分之一&#xff0c;千分之一&#xff0c;十万分之一等到他们迭代 200,500,1000,2000,3000,5000,9000次 他们在图片什么位置画曲线图&#xff0…

QGIS文章五——对遥感影像进行土地类型分类-选择遥感影像

关于下载遥感影像的地方有很多&#xff1a; 1、国家综合地球观测数据共享平台&#xff08;https://www.chinageoss.cn/&#xff09; 2、地理空间数据云&#xff08;https://www.gscloud.cn/&#xff09; 3、美国地质勘探局官网&#xff08;https://earthexplorer.usgs.gov/&…

MD5玩翻车了-0缺失

废话背景&#xff1a; 跟别人集成免密登录&#xff0c;用到了MD5加密&#xff0c;做好的数据偶尔行&#xff0c;偶尔不行&#xff0c;深刻怀疑别人代码有问题。&#xff08;从不怀疑自己&#xff09;&#xff0c;理直气壮的找了别个对接人好几次。最后发现自己做的MD5位数不对…

flutter中使用缓存

前言 在flutter项目中使用ListView或者PageView等有滚动条组件的时候&#xff0c;切换页面的时候&#xff0c;再切换回来会丢失之前的滑动状态&#xff0c;这个时候就需要需要使用缓存功能 缓存类 import package:flutter/material.dart;class KeepAliveWrapper extends Sta…

【Luogu】 P4649 [IOI2007] training 训练路径

题目链接 点击打开链接 题目解法 好神仙的题啊&#xff01;&#xff01;&#xff01; 首先一个合法的选路径方案等价于没有偶环出现 我们先判掉和树边能组成偶环的非树边 然后考虑一个结论是&#xff1a;如果有一条边被两个偶环都经过了一次&#xff0c;那么这个方案不合法 …

线性调频雷达简介

一、频率调制模式 Chirp雷达是脉冲雷达的统称,其中发射的脉冲是脉冲内调制的。这可以是脉冲上的频率调制(FMOP)或脉冲上的相位调制(PMOP)。发射的脉冲较长,但具有与脉冲功率高得多的短脉冲相同的能量含量 图1 线性频率调制 FMOP可能是: 线性频率调制– up-chirp – dow…

在Flink中集成和使用Hudi

本文介绍在Flink 中集成和使用Hudi。介绍Flink如何将Streaming引入Hudi。在Hudi上使用Flink,并学习Flink读写Hudi的不同模式: Flink SQL客户端写入:Flink SQL客户端写入(读取)Hudi。 配置:对于全局配置,通过$FLINK_HOME/conf/FLINK-conf.yaml进行设置。对于每个作业配置…

服务器挂机

title: “linux好玩的” createTime: 2021-05-27T10:09:5308:00 updateTime: 2021-05-27T10:09:5308:00 draft: false author: “xcb” tags: [“linux”,“tar”] categories: [“linux”] keywords: [“linux”] description: “测试的” linux 好玩 压缩 tar -zcvf soft.…

目标识别项目实战:基于Yolov7-LPRNet的动态车牌目标识别算法模型(二)

前言 目标识别如今以及迭代了这么多年&#xff0c;普遍受大家认可和欢迎的目标识别框架就是YOLO了。按照官方描述&#xff0c;YOLOv8 是一个 SOTA 模型&#xff0c;它建立在以前 YOLO 版本的成功基础上&#xff0c;并引入了新的功能和改进&#xff0c;以进一步提升性能和灵活性…

零基础如何自学网络安全,基于就业前景全方位讲解,包教包会

你是否对网络空间安全充满好奇&#xff1f;想要解开网络世界神秘的面纱&#xff1f;你是否对黑客技术着迷&#xff1f;而找不到合适的学习途径&#xff1f;你是否遭到过各种各样的网络攻击&#xff0c;却因知识的匮乏束手无策&#xff1f; 那么接下来将为你全面介绍&#xff0c…

优化器optimizer

用来更新和计算影响模型训练和模型输出的网络参数,使其逼近或达到最优值,从而最小化(或最大化)损失函数。 总结 从SGD到Adam做了哪些改进自适应的学习率、动量 从SGD到Adam做了哪些改进Adamw 即 Adam + weight decate ,效果与 Adam + L2正则化相同,但是计算效率更高,因为L2正则…

css--踩坑

1. 子元素的宽高不生效问题 设置flex布局后&#xff0c;子元素的宽高不生效问题。 如果希望子元素的宽高生效&#xff0c;解决方法&#xff0c;给子元素添加如下属性&#xff1a; flex-shrink: 0; flex-shrink: 0;2. 横向滚动&#xff08;子元素宽度不固定&#xff09; /* tab…

Centos7升级OpenSSH9.1

最近遇到了服务器漏洞&#xff0c;需要对服务器的OpenSSH版本进行升级&#xff0c;查阅了相关资料&#xff0c;总结出了一套比较简单的方案。中间遇到的个别问题也进行了记录&#xff0c;供大家参考。 下载准备 从https://ftp.jaist.ac.jp/pub/OpenBSD/OpenSSH/portable/opens…

mysql 逻辑备份 恢复数据

一、逻辑备份 逻辑备份&#xff1a;备份的是建表&#xff0c;建库&#xff0c;插入数据等操作所执行SQL语句&#xff0c;适用于中小型数据库&#xff0c;效率相对较低&#xff0c;提供三种级别的备份&#xff0c;表级&#xff0c;库级和全库级。 本质&#xff1a;导出的是SQL语…

【外汇天眼】携手共护外汇投资:2023年WikiFX晚宴首次在越南圆满举行

9月23日&#xff0c;WikiFX在越南与Wsaas合作举办了一场晚宴&#xff0c;以此表达对合作伙伴的感谢。此次晚会不仅仅是各位行业精英聚一起分享经验、了解行业动向的机会&#xff0c;也是WikiFX在越南分部第一次思考与复盘的活动。 回顾过去——WikiFX在越南的四年 从2019年开始…

linearlayout中使用多个weight导致部分子控件消失异常

问题描述&#xff1a; 在一个linearlayout中写了两个用到weight的布局&#xff0c;在androidstudio中显示正常 但是代码跑起来之后最下面哪一行都消失了&#xff1b; 解决办法1 把两个用到weight的改成一个了&#xff0c;外面那层的weight写成固定宽度就能正常显示出丢失的…