Continue seeded Qinglong script collection

This commit is contained in:
Hermes Agent
2026-05-24 05:33:05 +00:00
parent ca1a4275e4
commit b082da3fe1
392 changed files with 131619 additions and 7 deletions

View File

@@ -0,0 +1,540 @@
# Source: https://github.com/3ixi/CodeScripts/blob/main/envRefresh.py
# Raw: https://raw.githubusercontent.com/3ixi/CodeScripts/main/envRefresh.py
# Repo: 3ixi/CodeScripts
# Path: envRefresh.py
# UploadedAt: 2025-09-23T14:07:43+08:00
# SHA256: 9b6e74e8f24750c6fa1c5311177fdffc0a57605c711d266f5e28ad75f4aed03f
# Category: 微信小程序/抓包版
# Evidence: appid/openid/session_key/encryptedData等小程序字段
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
青龙面板环境变量更新脚本
用于自动获取并更新青龙面板中的指定环境变量值
脚本作者3iXi
创建时间2025/09/22
此脚本需要配合iPad协议服务使用
需要自定义依赖:
        getCode.pyhttps://github.com/3ixi/CodeScripts
        cloud_auth.pyhttps://github.com/3ixi/CloudScripts
        SendNotify.pyhttps://github.com/3ixi/CloudScripts
