基于微信的邮箱新邮件推送
最近主要做了2个东西:
-
合肥医保口罩购买预约网站分析
-
通过微信推送邮箱新邮件来信提醒
第一个因为网站已经下线,当时也没截图,导致想写过程,没素材。所以来写写通过微信推送邮箱的来信提醒。
一、背景
估计有人会问我在手机上登录邮箱账号,邮箱来信不自然能收到提醒吗?
主要是最近小丸子同学的公司邮箱在苹果手机上新邮件推送延迟。经常收到2天前的邮件提醒,如果不进入邮箱app主动收取邮件,根本不知道有邮件过来。对此小丸子同学也是跟我抱怨和很久,一直以为是手机坏了。最后分析了一下,确认是邮箱的问题(她的同事也有这个问题,好像很多pop3协议的邮箱在苹果手机下都有这个问题)。因为苹果手机不能像安卓手机那样设置邮件收取频率。所以不能通过修改手机设置的方式解决问题。
虽然也不算是手机的问题,但是问题总是要解决。最后决定我通过代码检测她的邮箱是否有新邮件,如果有新邮件,就通过微信告知她。让她及时进入邮件app查看。
好了,方案决定了,那就开始吧!
二、设计
步骤很简单。
-
定时任务每分钟查询邮箱收件箱(她们公司邮箱只支持pop3)
-
检查是否有新邮件,如果有发送微信消息通知
这里需要解决2个问题:
-
怎么收取并检查新邮件?
-
代码怎么发送微信消息?
方案:
-
java-mail库支持pop3收取邮件,但是会收取全部邮件,通过本地保存一份已收邮件列表,通过比对得出新邮件列表。
-
发微信有2种选择:
1 微信公众号(需要企业认证才能主动发送消息)-门槛高,代码实现简单,腾讯提供完备的api。
2 xposed编写模块hook安卓微信客户端(需要一个root的安卓手机)-门槛低,但是代码实现比较复杂,不过网络上有很多现成的介绍,主要是root的安卓手机比较麻烦。
很显然,第2个问题我选择了xposed hook 微信客户端。因为我没办法做企业认证。不过之前微信对使用xposed的账号进行了一轮封锁,这个方法还是有风险。但是我没其他的选择。
这里需要知道几个知识点:
-
xposed框架 -包括xposed安装,模块的使用
-
java实现定时任务。我采用的springboot
一开始准备直接在xposed框架中,当hook住微信的时候启动定时任务。毕竟安卓app(xposed模块)也是java写。这样肯定简单。但是因为我不是专业安卓开发,不知道怎么存储已收邮件列表。特别在xposed的模块中,操作sqlite比较麻烦。
最后决定xposed框架中当hook住微信时启动一个http服务器,再另外通过springboot 启动定时任务,当需要发送微信时,通过http方式发送请求,xposed中的服务器收到请求后,调用微信的代码将消息发送出去。
所以整体结构是这样的。
xposed模块编写
暂时不知道怎么把代码描述清楚,直接上代码
github地址:https://github.com/itlaonong/weixin-xposed-server
(吐槽下上海移动,竟然把github屏蔽了,导致家里上github要特殊手段)
本来我是将我的安卓手机安装linux deploy,然后将定时任务部署在linux deploy中,这样就是本机调用。因为是本地服务,不需要暴露在公网(手机放在家里连上家里的WiFi就行)。但是后面发现linux deploy中定时任务经常会卡死,导致不能每分钟都进行查询,也会出现消息延迟的现象。最后还是将定时任务搬迁到阿里云中。
因为手机在家里,springboot的定时任务在阿里云,就出现无法直接调用我家里的微信消息发送服务。这里就需要使用frp进行内网穿透。就会出现另一个问题:微信消息发送服务直接暴露在公网,不安全。
为了防止被人恶意调用接口。我增加了Google二次认证形式的安全校验,调用接口时,必须附上动态码,手机上的服务器校验通过后才会发送微信消息。因为是动态码,有时效性,就算被人拦截也不会有太大的影响。比直接传递密码安全多了。需要注意,因为是基于时间的动态码,调用方和服务方必须时间同步才行,至少不能相差太多。
使用方式就是配置Constants中的seed,调用方使用相同seed生成动态码,调用时附上动态码(token字段)即可。
springboot定时任务
//TODO 暂时不知道怎么把代码写清楚,回头补一下github地址,直接上代码