Mac 微信是有一个消息通知的,这一点就挺好的,有时候根本不用点开开看就能看到消息内容。而 Windows 电脑版是没有这个消息通知的,只有右下角图标闪烁。
于是我想了不少的办法去实现这么一个功能,已经另辟蹊径实现了这个功能,其实也有一定的局限性,但是能满足办公期间的小需求。
效果如下:
接收通知
首先是 Windows 的通知弹出的实现就是 Windows 自带的通知栏,我们可以通过 Python 去调用 Windows API 去发送 Windows 通知,让消息弹出来。
发送通知
相比于接收通知,那么发送通知就比较困难,因为 Windows 微信电脑版的窗口属于非 Windows 窗口标准,我们无法通过常规的方式去读取每个控件的内容,更无法监听到通知内容,所以我这边另辟蹊径,通过安卓手机去监听微信消息。
所以这里用到了 SmsForwarder 这款开源软件,安装在你的安卓手机上,然后设置转发规则,监听微信 APP 的通知,然后发送通道选择 WebHook ,将监听到的消息 POST 到 Python 开启的 HTTP 服务器,触发 Windows 通知就行了!
from flask import Flask, request
from winotify import Notification
import urllib.parse
import win32gui
import win32con
app = Flask(__name__)
@app.route('/') # 获取 url 信息
def getUrlInfo():
# 完整 url
url = request.url
# 主机部分
hostUrl = request.host_url
# 访问路径
fullPath = request.full_path
# 输出
print('收到推送任务,推送内容是:'+str(urllib.parse.unquote(fullPath.split("/?")[1])).replace('+', ' ', 1))
# 接收到的内容
content = str(urllib.parse.unquote(fullPath.split("/?")[1])).replace('+', ' ', 1);
# 错误处理
# 因为监听软件那边监听到的首条消息是没有带上微信用户昵称的
# 所以需要判断当前接收到的消息是不是首条消息
# 如果不做这一步就会出错
pdmh = ":" in content
if pdmh == True:
# 截取:前面的内容
qianmian = content.split(":")[0]
weixinMsg = content.split(":")[1]
# 还要将[]这一块也去掉,这就提取到了微信昵称
nickname = qianmian.split("]")[1]
else:
nickname = '微信消息通知'
weixinMsg = content
# 开发 Push 通知
# toaster = ToastNotifier()
# toaster.show_toast(title=nickname, msg=weixinMsg,icon_path="logo.ico", duration=5)
toast = Notification(app_id="通知中心",title=nickname,msg=weixinMsg,icon=r"D:\Python\demo\wechat.png")
toast.show()
return "ok"
def notify(hwnd, msg, wparam, lparam):
print("notify", msg)
if lparam == win32con.WM_LBUTTONDBLCLK: # 双击左键
print("双击左键", msg)
pass
elif lparam == win32con.WM_RBUTTONUP: # 右键弹起
print("右键弹起", msg)
pass
elif lparam == win32con.WM_LBUTTONUP: # 左键弹起
print("左键弹起", msg)
pass
return True
wc = win32gui.WNDCLASS()
wc.hInstance = win32gui.GetModuleHandle(None)
wc.lpszClassName = "Windows 通知中心"
wc.style = win32con.CS_VREDRAW | win32con.CS_HREDRAW;
wc.lpfnWndProc = notify
classAtom = win32gui.RegisterClass(wc)
hwnd =win32gui.CreateWindow(classAtom,"tst2",win32con.WS_OVERLAPPEDWINDOW,win32con.CW_USEDEFAULT,win32con.CW_USEDEFAULT,win32con.CW_USEDEFAULT,win32con.CW_USEDEFAULT,None,None,None,None)
notify_id = (hwnd,0,win32gui.NIF_ICON | win32gui.NIF_MESSAGE | win32gui.NIF_TIP,win32con.WM_USER + 20,win32gui.LoadIcon(0, win32con.IDI_APPLICATION),"Windows 通知中心")
win32gui.Shell_NotifyIcon(0,notify_id)
# 在指定 IP 和端口开启 HTTP 服务
if __name__ == '__main__':
app.run(debug=False,host='192.168.1.100', port=8080)
192.168.1.100 是我电脑的内网 ip ,8080 是端口号,你需要获取你电脑的内网 ip 换上去,不然后续配置安卓那边的监听转发端就无法正常转发通知。
执行代码后,会在你电脑开启一个 HTTP 服务,这时候你可以在浏览器进行本地测试,在浏览器按照以下格式粘贴:
http://内网 ip:端口号 /?通知内容
安装 SmsForwarder 这款软件。
下载地址: https://gitee.com/pp/SmsForwarder/releases/tag/v3.0.8
设置发送通道,选择 Webhook ,Webserver 按照以下格式填写:
http://内网 ip:端口号 /
WebParams 直接填写 [msg] ,请求方式是 GET
设置转发规则,添加规则,选择匹配 “APP 包名”,匹配模式选择 “是”,匹配值是 com.tencent.mm ,选择刚才配置的发送通道,自定义模板直接点击通知内容。
简单进行配置后,SmsForwarder 进行一些必要的设置后,就可以正常使用了。
目前还在想办法在电脑本地监听微信消息,毕竟通过安卓手机监听消息也不是办法,一方面是依赖本地的服务器,通过局域网才可以发送通知给电脑。另一方面就是安卓监听消息也不具备稳定性,而且也不是人人都用安卓,对于苹果手机的用户,也是难以实现这个。
内网 ip 可能会变化,如果你发现后面无法正常接收到通知,可以检查下内网 ip ,更换一下 ip 重启服务。
因为这是使用内网 ip 实现的 HTTP 服务,所以你安卓手机需要连接的 wifi 与电脑的一致,如果电脑是有线网络,那么你手机需要与电脑有线网络同一个网络环境,即 ip 相同。
如果不想通过局域网实现,可以自己配置内网穿透服务去实现外网请求服务。
自写 Hook 微信,读取内存去监听微信消息
使用现成的方案,市面上也有一些 Hook 微信的框架,例如可爱猫,这个框架提供了非常便利的 SDK 去调用 API 来监听微信聊天消息,甚至还可以做到发送消息。
1
ysc3839 2022-08-29 12:21:53 +08:00
> 因为 Windows 微信电脑版的窗口属于非 Windows 窗口标准,我们无法通过常规的方式去读取每个控件的内容,更无法监听到通知内容
实测可以使用无障碍接口获取,微信是支持的。可以用 Windows SDK 附带的 inspect.exe 试试看。 |
2
brucmao 2022-08-29 14:11:00 +08:00
昨天看到一个 sublime text 通知插件,挺好玩的
http://facelessuser.github.io/SubNotify/ |
3
PRStarDust 2022-08-29 15:06:05 +08:00
话说你们不会觉得 Windows 的通知中心很难用吗?这个右下角的通知每次弹出来,既不能像安卓那样划掉,又不能点击那个 X 来彻底关掉,点 X 只是消除他的悬浮显示,并不能让它从通知中心彻底消失,所以我只好把所有应用的通知权限关掉...
|
4
pytth OP 是的,要进入通知中心列表再次 X 掉
@PRStarDust |
5
icepie 2022-08-29 21:09:54 +08:00
貌似装个 kde connect 就解决了你的需求
|
6
01046 2022-08-30 00:16:00 +08:00
对呀,kde connect 就可以了啊。。。
话说 kde connect 什么时候可以修复手机剪贴板同步到 PC 无效的 BUG 啊,现在用 join ,感觉不是很稳定 |
7
RyanLin1995 2022-08-30 10:37:42 +08:00
我没记错的话,win11 好像已经实现了
|
9
pytth OP @RyanLin1995 win11 也没有像 mac 一样弹出微信消息通知。
|
10
pytth OP @ysc3839 感谢提醒,我用 ui spy.exe 试了下,之前试了一下是不行的,重新研究了,确实是可以得到每个控件,连每条聊天记录都可以获取到!感觉可以开发很多微信的小工具出来。
|
11
icepie 2022-08-30 11:18:39 +08:00
其实我也挺困扰的...为什么微信 pc 端不调用系统的通知 api...
|
12
kid740246048 2022-08-30 12:18:15 +08:00 via Android
@01046 Android 10 之后不允许后台读取剪贴板,可以装个 magisk 模块来绕过
|
13
RyanLin1995 2022-08-30 16:40:27 +08:00
@pytth 我记得我的预览版 win11 是有的,等我今晚回去确定一下
|
14
01046 2022-08-31 02:12:51 +08:00
@kid740246048 谢谢,请教一下模块名字? 剪贴板互通是刚需
|
15
kid740246048 2022-08-31 02:15:20 +08:00
|
16
01046 2022-08-31 02:44:46 +08:00
啊,没事了,用关键词搜到了,clipboard whitelist
|
17
01046 2022-08-31 02:45:16 +08:00
原来已经被回复了,还是非常感谢
|
18
llsquaer 2022-09-01 18:58:57 +08:00
思路很不错..我觉得直接自己写一个弹窗比 windows 自带的好用多了
|
19
cx1251cx 2022-12-04 19:20:12 +08:00
我只能说,你们玩 it 的……是真牛逼啊
|