75 lines
2.7 KiB
Python
75 lines
2.7 KiB
Python
"""
|
|
WeChat Hermes Bridge — with webhook keepalive
|
|
"""
|
|
import pymem, pymem.process, requests, time, json, threading
|
|
from http.server import HTTPServer, BaseHTTPRequestHandler
|
|
|
|
DLL = r"C:\Users\hmo\AppData\Local\Programs\Python\Python310\Lib\site-packages\wxhook\tools\wxhook.dll"
|
|
WX = "http://127.0.0.1:19088"
|
|
HERMES = "http://192.168.0.103:5800/callback"
|
|
LOG = r"C:\Users\hmo\Desktop\bridge.log"
|
|
BOT = "wxid_7onnerpx2s2l22"
|
|
PORT = 5801
|
|
|
|
def log(m):
|
|
with open(LOG, "a", encoding="utf-8") as f:
|
|
f.write(f"{time.strftime('%H:%M:%S')} {m}\n")
|
|
|
|
# Inject DLL
|
|
try:
|
|
requests.post(f"{WX}/api/checkLogin", json={}, timeout=3)
|
|
log("DLL OK")
|
|
except:
|
|
pm = pymem.Pymem("WeChat.exe")
|
|
pymem.process.inject_dll(pm.process_handle, DLL.encode())
|
|
time.sleep(2)
|
|
log("DLL injected")
|
|
|
|
log(f"login: {requests.post(f'{WX}/api/checkLogin', json={}, timeout=5).json()}")
|
|
|
|
# Periodic webhook refresh (every 30 seconds)
|
|
def webhook_keepalive():
|
|
while True:
|
|
try:
|
|
requests.post(f"{WX}/api/hookSyncMsg", json={
|
|
"port": PORT, "ip": "0.0.0.0", "enableHttp": 1,
|
|
"url": f"http://127.0.0.1:{PORT}", "timeout": 300
|
|
}, timeout=5)
|
|
except:
|
|
pass
|
|
time.sleep(30)
|
|
|
|
threading.Thread(target=webhook_keepalive, daemon=True).start()
|
|
log("keepalive started (30s)")
|
|
|
|
# Test message
|
|
requests.post(f"{WX}/api/sendTextMsg",
|
|
json={"wxid": "filehelper", "msg": "[Bridge] online"}, timeout=5)
|
|
|
|
class H(BaseHTTPRequestHandler):
|
|
def do_POST(self):
|
|
body = self.rfile.read(int(self.headers.get("Content-Length", 0)))
|
|
try:
|
|
d = json.loads(body)
|
|
fu = d.get("fromUser", "")
|
|
ct = d.get("content", "")
|
|
if fu and ct and fu != BOT:
|
|
log(f"MSG {fu}: {ct[:60]}")
|
|
threading.Thread(target=lambda: requests.post(HERMES, json=[{"id": int(time.time()*1000), "type": 1, "content": ct, "sender": fu, "roomid": "", "ts": time.time()}], timeout=30), daemon=True).start()
|
|
self.send_response(200); self.end_headers(); return
|
|
to = d.get("to", "") or d.get("wxid", "")
|
|
msg = d.get("message", "") or d.get("content", "")
|
|
if to and msg:
|
|
r = requests.post(f"{WX}/api/sendTextMsg", json={"wxid": to, "msg": msg}, timeout=5)
|
|
log(f"SEND {to}: {r.get('msg','')}")
|
|
self.send_response(200); self.end_headers(); return
|
|
except Exception as e:
|
|
log(f"ERR: {str(e)[:80]}")
|
|
self.send_response(200); self.end_headers()
|
|
def do_GET(self):
|
|
self.send_response(200); self.end_headers(); self.wfile.write(b'{"ok":true}')
|
|
def log_message(self, *a): pass
|
|
|
|
log(f"ready on :{PORT}")
|
|
HTTPServer(("0.0.0.0", PORT), H).serve_forever()
|