--------------------------
2025/09/22 更新支持:捷停车、老板电器、雀巢会员俱乐部
"""
import os
import json
import time
import requests
from datetime import datetime
from typing import Dict, List, Tuple, Any, Optional
import getCode
import cloud_auth
import SendNotify
# 青龙面板API相关常量
API_ENDPOINTS = {
'auth': '/open/auth/token',
'envs': '/open/envs'
}
BASE_HEADERS = {
'User-Agent': 'envRefresh_3iXi/1.0.1',
'Accept': 'application/json'
}
ENV_UPDATE_CONFIG = {
'quechao': {
'appid': 'wxc5db704249c9bb31',
'api_url': 'https://crm.nestlechinese.com/openapi/identityservice/connect/token',
'api_host': 'crm.nestlechinese.com',
'name': '雀巢会员俱乐部'
},
'laobandianqi': {
'appid': 'wxba70fb8e3eb3aab9',
'api_url': 'https://aio.myroki.com/api/v1/mini-app/user/login',
'api_host': 'aio.myroki.com',
'name': '老板电器'
},
'jtc': {
'appid': 'wx24b70f0ad2a9a89a',
'api_url': 'https://www.jslife.com.cn/wxhttp/weixin/xcx/get_openid_by_code',
'api_host': 'www.jslife.com.cn',
'name': '捷停车'
}
}
class QinglongEnvUpdater:
"""青龙面板环境变量更新器"""
def __init__(self):
"""初始化,获取必要的环境变量"""
# 获取青龙面板认证信息
env_refresh = os.getenv('envRefresh')
if not env_refresh:
raise ValueError("未找到环境变量'envRefresh',请访问青龙面板的“系统设置”-“应用设置”创建包含“环境变量”权限的应用按照client_id&client_secret格式创建envRefresh环境变量")
parts = env_refresh.split('&')
if len(parts) != 2:
raise ValueError("环境变量'envRefresh'格式错误应为client_id&client_secret")
self.client_id = parts[0]
self.client_secret = parts[1]
# 获取青龙面板URL优先使用环境变量其次尝试本地默认地址
env_qinglong = os.getenv('qinglongURL')
if env_qinglong:
self.qinglong_url = env_qinglong.rstrip('/')
else:
# 默认尝试本地青龙地址
default_url = 'http://127.0.0.1:5700'
# 测试默认地址是否可达
try:
test_resp = requests.get(default_url, headers=BASE_HEADERS, timeout=3)
if 200 <= test_resp.status_code < 400:
self.qinglong_url = default_url
else:
raise Exception('默认地址返回异常状态码')
except Exception:
# 默认地址不可达,提示用户需要创建环境变量
raise ValueError("未检测到可用的青龙面板地址。请创建环境变量'qinglongURL'值为青龙面板的Web访问地址例如 http://192.168.110.102:5700")
self.token = None
self.env_list = []
def _make_request(self, method: str, url: str, **kwargs) -> Dict:
"""统一请求处理"""
headers = BASE_HEADERS.copy()
if 'headers' in kwargs:
headers.update(kwargs['headers'])
del kwargs['headers']
try:
response = requests.request(method, url, headers=headers, **kwargs, timeout=30)
response.raise_for_status()
data = response.json()
# 统一错误处理
if 'statusCode' in data:
raise Exception(f"请求失败: {data.get('message', '未知错误')}")
return data
except requests.RequestException as e:
raise Exception(f"网络请求失败: {e}")
except json.JSONDecodeError as e:
raise Exception(f"响应数据解析失败: {e}")
def authenticate(self):
"""获取青龙面板认证token"""
url = f"{self.qinglong_url}{API_ENDPOINTS['auth']}"
params = {
'client_id': self.client_id,
'client_secret': self.client_secret
}
data = self._make_request('GET', url, params=params)
if 'data' in data and 'token' in data['data']:
self.token = data['data']['token']
print("✅ 青龙面板认证成功")
else:
raise Exception("认证失败未找到token")
def get_envs(self):
"""获取环境变量列表"""
if not self.token:
raise Exception("请先进行认证")
url = f"{self.qinglong_url}{API_ENDPOINTS['envs']}"
headers = {
'Authorization': f'Bearer {self.token}'
}
data = self._make_request('GET', url, headers=headers)
if 'data' in data:
self.env_list = data['data']
print(f"✅ 获取到{len(self.env_list)}个环境变量")
else:
raise Exception("获取环境变量列表失败")
def _get_env_by_name(self, name: str) -> Optional[Dict]:
"""根据名称获取环境变量"""
for env in self.env_list:
if env.get('name') == name:
return env
return None
def _update_env_value(self, env_id: int, name: str, value: str, remarks_prefix: str):
"""更新环境变量值"""
if not self.token:
raise Exception("请先进行认证")
url = f"{self.qinglong_url}{API_ENDPOINTS['envs']}"
headers = {
'Authorization': f'Bearer {self.token}',
'Content-Type': 'application/json'
}
today = datetime.now().strftime('%Y%m%d')
remarks = f"{remarks_prefix}{today}更新"
payload = {
'id': env_id,
'name': name,
'value': value,
'remarks': remarks
}
data = self._make_request('PUT', url, headers=headers, json=payload)
if data.get('code') == 200:
print(f"✅ 环境变量{name}更新成功")
print("-" * 30)
else:
raise Exception(f"环境变量{name}更新失败: {data}")
def _update_quechao_env(self, env_info: Dict):
"""更新雀巢环境变量"""
print("🔄 开始更新雀巢会员俱乐部环境变量...")
# 获取Code列表
app_id = ENV_UPDATE_CONFIG['quechao']['appid']
codes = getCode.get_wechat_codes(app_id)
if not codes:
raise Exception("未获取到任何Code")
# 获取新Token
access_tokens = []
for nick_name, code in codes.items():
print(f"🎫 正在获取{nick_name}的新Token...")
headers = {
'host': ENV_UPDATE_CONFIG['quechao']['api_host'],
'content-type': 'application/x-www-form-urlencoded',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x63090a13) UnifiedPCWindowsWechat(0xf2541022) XWEB/16467'
}
payload = {
'client_id': 'wechatMini',
'client_secret': 'secret',
'grant_type': 'wechat_auth_code',
'auth_code': code
}
try:
response = requests.post(
ENV_UPDATE_CONFIG['quechao']['api_url'],
headers=headers,
data=payload,
timeout=30
)
response.raise_for_status()
result = response.json()
if 'access_token' in result:
access_tokens.append(result['access_token'])
print(f"{nick_name}新Token获取成功")
else:
error_msg = result.get('error', '未知错误')
print(f"{nick_name}新Token获取失败: {error_msg}")
except Exception as e:
print(f"{nick_name}新Token获取失败: {e}")
if not access_tokens:
raise Exception("未获取到任何有效的新Token")
# 更新环境变量
new_value = "#".join(access_tokens)
self._update_env_value(
env_info['id'],
env_info['name'],
new_value,
ENV_UPDATE_CONFIG['quechao']['name']
)
return len(access_tokens)
def _update_laobandianqi_env(self, env_info: Dict):
"""更新老板电器环境变量"""
print("🔄 开始更新老板电器环境变量...")
# 获取Code列表
app_id = ENV_UPDATE_CONFIG['laobandianqi']['appid']
codes = getCode.get_wechat_codes(app_id)
if not codes:
raise Exception("未获取到任何Code")
# 获取新Token
tokens = []
for nick_name, code in codes.items():
print(f"🎫 正在获取{nick_name}的新Token...")
# 生成时间戳
timestamp = int(time.time() * 1000)
# 使用云函数认证模块生成签名相关参数调用云服务获取secret和signature
auth_client = cloud_auth.get_auth_client()
try:
auth_resp = auth_client.call_service('roki', timestamp=timestamp)
if auth_resp.get('success'):
secret = auth_resp.get('secret', '')
signature = auth_resp.get('signature', '')
if not secret or not signature:
print(f"{nick_name} 获取认证信息失败: secret或signature为空")
continue
else:
error_msg = auth_resp.get('error', '未知错误')
print(f"{nick_name} 获取认证信息失败: {error_msg}")
continue
except Exception as e:
print(f"{nick_name} 获取认证信息失败: {e}")
continue
headers = {
'host': ENV_UPDATE_CONFIG['laobandianqi']['api_host'],
'content-type': 'application/json',
'x-app-env': 'release',
'timestamp': str(timestamp),
'nonce': '1234567890123456',
'app-version': '5000',
'app-id': 'roki_app',
'signature': signature,
'secret': secret
}
payload = {
"code": code,
"param": {
"qr-code": ""
}
}
try:
response = requests.post(
ENV_UPDATE_CONFIG['laobandianqi']['api_url'],
headers=headers,
json=payload,
timeout=30
)
response.raise_for_status()
result = response.json()
if result.get('success', False) and 'data' in result and 'token' in result['data']:
tokens.append(result['data']['token'])
print(f"{nick_name}新Token获取成功")
else:
error_msg = result.get('message', '未知错误')
print(f"{nick_name}新Token获取失败: {error_msg}")
except Exception as e:
print(f"{nick_name}新Token获取失败: {e}")
if not tokens:
raise Exception("未获取到任何有效的新Token")
# 更新环境变量
new_value = "#".join(tokens)
self._update_env_value(
env_info['id'],
env_info['name'],
new_value,
ENV_UPDATE_CONFIG['laobandianqi']['name']
)
return len(tokens)
def _update_jtc_env(self, env_info: Dict):
"""更新捷停车环境变量jtc"""
print("🔄 开始更新捷停车环境变量...")
app_id = ENV_UPDATE_CONFIG['jtc']['appid']
codes = getCode.get_wechat_codes(app_id)
if not codes:
raise Exception("未获取到任何Code")
tokens = []
for nick_name, code in codes.items():
print(f"🎫 正在获取{nick_name}的新Token...")
t = int(time.time() * 1000)
url = f"{ENV_UPDATE_CONFIG['jtc']['api_url']}?t={t}"
headers = {
'Host': ENV_UPDATE_CONFIG['jtc']['api_host'],
'Connection': 'keep-alive',
'applicationVersion': '1.0.1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x63090a13) UnifiedPCWindowsWechat(0xf2541022) XWEB/16467',
'Content-Type': 'application/json;charset=UTF-8',
'Accept': '*/*',
'Referer': f"https://servicewechat.com/{app_id}/285/page-frame.html",
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9'
}
payload = {
'code': code,
'userType': 'WX_XCX_JTC',
'appId': app_id
}
try:
response = requests.post(url, headers=headers, json=payload, timeout=30)
response.raise_for_status()
result = response.json()
if str(result.get('resultCode')) != '0':
message = result.get('message', '未知错误')
print(f"{nick_name} 获取新Token失败: {message}")
continue
obj = result.get('obj', {})
token = obj.get('token')
if token:
tokens.append(token)
print(f"{nick_name}新Token获取成功")
else:
print(f"{nick_name} 响应中未包含token")
except Exception as e:
print(f"{nick_name}新Token获取失败: {e}")
if not tokens:
raise Exception("未获取到任何有效的新Token")
new_value = "#".join(tokens)
self._update_env_value(
env_info['id'],
env_info['name'],
new_value,
ENV_UPDATE_CONFIG['jtc']['name']
)
return len(tokens)
def update_envs(self) -> Tuple[int, int, List[Dict[str, Any]]]:
"""更新所有支持的环境变量"""
if not self.env_list:
raise Exception("请先获取环境变量列表")
updated_env_count = 0
updated_value_count = 0
# 收集每个环境变量的更新结果,便于推送通知
per_env_results: List[Dict[str, Any]] = []
# 遍历支持更新的环境变量
for env_name, config in ENV_UPDATE_CONFIG.items():
env_info = self._get_env_by_name(env_name)
if not env_info:
msg = f"⚠️ 您未创建环境变量{env_name},本次跳过更新"
print(msg)
per_env_results.append({
'key': env_name,
'name': config.get('name', ''),
'success': False,
'count': 0,
'message': '未创建此环境变量'
})
continue
try:
if env_name == 'quechao':
value_count = self._update_quechao_env(env_info)
elif env_name == 'laobandianqi':
value_count = self._update_laobandianqi_env(env_info)
elif env_name == 'jtc':
value_count = self._update_jtc_env(env_info)
else:
print(f"⚠️ 环境变量{env_name}暂不支持更新")
per_env_results.append({
'key': env_name,
'name': config.get('name', ''),
'success': False,
'count': 0,
'message': '不支持更新'
})
continue
# 成功更新
updated_env_count += 1
updated_value_count += value_count
per_env_results.append({
'key': env_name,
'name': config.get('name', ''),
'success': True,
'count': value_count,
'message': ''
})
except Exception as e:
print(f"❌ 环境变量{env_name}更新失败: {e}")
per_env_results.append({
'key': env_name,
'name': config.get('name', ''),
'success': False,
'count': 0,
'message': str(e)
})
return updated_env_count, updated_value_count, per_env_results
def main():
"""主函数"""
print("🔄 青龙面板环境变量更新脚本开始执行...")
print("=" * 30)
try:
updater = QinglongEnvUpdater()
updater.authenticate()
updater.get_envs()
env_count, value_count, per_env_results = updater.update_envs()
print("=" * 30)
print(f"✅ 脚本执行完成")
# 构造更详细的推送内容包含每个环境的中文名、key、成功/失败、数量与错误信息
lines = []
lines.append(f"本次成功更新了{env_count}个环境变量,共{value_count}个环境变量值")
lines.append("")
for r in per_env_results:
name = r.get('name') or ''
key = r.get('key')
success = r.get('success')
count = r.get('count')
message = r.get('message') or ''
if success:
lines.append(f"{name}{key})更新成功,更新了{count}个环境变量值")
lines.append("=" * 30)
else:
lines.append(f"{name}{key})更新失败,更新了{count}个环境变量值")
if message:
lines.append(f" 错误信息: {message}")
lines.append("=" * 30)
content = "\n".join(lines)
# 发送推送通知
try:
title = "青龙环境变量更新脚本执行完成"
SendNotify.SendNotify(title, content)
except Exception as e:
print(f"⚠️ 发送通知时出错: {e}")
except Exception as e:
print(f"❌ 脚本执行失败: {e}")
# 失败时也尝试发送通知
try:
title = "青龙环境变量更新脚本执行失败"
content = f"脚本执行失败: {e}"
SendNotify.SendNotify(title, content)
except Exception as e2:
print(f"⚠️ 发送失败通知时出错: {e2}")
return 1
return 0
if __name__ == "__main__":
exit(main())