• 邮件是什么?

  • 那么电子邮件又是个啥?

    • 电子邮件的优势是啥?

    • 电子邮件的形式是啥样的?

  • 邮件协议

  • 开始编码发邮件

    • 在 `QQ` 邮箱上面,拿到授权码

    • 编码,并安装`email` 邮件库

    • 发送`HTML`内容 + 附件

    • 如何提高发送邮件的性能

  • 总结

  • 欢迎点赞,关注,收藏


我们一起来回顾一下上一次咱们说到的GO 的验证码案例

  • 验证码种类梳理

  • 验证码库的安装

  • 验证码库的源码介绍

  • 实操,编码

  • 验证码效果展示

想看看GO 咋做验证码的,欢迎查看文章  GO 的验证码案例

生活和工作中,咱们都离不开邮件的收发,要么在手机上查收和发送,要么在自己的电脑前面进行邮件编辑和处理

可是,我们会发现,很多时候,某类邮件,咱们每天都必须要在同一个时刻发出去,并且内容也是大同小异的,

而且,有时候因为各种各种各样的原因,不能准时的发送邮件,这个时候,咱们如果可以写一个定制化的发送邮件的程序那可以说还是很香的

那么,咱们还是先来看看一些基本的常识吧

邮递国内邮件
信息交换

电子邮件依托于网络的电子邮件系统,有如下优势:

  • 价格非常低廉

不管发送到哪里,都只需负担网费

  • 传输快速

几秒钟之内可以发送到世界上任何指定的目的地,与世界上任何一个角落的网络用户联系

  • 文字

  • 图像

  • 声音等

想一想每次发邮件都需要经历如下的步骤

  • 打开电脑

  • 进入浏览器

  • 打开电子邮件

  • 新建 - 编辑 - 发送

大部分内容还是复制粘贴的,

GOLang

咱们使用编程语言需要遵守编程语言的规范,我们在浏览器里面浏览网页也是一样,需要遵循各种网络协议

那么,我们发送邮件的必须也要先知道有哪些邮件协议可以使用,咱们都来列举一下

  • SMTP

SMTP
SMTPTCP/IP
  • POP3

邮局协议的第3个版本,是因特网电子邮件的第一个离线协议标准

  • IMAP

POP
POPIMAP
IMAP

最终完成所有这些工作都不需要把邮件从服务器下载到用户的个人计算机上

OK,让我们开始进入到编码环节

SMTP
email
QQ
  • 下滑页面,看到 POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务

POP3/SMTPIMAP/SMTP
"github.com/jordan-wright/email"
 go get github.com/jordan-wright/email

不进行手动安装也没有问题,咱们可以现在看看 写一个初版的发送邮件小案例

