golang--自动下载邮件的附件

这个是之前做的一个小应用,主要用到的是golang的go-imap这个库。之前看到php和java都有完整的自动下载邮件的程序,现在也分享一个golang的,其中主要麻烦的是判断邮件的状态,是否未读,然后就是获取附件并且下载,具体代码如下:

package main

import (
	"io"
	"io/ioutil"
	"log"

	"os"

	"github.com/emersion/go-imap"
	"github.com/emersion/go-imap/client"
	"github.com/emersion/go-message/mail"
)

/*
	函数名称:mk_dir
	函数作用:新建目录
	输入参数:dir_path(目录路径)
	输出参数:新建目录路径
*/

func mk_dir(dir_path string) string {
	var path string
	if os.IsPathSeparator('\\') { //前边的判断是否是系统的分隔符
		path = "\\"
	} else {
		path = "/"
	}
	//fmt.Println(path)
	dir, _ := os.Getwd()                            //当前的目录
	err := os.Mkdir(dir+path+dir_path, os.ModePerm) //在当前目录下生成md目录
	if err != nil {
		log.Println(err)
	}
	return dir + path + dir_path
}

/*
	函数名称:checkFileIsExist
	函数作用:检查文件是否存在,不存在则新建文件
	输入参数:filename(文件名)
	输出参数:是否新建成功
*/
func checkFileIsExist(filename string) bool {
	var exist = true
	if _, err := os.Stat(filename); os.IsNotExist(err) {
		exist = false
	}
	return exist
}

/*
	函数名称:write_to_file
	函数作用:写内容到文件
	输入参数:filename(文件名),content(内容)
	输出参数:无
*/

func write_to_file(filename string, content string) {
	var f *os.File
	var err error
	if checkFileIsExist(filename) { //如果文件存在
		f, err = os.OpenFile(filename, os.O_APPEND, 0666) //打开文件
		log.Println("文件存在")
	} else {
		f, err = os.Create(filename) //创建文件
		log.Println("文件不存在")
	}
	check_error(err)
	_, err = io.WriteString(f, content) //写入文件(字符串)
	check_error(err)
}

/*
	函数名称:check_error
	函数作用:捕抓错误
	输入参数:error
	输出参数:无
*/
func check_error(e error) {
	if e != nil {
		log.Fatal(e)
	}
}
func main() {
	arg_num := len(os.Args)
	if arg_num != 3 {
		log.Println("参数有错,请以此输入邮箱名称和密码,如./download.exe 123@qq.com 123123123")
		return
	}

	log.Println("Connecting to server...")

	// 连接服务器
	c, err := client.DialTLS("imap.qq.com:993", nil)
	check_error(err)
	log.Println("连接服务器")

	// 结束后退出登录
	defer c.Logout()

	// 登录
	//args[1]是用户名,args[2]是imap密码
	if err := c.Login(os.Args[1], os.Args[2]); err != nil {
		log.Fatal(err)
	}
	log.Println("登陆邮箱")

	// 获取邮箱列表
	mailboxes := make(chan *imap.MailboxInfo, 10)
	done := make(chan error, 1)
	go func() {
		done <- c.List("", "*", mailboxes)
	}()

	log.Println("邮箱列表:")
	for m := range mailboxes {
		log.Println("* " + m.Name)
	}

	if err := <-done; err != nil {
		log.Fatal(err)
	}

	// 选择收件箱
	mbox, err := c.Select("INBOX", false)
	if err != nil {
		log.Fatal(err)
	}

	from := uint32(1)
	to := mbox.Messages
	seqset := new(imap.SeqSet)
	seqset.AddRange(from, to)
	attrs := []string{"BODY[]", imap.FlagsMsgAttr}
	messages := make(chan *imap.Message, 10)
	done = make(chan error, 1)
	go func() {
		done <- c.Fetch(seqset, attrs, messages)
	}()

	for msg := range messages {
		//判断是否未读邮件
		if len(msg.Flags) == 0 {
			r := msg.GetBody("BODY[]")
			if r == nil {
				log.Fatal("Server didn't returned message body")
			}

			mr, err := mail.CreateReader(r)
			if err != nil {
				log.Fatal(err)
			}
			header := mr.Header
			//获取邮件日期
			mail_date, errs := header.Date()
			check_error(errs)
			for {
				p, err := mr.NextPart()
				if err == io.EOF {
					break
				} else if err != nil {
					log.Fatal(err)
				}
				//提取邮件的附件
				switch h := p.Header.(type) {
				case mail.TextHeader:
					log.Println("just mail")
				case mail.AttachmentHeader:
					filename, _ := h.Filename()
					log.Println("Got attachment: %v", filename)
					dir := mk_dir(mail_date.Format("01-02-2006"))
					filename = dir + "\\" + filename
					content, _ := ioutil.ReadAll(p.Body)
					write_to_file(filename, string(content))

				}
			}
		} else {
			log.Println("已读邮件")
		}

	}

	if err := <-done; err != nil {
		log.Fatal(err)
	}

}

当然这已经2021年底了,上面的代码有些已经过时了,参照下面的改一下吧。

参考网址:

github.com/emersion/go-imap怎么获取邮件正文和附件 - Go语言中文网 - Golang中文社区

https://github.com/emersion/go-imap/wiki/Fetching-messages

package main

import (
	"io"
	"io/ioutil"
	"log"
	
	"github.com/emersion/go-imap"
	"github.com/emersion/go-imap/client"
	"github.com/emersion/go-message/mail"
)

func main() {
	// Let's assume c is a client
	var c *client.Client

	// Select INBOX
	mbox, err := c.Select("INBOX", false)
	if err != nil {
		log.Fatal(err)
	}

	// Get the last message
	if mbox.Messages == 0 {
		log.Fatal("No message in mailbox")
	}
	seqSet := new(imap.SeqSet)
	seqSet.AddNum(mbox.Messages)

	// Get the whole message body
	var section imap.BodySectionName
	items := []imap.FetchItem{section.FetchItem()}

	messages := make(chan *imap.Message, 1)
	go func() {
		if err := c.Fetch(seqSet, items, messages); err != nil {
			log.Fatal(err)
		}
	}()

	msg := <-messages
	if msg == nil {
		log.Fatal("Server didn't returned message")
	}

	r := msg.GetBody(&section)
	if r == nil {
		log.Fatal("Server didn't returned message body")
	}

	// Create a new mail reader
	mr, err := mail.CreateReader(r)
	if err != nil {
		log.Fatal(err)
	}

	// Print some info about the message
	header := mr.Header
	if date, err := header.Date(); err == nil {
		log.Println("Date:", date)
	}
	if from, err := header.AddressList("From"); err == nil {
		log.Println("From:", from)
	}
	if to, err := header.AddressList("To"); err == nil {
		log.Println("To:", to)
	}
	if subject, err := header.Subject(); err == nil {
		log.Println("Subject:", subject)
	}

	// Process each message's part
	for {
		p, err := mr.NextPart()
		if err == io.EOF {
			break
		} else if err != nil {
			log.Fatal(err)
		}

		switch h := p.Header.(type) {
		case *mail.InlineHeader:
			// This is the message's text (can be plain-text or HTML)
			b, _ := ioutil.ReadAll(p.Body)
			log.Println("Got text: %v", string(b))
		case *mail.AttachmentHeader:
			// This is an attachment
			filename, _ := h.Filename()
			log.Println("Got attachment: %v", filename)
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值