QQNotifier

好吧我就是无聊了……

这玩意是为了解决这么一个问题的:我的 QQ 跑在虚拟机里面,因此里面有消息了我在外面并不知情。消息推送有几个可能的解决方案:

  1. WineQQ。我对稳定性产生怀疑。
  2. QQ for iPhone。其推送并没有那么及时。
  3. 戴上耳机就可以听到 QQ 的声音了。但是我的歌都放在 iPhone 里面且耳机只能用在 iPhone 上。
  4. 换成 Windows/Mac 系统。我没那么土豪。

于是就想能不能写一个小程序使得虚拟机里面有消息了就在外部的 KDE 里面出个提示之类的。

琢磨了以下,QQ 自带的提示似乎只能播放声音。于是第一想法是监听声卡播放。搜了搜没找到相关资料(其实是自己懒,觉得如果这样的话有得进行 WinAPI 编程。感觉监听声卡这还是比较底层的,感觉不好搞。),于是就放弃了。

第二想法是播放声音的时候肯定得访问声音文件,我记得 png 还是 jpeg 可以嵌入一个奇怪的东西,不知道 WAV 是否可以。搜了搜还是没找到类似东西。放弃。

第三个想法是监视屏幕,我打开一个 QQ 窗口,如果有消息过来了,其图标会有相应的变化。在我使用的这个版本里面,窗口合并后如果一个人有新消息,其名字后会出现一个橙色小圆圈,里面一个数字表示其消息数目。如果我定时扫描这个位置,获取此时此像素的颜色,就可以知道有没有消息了。后来想到,如果我把 QQ 不设置为当前窗口,那么当有新消息过来的时候 QQ 在任务栏里的图标会变成那种一闪一闪的黄色。于是我监视的点的位置基本上是不变的,只要我保证 QQ 在任务栏中的位置不变就好了。

于是就用了 AutoHotKey 这个小工具,代码大概就长这样:

#Persistent
#SingleInstance
SetTimer, CheckQQNotification, 1000
return

CheckQQNotification:
CoordMode, Pixel, Screen
PixelGetColor, col, 187, 775
; 颜色就是 %col%
return

现在我们知道颜色了。实践发现,图标的颜色不是两种颜色,新消息过来后,由于会闪所以可能会有其余的颜色。于是就直接用 RGB 三元组的 Manhatton 距离来判断处于什么状态了。

现在考虑如何将颜色这个信息传到 Linux 里面去了。第一想法是造一个小型 http 服务器。看起来没那么复杂,就开始写了。

框架用的 Node.js 的 Express 框架,而且我只需要得到一个信息,直接 POST 过去就好了。那么考虑在 AutoHotKey 中如何发送一个 POST 请求。据说 AHK 有一个包可以做这种事,但是我试了试发现不 work ,果断下了一个 curl for Win 然后直接 POST 过去。我很想吐槽 AHK 带参数运行一个程序,照着别人的程序写都发现不 work 。这里有个一个小细节,AHK 运行这种 Console 程序会闪出一个黑框,很影响用户体验。解决方法是找了一个叫做 Hidden Start 的程序, hstart /NOCONSOLE curl 就好了。Win 这边差不多布置好了。

在 Linux 这边,弹窗的话我用的是 notify-send 还附赠一堆小图标。由于请求是 1s 一个的过来的,不能对于每个 Active 的请求我都弹一个窗,于是就设置:如果上一次表示 QQ Active 的请求是在 5s 以前,那么就弹窗,否则不弹。另外如果我现在就在虚拟机里面操作也可以不弹窗。如何判断在是否在虚拟机里面?第一想法是在 Win 里面获取鼠标位置,发现不 work 。第二想法是在 Linux 里面获取活跃窗口,用的 xdotool getactivewindow getwindowname 搞的。为了好看还加了当前时间,moment.js

(我是不是又造了一个轮子?)