一丶 参考
1.https://blog.csdn.net/Manrener/article/details/65437374?utm_source=blogxgwz5
2.https://github.com/emersion/go-imap
安装go-imap go-message
二丶解决邮件主题乱码的编码问题
subjectStr ,_:=charset.DecodeHeader(msg.Envelope.Subject)
三丶已读邮件删除-暂时 用了笨办法使用pop3登录在使用imap收取附件变成已读后,删除
参考地址:https://github.com/taknb2nch/go-pop3
package initial
import (
"fmt"
"github.com/emersion/go-imap"
"github.com/emersion/go-imap/client"
"github.com/emersion/go-message/charset"
"github.com/emersion/go-message/mail"
"github.com/taknb2nch/go-pop3"
"github.com/tryor/commons/ioutil"
"io"
"log"
"os"
"strconv"
"strings"
"time"
)
func InitTimer() {
timing();
}
func timing() {
//定时器,100秒钟执行一次
ticker := time.NewTicker(100 * time.Second)
for {
time := <-ticker.C
log.Println("定时器====>",time.String())
receiveFactoryMail()
}
}
/*
函数名称: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) bool{
var f *os.File
var err error
if checkFileIsExist(filename) { //如果文件存在
//f, err = os.OpenFile(filename, os.O_APPEND, 0666) //打开文件
log.Println("文件存在")
return false
} else {
f, err = os.Create(filename) //创建文件
log.Println("文件不存在")
err = os.Chmod(filename,0755)
}
check_error(err)
_, err = io.WriteString(f, content) //写入文件(字符串)
check_error(err)
return true
}
func check_error(e error) {
if e != nil {
log.Fatal(e)
}
}
func receiveFactoryMail() {
log.Println("Connecting to server...")
// 连接服务器
c, err := client.Dial("mail.XXX.com:8043")
check_error(err)
log.Println("连接服务器")
// 结束后退出登录
defer c.Logout()
// 登录
//args[1]是用户名,args[2]是imap密码
if err := c.Login("XXXXXXXXX", "XXXXXXX"); 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}
section := &imap.BodySectionName{}
//items 是需要筛选的 刷选模式为flag和body
items := []imap.FetchItem{imap.FetchFlags}
uidItem := imap.FetchUid
envelopeItem := imap.FetchEnvelope
items = append(items, section.FetchItem())
items = append(items, imap.FetchItem(uidItem))
items = append(items, imap.FetchItem(envelopeItem))
messages := make(chan *imap.Message, 10)
done = make(chan error, 1)
//pop3登录
cpop3, err := pop3.Dial("XXXXXXXXXX:110")
if err != nil {
log.Println("Dial")
log.Fatal(err)
}
defer func() {
if err != nil && err != pop3.EOF {
cpop3.Rset()
}
cpop3.Quit()
cpop3.Close()
}()
if err = cpop3.User("XXXXXXXXXXXXXXX"); err != nil {
log.Println("User")
log.Fatal(err)
}
if err = cpop3.Pass("XXXXXXXXXX"); err != nil {
log.Println("Pass")
log.Fatal(err)
}
go func() {
done <- c.Fetch(seqset, items, messages)
}()
//var section imap.BodySectionName;
//section.BodyPartName = "BODY[]";
for msg := range messages {
log.Println("msg.Envelope.Subject: %d", msg.Uid)
//判断是否未读邮件
if len(msg.Flags) == 0 {
section, err := imap.ParseBodySectionName("BODY[]")
if err != nil {
log.Fatal(err)
}
r := msg.GetBody(section)
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:
subjectStr ,_:=charset.DecodeHeader(msg.Envelope.Subject)
log.Println("msg.Envelope.Subject: %s", subjectStr)
filename, _ := h.Filename()
//附件规则自己定义
var mailAddr = msg.Envelope.From[0].MailboxName+"@"+msg.Envelope.From[0].HostName
var arr =strings.Split(filename,"-")
//获取附件后缀
var arrDot =strings.Split(filename,".")
//过滤附件,只取包含XXX的附件,
if(strings.HasPrefix(filename,"XXX")){
if len(arr) == 4 {
log.Println("Got attachment: %s", filename)
//dir := mk_dir(mail_date.Format("01-02-2006"))
l,_ := time.LoadLocation("Asia/Shanghai")
now := time.Now().In(l)
dir := "/static/uploadfile/" +arr[0]+ "/"+arr[1]+ "/"+strconv.Itoa(now.Year()) + "-" + strconv.Itoa(int(now.Month())) + "/" + strconv.Itoa(now.Day()) + "/"+arr[2]
err1 := os.MkdirAll("."+dir, 0755)
if err1 != nil {
log.Println("目录权限不够")
return
}
var filePath = dir + "/" + arr[2]+"."+arrDot[1]
content, _ := ioutil.ReadAll(p.Body)
//写文件
if !write_to_file("."+filePath,content.String()) {
sendMail.SendMailNew(mailAddr,fmt.Sprintf("您的文档:%s 上传失败!",filename),
"服务器上存在同名文件,请修改名称或者版本重新上传!",
"text/html")
return
}
//地址保存数据库
}else {
log.Println("名称不合法:%s",filename)
sendMail.SendMailNew(mailAddr,fmt.Sprintf("您的文档:%s 上传失败!",filename),
"您上传的文件,名称不合法.)",
"text/html")
}
}else {
log.Println("Got attachment: other")
//dir := mk_dir(mail_date.Format("01-02-2006"))
var arr =strings.Split(subjectStr,"-")
l,_ := time.LoadLocation("Asia/Shanghai")
now := time.Now().In(l)
dir := "/static/uploadfile/" +arr[0]+ "/"+arr[1]+ "/"+strconv.Itoa(now.Year()) + "-" + strconv.Itoa(int(now.Month())) + "/" + strconv.Itoa(now.Day()) + "/"+"其他附件"
err1 := os.MkdirAll("."+dir, 0755)
if err1 != nil {
log.Println("目录权限不够")
return
}
var filePath = dir + "/" + filename
content, _ := ioutil.ReadAll(p.Body)
//写文件
if !write_to_file("."+filePath,content.String()) {
/*
sendMail.SendMailNew(mailAddr,fmt.Sprintf("您的文档:%s 上传失败!",filename),
"服务器上存在同名文件,请修改名重新上传!",
"text/html")
*/
log.Println("Got attachment: other:重名上传失败")
return
}
}
}
}
} else {
log.Println("已读邮件:%d",int(msg.SeqNum))
if err = cpop3.Dele(int(msg.SeqNum)); err != nil {
log.Println("Dele failed")
log.Fatal(err)
}
log.Println("Del mail")
}
}
if err := <-done; err != nil {
log.Fatal(err)
}
}