微信电脑版4.1.X最新版获取未读消息并在右下角弹出提醒
摘要
微信4.1版本的UI采用新的框架开发,能够获取到的信息有限,目前只能获取到消息列表的控件内容。
代码
import time
import threading
import uiautomation as auto
from win10toast import ToastNotifier
import tkinter as tk
from tkinter import ttk
import re
shown_msgs = set()
FILE_NAME = "messages.txt"
import re
def parse_chat_name_flexible(raw_name: str):
"""
灵活解析微信未读消息,并去掉【消息免打扰】字样和方括号中的未读数
"""
if not raw_name:
return None
# 去掉消息免打扰
raw_name = re.sub(r'[/[/(【(]*消息免打扰[/]/)】)]*', '', raw_name)
parts = raw_name.split()
if len(parts) < 2:
return None
user = parts[0]
unread = "0条未读"
msg = ""
sender = ""
time_str = ""
start_idx = 1
# 已置顶
if "已置顶" in parts:
start_idx += 1
# 查找未读条数
for i in range(start_idx, min(start_idx + 2, len(parts))):
if "条未读" in parts[i]:
unread = parts[i]
start_idx = i + 1
break
# 查找时间
for i in range(len(parts) - 1, start_idx - 1, -1):
if ':' in parts[i] or '/' in parts[i]:
time_str = parts[i]
end_idx = i
break
else:
end_idx = len(parts)
msg_parts = parts[start_idx:end_idx]
msg = " ".join(msg_parts)
# 拆分发送人和消息内容
if ":" in msg:
sender, msg_content = msg.split(":", 1)
elif ":" in msg: # 中文冒号
sender, msg_content = msg.split(":", 1)
else:
sender, msg_content = "", msg
# 清理发送人里的 [n条]
sender = re.sub(r'/[/d+条/]', '', sender).strip()
return {
"user": user.strip(),
"unread": unread.strip(),
"sender": sender.strip(),
"msg": msg_content.strip(),
"time": time_str.strip()
}
def find_unread_sessions():
desktop = auto.GetRootControl()
chat_cells = []
for control, depth in auto.WalkControl(desktop):
if control.ClassName == "mmui::ChatSessionCell":
if "未读" in (control.Name or ""):
parsed = parse_chat_name_flexible(control.Name)
if parsed:
chat_cells.append(parsed)
return chat_cells
def monitor_messages(tree):
# 确保子线程正确初始化 COM
with auto.UIAutomationInitializerInThread():
toaster = ToastNotifier()
while True:
try:
sessions = find_unread_sessions()
for s in sessions:
key = f"{s['user']}_{s['msg']}_{s['time']}"
if key not in shown_msgs:
title = f"{s['user']} ({s['unread']})"
msg = f"{s['msg']} [{s['time']}]"
print(f"[通知] {title} -> {msg}")
# 系统通知
toaster.show_toast(title, msg, duration=3, threaded=True)
# 写入txt
with open(FILE_NAME, "a", encoding="utf-8") as f:
f.write(f"{s['time']}/t{s['user']}/t{s['unread']}/t{s['sender']}/t{s['msg']}/n")
# 更新表格
tree.after(0, lambda s=s: tree.insert(
"", "end",
values=(s['time'], s['user'], s['unread'], s['sender'], s['msg'])
))
shown_msgs.add(key)
except Exception as e:
print(f"[错误] {e}")
time.sleep(2)
def start_gui():
root = tk.Tk()
root.title("微信未读消息监控")
root.geometry("1200x550")
style = ttk.Style(root)
style.theme_use("default")
style.configure("Treeview", rowheight=30, font=("Microsoft YaHei", 11))
style.configure("Treeview.Heading", font=("Microsoft YaHei", 12, "bold"), anchor="center")
# 新增 sender 列
columns = ("time", "user", "unread", "sender", "msg")
tree = ttk.Treeview(root, columns=columns, show="headings")
tree.heading("time", text="时间")
tree.heading("user", text="用户")
tree.heading("unread", text="未读")
tree.heading("sender", text="发送人")
tree.heading("msg", text="消息内容")
# 设置列宽和对齐
tree.column("time", width=100, anchor="center")
tree.column("user", width=120, anchor="center")
tree.column("unread", width=80, anchor="center")
tree.column("sender", width=120, anchor="center")
tree.column("msg", width=500, anchor="center")
# 滚动条
scrollbar = ttk.Scrollbar(root, orient="vertical", command=tree.yview)
tree.configure(yscroll=scrollbar.set)
scrollbar.pack(side="right", fill="y")
tree.pack(fill="both", expand=True)
# 启动后台线程
t = threading.Thread(target=monitor_messages, args=(tree,), daemon=True)
t.start()
root.mainloop()
if __name__ == "__main__":
start_gui()
使用
需要将微信打开,不能关闭,可最小化,但绝对不能叉掉。
然后允许这个Python脚本即可。
Python wxmsg.py
目前支持的功能:
- 读取私信未读的最新的那条消息
- 读取群最新的未读的那条消息
- 读取最新的收款记录
- 会在右下角弹出
- 会有ui界面,记录消息
- 读取公众号最新发布的消息
界面
作者
TANKING