package mainimport (   "github.com/jordan-wright/email"   "log"   "net/smtp")func main() {   // 简单设置 log 参数   log.SetFlags(log.Lshortfile | log.LstdFlags)   em := email.NewEmail()   // 设置 sender 发送方 的邮箱 , 此处可以填写自己的邮箱   em.From = "xx "       // 设置 receiver 接收方 的邮箱  此处也可以填写自己的邮箱, 就是自己发邮件给自己   em.To = []string{"xxx@qq.com"}       // 设置主题   em.Subject = "小魔童给你发邮件了"       // 简单设置文件发送的内容,暂时设置成纯文本   em.Text = []byte("hello world, 咱们用 golang 发个邮件!!")       //设置服务器相关的配置   err := e.Send("smtp.qq.com:25", smtp.PlainAuth("", "自己的邮箱账号", "自己邮箱的授权码", "smtp.qq.com"))   if err != nil {      log.Fatal(err)   }   log.Println("send successfully ... ")}

运行上述代码的效果如下:

2021/06/xx xx:36:28 main.go:28: send successfully ...

说明发送邮件成功了,咱们来看看我们的邮箱

果然是发送成功了 , 窃喜

html

好的安排

NewEmail
// NewEmail creates an Email, and returns the pointer to it.func NewEmail() *Email {   return &Email{Headers: textproto.MIMEHeader{}}}

这个指针是指向了一个邮件的数据结构,咱们一起来瞅瞅

// Email is the type used for email messagestype Email struct {   ReplyTo     []string       From        string  // 发送者   To          []string  // 接收者   Bcc         []string  // 密送   Cc          []string  // 抄送   Subject     string  // 主题   Text        []byte // Plaintext message (optional)     HTML        []byte // Html message (optional)   Sender      string // override From as SMTP envelope sender (optional)   Headers     textproto.MIMEHeader  // 协议头   Attachments []*Attachment    // 附件   ReadReceipt []string}
HTML
func main() {   // 简单设置l og 参数   log.SetFlags(log.Lshortfile | log.LstdFlags)   em := email.NewEmail()   //设置发送方的邮箱   em.From = "xx "   // 设置接收方的邮箱   em.To = []string{"xxx@qq.com"}   // 抄送   em.Cc = []string{"xxx@qq.com"}   // 密送   em.Bcc = []string{"xxx@qq.com"}   //设置主题   em.Subject = "小魔童给你发邮件了"   //设置文件发送的内容   em.HTML = []byte(`   

欢迎来到小魔童哪吒的主页


             1         GO 中 defer的实现原理                 2         GO 中 Chan 实现原理分享                 3         GO 中 map 的实现原理                 4         GO 中 slice 的实现原理                 5          GO 中 string 的实现原理                 6         GO 中 ETCD 的编码案例分享                 7         服务注册与发现之ETCD                 8          GO通道和 sync 包的分享                 9          GO的锁和原子操作分享    `)   // 添加附件   em.AttachFile("./test.html")   // 设置服务器相关的配置   err := e.Send("smtp.qq.com:25", smtp.PlainAuth("", "自己的邮箱账号", "自己邮箱的授权码", "smtp.qq.com"))   if err != nil {      log.Fatal(err)   }   log.Println("send successfully ... ")}

运行之后,咱们去查收一下邮件

HTML
get github.com/jordan-wright/email

我们都知道,建立连接是会耗费时间和资源的,咱们得尽可能的优化

再来一个DEMO,连接池的,咱们运用连接池,创建 一个 有 5 个缓冲的通道,让 3 个协程去通道里面获取数据,然后发送邮件

func main() {   // 简单设置l og 参数   log.SetFlags(log.Lshortfile | log.LstdFlags)   // 创建有5 个缓冲的通道,数据类型是  *email.Email   ch := make(chan *email.Email, 5)   // 连接池   p, err := email.NewPool(      "smtp.qq.com:25",      3, // 数量设置成 3 个      smtp.PlainAuth("", "自己的邮箱", "自己邮箱的授权码", "smtp.qq.com"),   )   if err != nil {      log.Fatal("email.NewPool error : ", err)   }    // sync 包,控制同步   var wg sync.WaitGroup   wg.Add(3)   for i := 0; i < 3; i++ {      go func() {         defer wg.Done()          // 若 ch 无数据,则阻塞, 若 ch 关闭,则退出循环         for e := range ch {            // 超时时间 10 秒            err := p.Send(e, 10*time.Second)            if err != nil {               log.Printf( "p.Send error : %v , e = %v , i = %d\n", err , e, i)            }         }      }()   }   for i := 0; i < 5; i++ {      e := email.NewEmail()      // 设置发送邮件的基本信息      e.From = "xx "      e.To = []string{"xxx@qq.com"}      e.Subject = "test email.NewPool " + fmt.Sprintf("  the %d email",i)      e.Text = []byte(fmt.Sprintf("test email.NewPool , the %d email !", i))      ch <- e   }   // 关闭通道   close(ch)   // 等待子协程退出   wg.Wait()   log.Println("send successfully ... ")}

运行上述代码后,咱们查看邮箱

咱们可以看到,邮件并不是按照顺序发送出来的,这就对了

sync
HTML

之前我们也简单分享了GOLANG如何发送邮件,大家可以对比一下,哪一种更加方便golang如何发送邮件(qq邮箱) |Go主题月

朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

好了,本次就到这里,下一次 分享一波GO的爬虫

技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是小魔童哪吒,欢迎点赞关注收藏,下次见~