#!/usr/bin/env python3 """Create empty records, wait for automation, then update with real jsonData.""" import json, requests, sys, time CRED_FILE = "/root/.openclaw/credentials/xiaoyan/config.json" APP_TOKEN = "CMHSbUUjka3TrUsaxxEc297ongf" TABLE_ID = "tblweY65jGBiwSdt" sys.path.insert(0, '/root/.openclaw/workspace-xiaoyan') from scripts.batch_reading_pic_qa import ALL_QUESTIONS, build_json with open(CRED_FILE) as f: cred = json.load(f) app_id = cred["apps"][0]["appId"] app_secret = cred["apps"][0]["appSecret"] def get_token(): resp = requests.post( "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal", json={"app_id": app_id, "app_secret": app_secret}, ) return resp.json()["tenant_access_token"] token = get_token() # Step 1: Delete any existing corrupted records print("=== Step 1: Clean up ===") resp = requests.get( f"https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{TABLE_ID}/records?page_size=20", headers={"Authorization": f"Bearer {token}"}, ) for item in resp.json()["data"]["items"]: fid = item["fields"].get("题目集合 ID", "") if fid in ALL_QUESTIONS: rid = item["record_id"] requests.delete( f"https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{TABLE_ID}/records/{rid}", headers={"Authorization": f"Bearer {token}"}, ) print(f" Deleted {fid}") time.sleep(3) # Step 2: Create ALL empty records first print("\n=== Step 2: Create empty records ===") record_ids = {} for qid in sorted(ALL_QUESTIONS.keys()): fields = {"题目集合 ID": qid, "dataStatus": "0"} resp = requests.post( f"https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{TABLE_ID}/records", headers={"Authorization": f"Bearer {token}", "Content-Type": "application/json"}, json={"fields": fields}, ) rid = resp.json()["data"]["record"]["record_id"] record_ids[qid] = rid print(f" {qid}: {rid}") time.sleep(0.5) # Step 3: Wait for automation to finish print("\n=== Step 3: Waiting 30s for automation... ===") for i in range(30, 0, -5): print(f" {i}s remaining...") time.sleep(5) # Step 4: Update all with real jsonData print("\n=== Step 4: Update with real jsonData ===") token = get_token() # refresh token results = {} for qid in sorted(record_ids.keys()): rid = record_ids[qid] json_data = build_json(qid, ALL_QUESTIONS[qid]) json_str = json.dumps(json_data, ensure_ascii=False) print(f" Updating {qid} ({len(json_str)} chars)...") update_resp = requests.put( f"https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{TABLE_ID}/records/{rid}", headers={"Authorization": f"Bearer {token}", "Content-Type": "application/json"}, json={"fields": {"jsonData": json_str}}, ) print(f" update code: {update_resp.json().get('code')}") time.sleep(0.5) # Step 5: Verify after delay print("\n=== Step 5: Wait 30s then verify ===") for i in range(30, 0, -5): print(f" {i}s remaining...") time.sleep(5) token = get_token() print("\n=== Step 6: Final verification ===") all_ok = True for qid, rid in sorted(record_ids.items()): resp = requests.get( f"https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{TABLE_ID}/records/{rid}", headers={"Authorization": f"Bearer {token}"}, ) jd = resp.json()["data"]["record"]["fields"].get("jsonData", "") try: j = json.loads(jd) fq = len(j["first"]["questionSet"]) sq = len(j["second"]["questionSet"]) if fq == 5 and sq == 5: q1 = j["first"]["questionSet"][0]["question"][:50] print(f" ✅ {qid}: {fq}q/{sq}q | Q1=\"{q1}\"") else: print(f" ❌ {qid}: {fq}q/{sq}q | jd={len(jd)}chars") print(f" jd preview: {jd[:200]}") all_ok = False except Exception as e: print(f" ❌ {qid}: {e}") all_ok = False print(f"\n{'✅ ALL INTACT' if all_ok else '❌ SOME CORRUPTED'}")