feat: 微信自动化客服(wechatauto-replica) 干净历史导入 - AI 自动回复/语音收发/朋友圈发布

This commit is contained in:
2026-09-16 10:12:49 +08:00
commit c3b98f4c4e
69 changed files with 19828 additions and 0 deletions
+113
View File
@@ -0,0 +1,113 @@
# -*- coding: utf-8 -*-
"""v10:纯图发布 + 长等待,正确相机坐标 (1244,84),验证图片上传。"""
import sys, os, time, json, ctypes
from ctypes import wintypes
sys.path.insert(0, r"C:\Users\Administrator\wechatauto-replica")
os.chdir(r"C:\Users\Administrator\wechatauto-replica")
from wechatauto.guia import (LAYOUT_CONFIG_DIR, SIDEBAR_RATIO, SEND_BUTTON_RATIO, _machine_id, WeChatGUI, ScreenOCR)
from PIL import ImageGrab
p = os.path.join(LAYOUT_CONFIG_DIR, f"layout-{_machine_id()}.json")
if not os.path.isfile(p):
os.makedirs(LAYOUT_CONFIG_DIR, exist_ok=True)
json.dump({"machine": _machine_id(), "sidebar_ratio": SIDEBAR_RATIO,
"send_button_ratio": list(SEND_BUTTON_RATIO), "render_w": 1298, "render_h": 950,
"date": time.strftime("%Y-%m-%d %H:%M:%S")}, open(p, "w", encoding="utf-8"))
wx = WeChatGUI()
u = ctypes.windll.user32
def upd(): wx._update_render_rect()
def find_dialog():
found = []
@ctypes.WINFUNCTYPE(wintypes.BOOL, wintypes.HWND, wintypes.LPARAM)
def cb(h, lp):
if u.IsWindowVisible(h):
b = ctypes.create_unicode_buffer(256)
u.GetClassNameW(h, b, 256)
if b.value == "#32770":
r = wintypes.RECT()
u.GetWindowRect(h, ctypes.byref(r))
found.append((r.left, r.top, r.right, r.bottom))
return True
u.EnumWindows(cb, 0)
return found[0] if found else None
def click_abs(x, y, wait=1.0):
u.SetCursorPos(int(x), int(y)); time.sleep(0.12)
u.mouse_event(0x0002,0,0,0,0); u.mouse_event(0x0004,0,0,0,0); time.sleep(wait)
def paste(t):
import pyperclip
pyperclip.copy(t); time.sleep(0.25)
u.keybd_event(0x11,0,0,0); u.keybd_event(0x56,0,0,0)
u.keybd_event(0x56,0,2,0); u.keybd_event(0x11,0,2,0); time.sleep(0.3)
def ctrl_a():
u.keybd_event(0x11,0,0,0); u.keybd_event(0x41,0,0,0)
u.keybd_event(0x41,0,2,0); u.keybd_event(0x11,0,2,0); time.sleep(0.15)
upd()
RW, RH = wx.render_w, wx.render_h
ox, oy = wx.origin_x, wx.origin_y
img_path = r"C:\Users\Administrator\wechatauto-replica\_test_moment.jpg"
# 1. 点相机(实测坐标 1244,84)
wx.wx_click(ox+1244, oy+84); time.sleep(2.5)
dlg = find_dialog()
if not dlg:
print("RESULT: NO_DIALOG"); sys.exit()
dx0, dy0, dx1, dy1 = dlg
DW, DH = dx1-dx0, dy1-dy0
print(f"[v10] 对话框 {DW}x{DH}")
# 2. 选图
click_abs(dx0+int(DW*0.33), dy0+int(DH*0.90), wait=0.8)
ctrl_a(); paste(img_path); time.sleep(0.5)
click_abs(dx0+int(DW*0.84), dy0+int(DH*0.94), wait=2.0)
print("[v10] 已选图")
# 3. 长等待 30s,观察图片状态
for i in range(6):
time.sleep(5)
upd()
img = ImageGrab.grab(bbox=(ox, oy, ox+RW, oy+RH))
lines = ScreenOCR.recognize(img)
has_pic = any("Unai" in t or "unai" in t.lower() for t,_,_,_,_ in lines)
has_cancel = any("取消" in t for t,_,_,_,_ in lines)
print(f" {i*5+5}s 图片在编辑框={has_pic} 取消按钮={has_cancel}")
# 4. 绿色扫描发表按钮
upd()
box = wx._rel_to_screen((int(RW*0.20), int(RH*0.40), RW, RH))
im = ImageGrab.grab(bbox=box).convert("RGB")
px = im.load(); pts = []
for y in range(0, im.size[1], 3):
for x in range(0, im.size[0], 3):
r,g,b = px[x,y][:3]
if abs(r)<45 and abs(g-195)<45 and abs(b-117)<45:
pts.append((x,y))
if len(pts) < 6:
print("RESULT: NO_GREEN_BUTTON"); sys.exit()
xs=[q[0] for q in pts]; ys=[q[1] for q in pts]
bx = int(RW*0.20)+(min(xs)+max(xs))//2
by = int(RH*0.40)+(min(ys)+max(ys))//2
print(f"[v10] 发表按钮 ({bx},{by}) 绿色点{len(pts)}")
# 5. 点发表
wx.wx_click(ox+bx, oy+by); time.sleep(6.0)
# 6. 验证
from wechatauto.db import WeChatDB
from wechatauto.moment import MomentDB
md = MomentDB(WeChatDB())
now = int(time.time())
for f in md.get_my_moments(limit=3):
ct = f.get("create_time") or 0
imgs = f.get("images") or []
if abs(now-int(ct)) < 300:
print(f"[v10] 最新 ct={ct} 图={len(imgs)} 正文={f.get('text','')[:30]}")
print("RESULT: SUCCESS_WITH_IMAGE" if imgs else "RESULT: NO_IMAGE")
break