Go语言如何实现删除Winmail邮箱系统中收件箱的所有邮件

背景

由于在公司使用的邮箱容量比较小,在电脑上安装的收信的客户端没有设置在接收邮件之后删除服务器上的邮件,导致服务器的邮件容量不经意就快用尽了,因为我的邮箱经常要收到很多邮件,也不是业务繁忙,就是很多jira的通知邮件一下子就占满了,所以就研究了下如何登录公司的邮箱web页面,如何删除收件箱的所有邮件。

公司使用的邮箱系统是Winmail,它的官网是:Winmail官网

代码实现

整体的代码思路比较简单:

删除邮件大致逻辑
1、访问公司邮箱系统web页面:mail.xxxx.com
2、通过页面的sessid获取验证码,手动输入验证码,保存下来
3、获取一个key,和本地的密码一起使用AES加密获得加密后的密码
4、调用登录接口,返回一个tokenid和sessid
5、访问主页,不停地请求第一页的收件箱,每次请求都会查看收件箱的邮件数目是否为0,如果为0,
代表已经全部删除收件箱的邮件
6、对第一页的每一封邮件拿到对应的item序号,调用删除接口删除即可,我这里是一封邮件一封邮件删除的。

使用的语言是:Go
使用的框架是:Colly框架。 不了解的可以去官网研究下,后面我可能会出一下Colly官方文档的中文翻译。

主要就是两个文件:
main.go
app.ini
放在同一级目录下面。

下面就放一下代码:

# main.go
package main

import (
	"bytes"
	"crypto/aes"
	"crypto/cipher"
	"crypto/md5"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"github.com/gocolly/colly"
	"gopkg.in/ini.v1"
	"io/ioutil"
	"math/rand"
	"net/http"
	"net/url"
	"os"
	"strconv"
)

type KeyResponse struct {
	Result string `json:"result"`
	Key string `json:"key"`
}

type LoginResponse struct {
	Result string `json:"result"`
	TokenId string `json:"tokenid"`
	SessionId string `json:"sessid"`
}

var loginSessionId = ""
var userName = ""
var password = ""
var isLogin = false
var total = "1"

func init(){
	cfg, err := ini.Load("app.ini")
	if err != nil {
		fmt.Println("配置文件app.ini读取错误", err)
		os.Exit(1)
	}
	userName = cfg.Section("base").Key("user").String()
	password = cfg.Section("base").Key("pwd").String()
}

func main() {
	c := colly.NewCollector(
		colly.UserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36"),
	)

	c.OnHTML("input[name=sessid]", func(e *colly.HTMLElement) {
		if !isLogin{
			loginSessionId = e.Attr("value")
			checkCodeUrl := fmt.Sprintf("http://mail.xxx.com/chkcode.php?sessid=%s&retid=%s",loginSessionId,
				strconv.FormatFloat(rand.Float64(), 'f', -1, 64))
			c.Visit(checkCodeUrl)
		}
	})
	c.OnRequest(func(request *colly.Request) {
		fmt.Println("开始访问 >> ", request.URL)
	})

	c.OnResponse(func(response *colly.Response) {
		path := response.Request.URL.Path
		if path == "/chkcode.php"{
			// 保存验证码图片
			ioutil.WriteFile("查看当前验证码.png", response.Body, 0755)
			var checkCode = ""
			fmt.Println("请输入本地验证码图片钟的验证码:")
			fmt.Scanln(&checkCode)
			key := getKey(loginSessionId)
			if key == ""{
				fmt.Println("获取密钥失败")
				return
			}
			pwd := "{wm_aes}" + encryptPwd(password,key)
			tokenId,sessionId := login(loginSessionId,userName,pwd,checkCode)
			if tokenId != ""{
				//删除验证码
				err := os.Remove("查看当前验证码.png")
				if err == nil{
					fmt.Println("验证码图片删除成功!")
				}
				isLogin = true
			}
			var requestData = make(map[string]string)
			requestData["sessid"] = sessionId
			requestData["act"] = "login"
			requestData["f_user"] = userName
			requestData["f_pass"] = password
			requestData["f_checkcode"] = checkCode
			requestData["f_lang"] = "ch_gb"
			requestData["f_theme"] = "default"
			c.Post(fmt.Sprintf("http://mail.xxx.com/main.php?token=%s&email=liuchangrong@xxx.com",
				tokenId),requestData)

			// 循环删除第一页,如果收件箱还有邮件的话
			for ;total != "0"; {
				DeleteMail(c, sessionId)
			}
		}
	})


	c.Visit("http://mail.xxx.com/")
}

