Files
F6--/张阳脚本/简道云/智能助手修复.py
T
2026-04-09 10:19:09 +08:00

216 lines
10 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.
# -*- coding: utf-8 -*-
import requests
import time
import json
# 配置部分
COOKIES = {
'auth_token': 's%3A.9uztgExtmqUJXHCi00hv9SGq6eVYSvH%2BxQSwrox1Yls',
'fx-lang': 'zh_cn',
'tenantId': 'agndqbuttb7ipfciraxcokgqyu',
'AGL_USER_ID': 'a50da526-dd43-4a78-ace1-ba810a6f2168',
'_ga': 'GA1.1.626243428.1772260541',
'_clck': 'y7ldwu%5E2%5Eg3y%5E0%5E2250',
'sensorsdata2015jssdkcross': '%7B%22distinct_id%22%3A%2257956c24ceedab0c48c17b4e%22%2C%22first_id%22%3A%2219b6dd1a10c148a-063e3a033b10ed-4c657b58-2073600-19b6dd1a10d145b%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E8%87%AA%E7%84%B6%E6%90%9C%E7%B4%A2%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC%22%2C%22%24latest_referrer%22%3A%22https%3A%2F%2Fcn.bing.com%2F%22%7D%2C%22identities%22%3A%22eyIkaWRlbnRpdHlfY29va2llX2lkIjoiMTliNmRkMWExMGMxNDhhLTA2M2UzYTAzM2IxMGVkLTRjNjU3YjU4LTIwNzM2MDAtMTliNmRkMWExMGQxNDViIiwiJGlkZW50aXR5X2xvZ2luX2lkIjoiNTc5NTZjMjRjZWVkYWIwYzQ4YzE3YjRlIn0%3D%22%2C%22history_login_id%22%3A%7B%22name%22%3A%22%24identity_login_id%22%2C%22value%22%3A%2257956c24ceedab0c48c17b4e%22%7D%7D',
'_ga_JTDW9M3LHZ': 'GS2.1.s1772266909$o3$g0$t1772266909$j60$l0$h0',
'_csrf': 's%3A_1U5JMsnCD3RTwmCER9JqFb4.mo773pACR2hpC5wQ5xRGTuHdG4IFBizJgZutwkTfRhc',
'Hm_lvt_de47dd1629940fe88b02865de93dd9fe': '1771984077,1772162048,1772241582,1772414152',
'Hm_lpvt_de47dd1629940fe88b02865de93dd9fe': '1772414152',
'HMACCOUNT': 'A6A0585E8C70051D',
'GSuvNKHqfvX2r6v7P8HkZv2bow': 's%3ANSFxWNnsV8OLC9fbqrhhSe7MujIfdZRJ.tMYAhg8UajUy6BrCqfYcElJt5PZXAPx5IFCMAzFhC0g',
'JDY_SID': 's%3AUdb7kb2OqRccqGoceHeVLZk8x0WSlLt7.ZWuCEChyCcI5HYSTmXSbFVsmMaAx9Lplm3%2F%2FJ4B%2Biuo',
'acw_tc': '743e76f717725247327573805ec920bcf336c7da350308d821feb726945021',
}
HEADERS = {
'accept': 'application/json, text/plain, */*',
'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
'content-type': 'application/json',
'origin': 'https://www.jiandaoyun.com',
'priority': 'u=1, i',
'referer': 'https://www.jiandaoyun.com/dashboard/app/675b900991ad2491c69389ca/settings',
'sec-ch-ua': '"Not:A-Brand";v="99", "Microsoft Edge";v="145", "Chromium";v="145"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-origin',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36 Edg/145.0.0.0',
'x-csrf-token': 'bNv86JCo-fWdbOodYigjN6C8IUfIrvt211k4',
'x-jdy-ver': '10.17.4',
'x-request-id': 'ed87c6c8-7a8c-4444-b487-5d1b37c653e7',
# 'cookie': 'auth_token=s%3A.9uztgExtmqUJXHCi00hv9SGq6eVYSvH%2BxQSwrox1Yls; fx-lang=zh_cn; tenantId=agndqbuttb7ipfciraxcokgqyu; AGL_USER_ID=a50da526-dd43-4a78-ace1-ba810a6f2168; _ga=GA1.1.626243428.1772260541; _clck=y7ldwu%5E2%5Eg3y%5E0%5E2250; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%2257956c24ceedab0c48c17b4e%22%2C%22first_id%22%3A%2219b6dd1a10c148a-063e3a033b10ed-4c657b58-2073600-19b6dd1a10d145b%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E8%87%AA%E7%84%B6%E6%90%9C%E7%B4%A2%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC%22%2C%22%24latest_referrer%22%3A%22https%3A%2F%2Fcn.bing.com%2F%22%7D%2C%22identities%22%3A%22eyIkaWRlbnRpdHlfY29va2llX2lkIjoiMTliNmRkMWExMGMxNDhhLTA2M2UzYTAzM2IxMGVkLTRjNjU3YjU4LTIwNzM2MDAtMTliNmRkMWExMGQxNDViIiwiJGlkZW50aXR5X2xvZ2luX2lkIjoiNTc5NTZjMjRjZWVkYWIwYzQ4YzE3YjRlIn0%3D%22%2C%22history_login_id%22%3A%7B%22name%22%3A%22%24identity_login_id%22%2C%22value%22%3A%2257956c24ceedab0c48c17b4e%22%7D%7D; _ga_JTDW9M3LHZ=GS2.1.s1772266909$o3$g0$t1772266909$j60$l0$h0; _csrf=s%3A_1U5JMsnCD3RTwmCER9JqFb4.mo773pACR2hpC5wQ5xRGTuHdG4IFBizJgZutwkTfRhc; Hm_lvt_de47dd1629940fe88b02865de93dd9fe=1771984077,1772162048,1772241582,1772414152; Hm_lpvt_de47dd1629940fe88b02865de93dd9fe=1772414152; HMACCOUNT=A6A0585E8C70051D; GSuvNKHqfvX2r6v7P8HkZv2bow=s%3ANSFxWNnsV8OLC9fbqrhhSe7MujIfdZRJ.tMYAhg8UajUy6BrCqfYcElJt5PZXAPx5IFCMAzFhC0g; JDY_SID=s%3AUdb7kb2OqRccqGoceHeVLZk8x0WSlLt7.ZWuCEChyCcI5HYSTmXSbFVsmMaAx9Lplm3%2F%2FJ4B%2Biuo; acw_tc=743e76f717725247327573805ec920bcf336c7da350308d821feb726945021',
}
BASE_URL = "https://dingtalk.jiandaoyun.com"
APP_ID = '675b900991ad2491c69389ca'
PROCESS_ID = "694b9e1a5ef7b2983fe1f922" # 智能助手流程id
NODE_ID = 3 # 根据原代码固定为4# 出現問題的結點
def check_response(resp_or_data, step_name):
"""通用响应校验函数(兼容 Response / 已解析的 JSON 数据)"""
if hasattr(resp_or_data, "status_code") and hasattr(resp_or_data, "json"):
response = resp_or_data
if response.status_code != 200:
print(f"[❌ {step_name}] 请求失败,状态码: {response.status_code}")
print(f" 响应内容: {response.text[:200]}...")
return None
try:
data = response.json()
except ValueError:
print(f"[❌ {step_name}] 响应不是有效的 JSON 格式")
return None
else:
# 允许直接传入 response.json() 的结果(dict/list/...
data = resp_or_data
# 检查常见错误结构:尽量只在“明确失败”时返回 None,避免误伤正常返回
if isinstance(data, dict):
if data.get("error"):
msg = data.get("message") or data.get("msg") or data.get("error") or "未知错误"
print(f"[❌ {step_name}] 业务逻辑错误: {msg}")
return None
if data.get("success") is False:
msg = data.get("message") or data.get("msg") or "success=false"
print(f"[❌ {step_name}] 业务逻辑错误: {msg}")
return None
if "code" in data:
code = data.get("code")
# 常见成功码:0/200;其他情况仅当明确不是成功码才判失败
if code not in (None, 0, 200, "0", "200", True):
msg = data.get("message") or data.get("msg") or data.get("error") or f"code={code}"
print(f"[❌ {step_name}] 业务逻辑错误: {msg}")
return None
return data
def main():
print(f"[*] 开始执行流程,目标应用: {APP_ID}, 流程: {PROCESS_ID}")
# 1. 轮询查询日志列表并依次处理
limit = 20 # 每次最多处理多少条
success_count = 0
fail_count = 0
total_instances = 0
while True:
log_payload = {
'appId': APP_ID,
'process_id': PROCESS_ID,
'skip': 0, # 每次都从第 0 条开始查最新的失败记录
'limit': limit,
'filter': [],
'status': 3, # 假设 3 代表某种特定状态(如失败/待处理)
}
print(f"[*] 正在获取流程日志列表,limit={limit} ...")
resp_logs = requests.post(
f'{BASE_URL}/automation/apis/process/logs',
cookies=COOKIES,
headers=HEADERS,
json=log_payload,
)
logs_data = check_response(resp_logs, "获取日志列表")
if not logs_data:
break
print(logs_data)
# 兼容不同返回字段命名:有的环境是 "logs",有的是 "log"
instance_list = logs_data.get("log") or logs_data.get("logs") or []
if not instance_list:
print("[⚠️] 未找到符合条件的流程实例,任务结束。")
break
batch_count = len(instance_list)
total_instances += batch_count
print(f"[✅] 本批获取 {batch_count} 条实例记录,开始逐个处理...")
for idx, item in enumerate(instance_list, start=1):
instance_id = item.get("instance_id")
if not instance_id:
print(f"[⚠️] 第 {idx} 条记录缺少 instance_id,跳过。")
continue
print(f"\n--- 处理实例 {idx}: {instance_id} ---")
# 2. 获取节点日志 (获取 execution_id 和 service_id)
node_log_payload = {
'appId': APP_ID,
'process_id': PROCESS_ID,
'instance_id': instance_id,
'node_id': NODE_ID,
}
resp_node = requests.post(
f'{BASE_URL}/automation/apis/process/node_logs',
cookies=COOKIES,
headers=HEADERS,
json=node_log_payload,
)
node_data = check_response(resp_node, "获取节点日志")
if not node_data:
print(f"[❌] 实例 {instance_id} 获取节点日志失败,跳过重试。")
fail_count += 1
continue
execution_id = node_data.get('execution_id')
service_id = node_data.get('service_id')
if not execution_id or not service_id:
print(f"[❌] 实例 {instance_id} 返回数据中缺少 execution_id 或 service_id。")
print(f" 返回数据: {json.dumps(node_data)}")
fail_count += 1
continue
print(f" [️] 获取到执行ID: {execution_id}, 服务ID: {service_id}")
# 3. 执行重试 (Retry)
retry_payload = {
'appId': APP_ID,
'process_id': PROCESS_ID,
'instance_id': instance_id,
'execution_id': execution_id,
'service_id': service_id,
}
resp_retry = requests.post(
f'{BASE_URL}/automation/apis/process/retry_node',
cookies=COOKIES,
headers=HEADERS,
json=retry_payload,
)
retry_data = check_response(resp_retry, "执行重试")
if retry_data:
print(f"[✅] 实例 {instance_id} 重试请求发送成功。")
success_count += 1
else:
print(f"[❌] 实例 {instance_id} 重试请求失败。")
fail_count += 1
# 可选:添加短暂延时,避免触发频率限制
time.sleep(0.5)
# 不使用 skip 分页,而是重新查询最新的失败记录,直到接口不再返回失败实例为止
print("\n" + "=" * 30)
print(f"[🏁] 任务完成。总计实例数: {total_instances}, 成功重试: {success_count}, 失败: {fail_count}")
if __name__ == "__main__":
try:
main()
except Exception as e:
print(f"[💥] 程序发生未捕获的异常: {e}")
import traceback
traceback.print_exc()