Files
qinglong/脚本库/微信小程序/协议版/微信协议适配器/2025-08-27_wechatCodeAdapter_36b9c2d8.py
2026-05-24 05:33:05 +00:00

363 lines
13 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Source: https://github.com/LinYuanovo/AutoTaskScripts/blob/main/utils/wechatCodeAdapter.py
# Raw: https://raw.githubusercontent.com/LinYuanovo/AutoTaskScripts/main/utils/wechatCodeAdapter.py
# Repo: LinYuanovo/AutoTaskScripts
# Path: utils/wechatCodeAdapter.py
# UploadedAt: 2025-08-27T15:31:08+08:00
# SHA256: 36b9c2d8634e456f442d8308b0b552eb86d59b1d65f9c1d0d8c2a8b370b34c3b
# Category: 微信小程序/协议版
# Evidence: getMiniProgramCode/wx_cloud/wx_token/code协议链路
"""
作者: 临渊
日期: 2025/7/22
name: 微信协议适配器
变量: soy_wxid_data (微信id) 多个账号用换行分割
soy_codetoken_data (微信授权token)
soy_codeurl_data (微信授权url)
定时: 一天两次
cron: 10 11,12 * * *
------------------------------------------------------------
更新日志:
2025/7/22 V1.0 初始化
2025/7/27 V1.1 适配StarBot Pro
"""
import requests
import os
import logging
import traceback
from datetime import datetime
class WechatCodeAdapter:
def __init__(self, wx_appid):
"""
初始化微信授权适配器
"""
self.wx_code_url = os.getenv("soy_codeurl_data")
self.wx_code_token = os.getenv("soy_codetoken_data")
self.wx_appid = wx_appid # 微信小程序id
self.wx_protocol_type = 0 # 微信协议类型
self.wx_accounts_list = [] # 微信账号列表
self.log_msgs = [] # 日志收集
self._init_protocol_type()
self._init_all_accounts()
self.setup_logging()
def setup_logging(self):
"""
配置日志系统
"""
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s\t- %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
handlers=[
# logging.FileHandler(f'{self.script_name}_{datetime.now().strftime("%Y%m%d")}.log', encoding='utf-8'), # 保存日志
logging.StreamHandler()
]
)
def log(self, msg, level="info"):
if level == "info":
logging.info(msg)
elif level == "error":
logging.error(msg)
elif level == "warning":
logging.warning(msg)
self.log_msgs.append(msg)
def get_protocol_type(self):
"""
获取协议类型
:return: 协议类型
"""
if self.wx_code_url:
end_url = self.wx_code_url.split("/")[-1]
else:
end_url = ""
if end_url == "getMiniProgramCode":
# 养鸡场
return 1
elif end_url == "code":
# 牛子
return 2
elif end_url == "GetAllDevices":
# WeChatPadPro
return 3
elif end_url == "GetAuthKey":
# iwechat
return 4
elif end_url == "processor":
# StarBot Pro
return 5
else:
# 其他不知道的协议
return 0
def _init_protocol_type(self):
"""
初始化微信协议类型
"""
self.wx_protocol_type = self.get_protocol_type()
def dict_keys_to_lower(self, obj):
"""
递归将字典的所有键名转为小写
"""
if isinstance(obj, dict):
return {k.lower(): self.dict_keys_to_lower(v) for k, v in obj.items()}
elif isinstance(obj, list):
return [self.dict_keys_to_lower(i) for i in obj]
else:
return obj
def get_code_1(self, wx_id):
"""
养鸡场 获取code
:param wx_id: 微信id
:return: code
"""
try:
url = self.wx_code_url
headers = {
"Authorization": self.wx_code_token,
"Content-Type": "application/json"
}
payload = {"wxid": wx_id, "appid": self.wx_appid}
response = requests.post(url, headers=headers, json=payload, timeout=5)
response.raise_for_status()
# 将所有键名转为小写
response_json = self.dict_keys_to_lower(response.json())
if response_json['code'] == 200:
return response_json['data']['code']
else:
self.log(f"[微信授权] 失败,错误信息: {response_json.get('msg', '未知错误')}", level="error")
return False
except requests.RequestException as e:
self.log(f"[微信授权]发生网络错误: {str(e)}\n{traceback.format_exc()}", level="error")
return False
except Exception as e:
self.log(f"[微信授权]发生未知错误: {str(e)}\n{traceback.format_exc()}", level="error")
return False
def get_code_2(self, wx_id):
"""
牛子 获取code
:param wx_id: 微信id
:return: code
"""
try:
url = self.wx_code_url
headers = {
"Content-Type": "application/json"
}
payload = {"wxid": wx_id, "appid": self.wx_appid}
response = requests.post(url, headers=headers, json=payload, timeout=5)
response.raise_for_status()
# 将所有键名转为小写
response_json = self.dict_keys_to_lower(response.json())
# 直接取授权code不判断返回码code
code_value = response_json.get('data', {}).get('code', '')
if code_value:
code = code_value
return code
else:
self.log(f"[微信授权] 失败,错误信息: {response_json['message']}", level="error")
return False
except requests.RequestException as e:
self.log(f"[微信授权]发生网络错误: {str(e)}\n{traceback.format_exc()}", level="error")
return False
except Exception as e:
self.log(f"[微信授权]发生未知错误: {str(e)}\n{traceback.format_exc()}", level="error")
return False
def _init_all_accounts(self):
"""
初始化微信账号列表
"""
if self.wx_protocol_type == 3:
self.wx_accounts_list = self.get_all_devices()
elif self.wx_protocol_type == 4:
self.wx_accounts_list = self.get_auth_keys()
def get_all_devices(self):
"""
WeChatPadPro 获取账号授权码列表
:return: 账号授权码列表
"""
try:
url = self.wx_code_url
params = {
"key": self.wx_code_token
}
response = requests.get(url, params=params, timeout=15)
response.raise_for_status()
response_json = response.json()
if response_json.get('Code') == 200:
all_devices = response_json.get('Data', {}).get('devices', [])
if all_devices:
return all_devices
else:
self.log(f"[获取账号授权码列表] 返回信息: {response_json['Text']}", level="error")
return []
else:
self.log(f"[获取账号授权码列表] 失败,错误信息: {response_json['Text']}", level="error")
return []
except Exception as e:
self.log(f"[获取账号授权码列表] 发生错误: {str(e)}\n{traceback.format_exc()}", level="error")
return []
def get_target_key_by_wxid(self, all_keys, wx_id):
"""
获取指定微信id的授权码
:param all_keys: 所有账号授权码列表
:param wx_id: 微信id
:return: 指定微信id的授权码
"""
for key in all_keys:
_wx_id = key.get('deviceId') or key.get('wx_id')
if _wx_id == wx_id:
return key.get('authKey') or key.get('license')
return None
def get_code_3(self, wx_id):
"""
WeChatPadPro 获取code
:param wx_id: 微信id
:return: code
"""
try:
all_devices = self.wx_accounts_list
if not all_devices:
self.log(f"[获取code] 账号列表为空,未能获取到", level="error")
return False
target_key = self.get_target_key_by_wxid(all_devices, wx_id)
url = self.wx_code_url.split("/admin")[0] + "/applet/JsLogin"
params = {
"key": target_key
}
payload = {
"AppId": self.wx_appid,
"Data": "",
"Opt": 1,
"PackageName": "",
"SdkName": ""
}
response = requests.post(url, params=params, json=payload, timeout=5)
response.raise_for_status()
response_json = response.json()
if response_json.get('Code') == 200:
# self.log(f"[获取code] 成功code: {response_json.get('Data', {}).get('Code', '')}")
return response_json.get('Data', {}).get('Code', '')
else:
self.log(f"[获取code] 失败,错误信息: {response_json['Text']}", level="error")
return False
except Exception as e:
self.log(f"[获取code] 发生错误: {str(e)}\n{traceback.format_exc()}", level="error")
return False
def get_auth_keys(self):
"""
iwechat 获取账号授权码列表
:return: 账号授权码列表
"""
try:
url = self.wx_code_url
params = {
"key": self.wx_code_token
}
response = requests.get(url, params=params, timeout=15)
response.raise_for_status()
response_json = response.json()
return response_json
except Exception as e:
self.log(f"[获取code] 发生错误: {str(e)}\n{traceback.format_exc()}", level="error")
return False
def get_code_4(self, wx_id):
"""
iwechat 获取code
:param wx_id: 微信id
:return: code
"""
try:
auth_keys = self.wx_accounts_list
if not auth_keys:
self.log(f"[获取code] 账号列表为空,未能获取到", level="error")
return False
target_key = self.get_target_key_by_wxid(auth_keys, wx_id)
url = self.wx_code_url.split("/admin")[0] + "/applet/JsLogin"
params = {
"key": target_key
}
payload = {
"AppId": self.wx_appid,
"Data": "",
"Opt": 1,
"PackageName": "",
"SdkName": ""
}
response = requests.post(url, params=params, json=payload, timeout=5)
response.raise_for_status()
response_json = response.json()
if response_json.get('Code') == 200:
self.log(f"[获取code] 成功code: {response_json.get('Data', {}).get('Code', '')}")
return response_json.get('Data', {}).get('Code', '')
else:
self.log(f"[获取code] 失败,错误信息: {response_json['Text']}", level="error")
return False
except Exception as e:
self.log(f"[获取code] 发生错误: {str(e)}\n{traceback.format_exc()}", level="error")
return False
def get_code_5(self, wx_id):
"""
StarBot Pro 获取code
:param wx_id: 微信id
:return: code
"""
try:
url = self.wx_code_url
headers = {
"Authorization": self.wx_code_token,
"Content-Type": "application/json"
}
payload = {
"type": "querySmallProgramCode",
"params": {
"robotId": wx_id,
"appid": self.wx_appid
}
}
response = requests.post(url, headers=headers, json=payload, timeout=5)
response.raise_for_status()
response_json = response.json()
if response_json.get('code') == 200:
return response_json.get('data', {}).get('code', '')
else:
self.log(f"[获取code] 失败,错误信息: {response_json['description']}", level="error")
return False
except Exception as e:
self.log(f"[获取code] 发生错误: {str(e)}\n{traceback.format_exc()}", level="error")
return False
def get_code(self, wx_id):
"""
获取code
:param wx_id: 微信id
:return: 指定wxid的code
"""
protocol_type = self.get_protocol_type()
if protocol_type == 1:
return self.get_code_1(wx_id)
elif protocol_type == 2:
return self.get_code_2(wx_id)
elif protocol_type == 3:
return self.get_code_3(wx_id)
elif protocol_type == 4:
return self.get_code_4(wx_id)
elif protocol_type == 5:
return self.get_code_5(wx_id)
else:
self.log(f"[获取code] 发生错误: 未知协议类型", level="error")
return False