// 登录接口
func login(sessionId, userName, password, checkCode string) (string,string){
	loginUrl := "http://mail.xxx.com/login.php"

	data := make(url.Values)
	data["sessid"] = []string{sessionId}
	data["f_user"] = []string{userName}
	data["f_domain"] = []string{""}
	data["f_pass"] = []string{password}
	data["f_checkcode"] = []string{checkCode}
	data["f_lang"] = []string{"ch_gb"}
	data["f_theme"] = []string{"default"}
	data["f_autologin"] = []string{"0"}
	data["f_result"] = []string{"json"}

	res, err := http.PostForm(loginUrl, data)
	if err != nil {
		fmt.Println("登录接口出错:", err)
		return "",""
	}
	defer res.Body.Close()

	body, _:= ioutil.ReadAll(res.Body)
	var loginResponse = &LoginResponse{}
	json.Unmarshal(body,&loginResponse)
	return loginResponse.TokenId, loginResponse.SessionId
}
/**
获取key
 */
func getKey(sessionId string) string{
	keyUrl := fmt.Sprintf("http://mail.xxx.com/index.php?act=key&retid=%s",
		strconv.FormatFloat(rand.Float64(), 'f', -1, 64))

	data := make(url.Values)
	data["sessid"] = []string{sessionId}

	//把post表单发送给目标服务器
	res, err := http.PostForm(keyUrl, data)
	if err != nil {
		fmt.Println("请求密钥出错:", err)
		return ""
	}
	defer res.Body.Close()

	body, _:= ioutil.ReadAll(res.Body)
	var keyResponse = &KeyResponse{}
	json.Unmarshal(body,&keyResponse)
	return keyResponse.Key
}

// 加密密码
func encryptPwd(pwd,key string) string{
	return AesEncrypt(pwd,key)
}

func AesEncrypt(orig string, key string) string {
	// 转成字节数组
	origData := []byte(orig)
	md5 := fmt.Sprintf("%x", md5.Sum([]byte(key)))
	k := []byte(md5)
	// 分组秘钥
	// NewCipher该函数限制了输入k的长度必须为16, 24或者32
	block, _ := aes.NewCipher(k)
	// 获取秘钥块的长度
	blockSize := block.BlockSize()
	// 补全码
	origData = ZeroPadding(origData, blockSize)
	// 加密模式
	blockMode := cipher.NewCBCEncrypter(block, k[:blockSize])
	// 创建数组
	created := make([]byte, len(origData))
	// 加密
	blockMode.CryptBlocks(created, origData)
	return base64.StdEncoding.EncodeToString(created)
}

func ZeroPadding(ciphertext []byte, blockSize int) []byte {
	padding := blockSize - len(ciphertext)%blockSize
	padText := bytes.Repeat([]byte{0}, padding)
	return append(ciphertext, padText...)
}

//删除邮件
func DeleteMail(collector *colly.Collector, sessionId string){
	collector.OnHTML("font[color=red]", func(element *colly.HTMLElement) {
		//计算收件箱是否还有邮件
		var cnt = element.Text
		total = cnt
	})
	// 一次只能删除一封邮件
	collector.OnHTML("input[type=checkbox][name^='item_']", func(element *colly.HTMLElement) {
		var requestData = make(map[string]string)
		requestData[element.Attr("name")] = element.Attr("value")
		requestData["sessid"] = sessionId
		requestData["act"] = "msglist"
		requestData["opt"] = "drop"
		requestData["folder"] = "INBOX"
		requestData["msgid"] = ""
		requestData["pag"] = "1"
		requestData["listcount"] = "10"
		requestData["tofolder"] = ""
		requestData["sortby"] = "date"
		requestData["sortorder"] = "DESC"
		requestData["nameto"] = ""
		requestData["mailto"] = ""
		requestData["listtype"] = ""
		requestData["label"] = ""
		requestData["search"] = ""
		collector.Post("http://mail.xxx.com/main.php",requestData)
		fmt.Println("---------删除了序号为"+element.Attr("value")+"的邮件--------")
	})

	// 请求第一页收件箱的邮件列表
	var requestData = make(map[string]string)
	requestData["sessid"] = sessionId
	requestData["act"] = "msglist"
	requestData["opt"] = "list"
	requestData["folder"] = "INBOX"
	requestData["search"] = ""
	requestData["listtype"] = ""
	requestData["label"] = ""
	collector.Post("http://mail.xxx.com/main.php",requestData)
}
# app.ini
[base]
# 邮箱名
user=liuchangrong@xxx.com
# 邮箱密码
pwd=xxx

以上就是删除收件箱邮件代码的全部实现,程序一运行的话,收件箱的邮件就会全部删除,删除之前千万要知道后果啊,别把有用的邮件删除了哦。

如果有什么疑问或者建议的话,欢迎在评论区留言!

如果觉得文章写的不错的话,希望一键三连哦!感谢您的观看!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值