Files
qinglong/脚本库/微信小程序/抓包版/鸿星尔克签到/2026-04-01_erke_c82ab68b.py
2026-05-24 04:36:41 +00:00

196 lines
7.2 KiB
Python
Raw 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/smallfawn/QLScriptPublic/blob/main/daily/erke.py
# Raw: https://raw.githubusercontent.com/smallfawn/QLScriptPublic/main/daily/erke.py
# Repo: smallfawn/QLScriptPublic
# Path: daily/erke.py
# UploadedAt: 2026-04-01T12:37:39Z
# SHA256: c82ab68bd69e9577d92fa8366558ae24b3be8793d62bef0381e1914cc805750d
# Category: 微信小程序/抓包版
# Evidence: appid/openid/session_key/encryptedData等小程序字段
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
new Env('鸿星尔克签到');
cron: 1 10 * * *
"""
# =================================================================
# 使用说明:
# 1. 环境变量名称ERKE_CONF
# 2. 环境变量格式member_id#enterprise_id#unionid#openid#wx_openid#备注
# 3. 多账号支持:多个账号请换行,或者使用 & 符号连接
# 示例:
# 12345#67890#unionid123#openid123#wx_openid123#我的账号
# 54321#09876#unionid456#openid456#wx_openid456#大号
# =================================================================
# 配置日志
import os
import requests
import hashlib
import random
import logging
from typing import Dict
from datetime import datetime, timedelta, timezone
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger("ErkeCheckIn")
def get_gmt8_time() -> str:
"""获取北京时间字符串"""
tz = timezone(timedelta(hours=8))
return datetime.now(tz).strftime('%Y-%m-%d %H:%M:%S')
def calculate_sign(appid: str, member_id: str, timestamp: str = None) -> dict:
"""计算请求签名逻辑"""
if timestamp is None:
timestamp = get_gmt8_time()
random_num = random.randint(0, 9999999)
trans_id = appid + timestamp
# 按照JS逻辑拼接字符串
sign_str = f"timestamp={timestamp}transId={trans_id}secret=damogic8888random={random_num}memberId={member_id}"
sign = hashlib.md5(sign_str.encode()).hexdigest()
return {
'sign': sign,
'timestamp': timestamp,
'transId': trans_id,
'random': random_num,
'appid': appid,
'memberId': member_id
}
class ErkeAPI:
def __init__(self, member_id, enterprise_id, unionid, openid, wx_openid, account_name):
self.member_id = member_id
self.enterprise_id = enterprise_id
self.unionid = unionid
self.openid = openid
self.wx_openid = wx_openid
self.account_name = account_name
self.appid = "wxa1f1fa3785a47c7d"
self.base_url = 'https://hope.demogic.com/gic-wx-app'
self.ua = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF'
def get_headers(self, sign_val: str) -> Dict[str, str]:
return {
'User-Agent': self.ua,
'Content-Type': 'application/x-www-form-urlencoded',
'sign': sign_val, # 注意原逻辑此处传入的是enterprise_id
'channelEntrance': 'wx_app',
'Referer': 'https://servicewechat.com/wxa1f1fa3785a47c7d/85/page-frame.html',
}
def get_integral(self):
"""查询积分明细"""
sign_data = calculate_sign(self.appid, self.member_id)
data = {
'currentPage': 1,
'pageSize': 20,
'memberId': self.member_id,
'cliqueId': '-1',
'enterpriseId': self.enterprise_id,
'unionid': self.unionid,
'openid': self.openid,
'wxOpenid': self.wx_openid,
'random': sign_data['random'],
'appid': self.appid,
'transId': sign_data['transId'],
'sign': sign_data['sign'],
'timestamp': sign_data['timestamp'],
'gicWxaVersion': '3.9.56'
}
try:
res = requests.post(f"{self.base_url}/integral_record.json",
headers=self.get_headers(self.enterprise_id),
data=data, timeout=10).json()
response_obj = res.get('response', {})
accumulate = response_obj.get('accumulatPoints', 0)
logger.info(f"[{self.account_name}] 当前累计积分: {accumulate}")
return accumulate
except Exception as e:
logger.error(f"[{self.account_name}] 积分查询异常: {e}")
return "未知"
def sign_in(self):
"""执行签到"""
sign_data = calculate_sign(self.appid, self.member_id)
payload = {
'source': 'wxapp',
'memberId': self.member_id,
'cliqueId': '-1',
'enterpriseId': self.enterprise_id,
'unionid': self.unionid,
'openid': self.openid,
'wxOpenid': self.wx_openid,
'sign': sign_data['sign'],
'random': sign_data['random'],
'appid': self.appid,
'transId': sign_data['transId'],
'timestamp': sign_data['timestamp'],
'gicWxaVersion': '3.9.56'
}
headers = self.get_headers(self.enterprise_id)
headers['Content-Type'] = 'application/json;charset=UTF-8'
try:
res = requests.post(f"{self.base_url}/sign/member_sign.json",
headers=headers, json=payload, timeout=10).json()
msg = res.get('message', '无返回信息')
code = res.get('code')
if code in ['0000', '1001', 0]:
logger.info(f"[{self.account_name}] 签到结果: {msg}")
return True, msg
else:
logger.warning(f"[{self.account_name}] 签到失败: {msg}")
return False, msg
except Exception as e:
logger.error(f"[{self.account_name}] 签到请求异常: {e}")
return False, str(e)
def main():
# 尝试从环境变量读取配置
conf_str = os.getenv("ERKE_CONF", "")
if not conf_str:
logger.error("未找到环境变量 ERKE_CONF请检查配置")
return
# 处理多账号,支持换行或 & 分隔
accounts_raw = conf_str.replace("&", "\n").splitlines()
summary = []
for line in accounts_raw:
if not line.strip(): continue
params = line.strip().split("#")
if len(params) < 5:
logger.error(f"账号配置格式错误 (需5个#分隔): {line}")
continue
# 提取参数
m_id, e_id, uid, oid, wx_oid = params[:5]
name = params[5] if len(params) > 5 else f"账号_{m_id[-4:]}"
api = ErkeAPI(m_id, e_id, uid, oid, wx_oid, name)
# 执行流程
points_before = api.get_integral()
success, msg = api.sign_in()
points_after = api.get_integral()
status_emoji = "" if success else ""
summary.append(f"{status_emoji}{name}】: {msg} (积分: {points_before} -> {points_after})")
# 打印最终统计
print("\n" + "="*30)
print(" 鸿星尔克任务简报")
print("="*30)
print("\n".join(summary))
# 如果有通知推送逻辑,可以在此处调用
# send_notification("鸿星尔克签到", "\n".join(summary))
if __name__ == "__main__":
main()