#!/usr/bin/env python3 """Generate and write F列 component configurations for L1-S2-U17-L4 门关啦""" import subprocess, json, sys # ============================================================ # Get Bot token # ============================================================ APP_SECRET = json.load(open('/root/.openclaw/credentials/xiaoyan/config.json'))['apps'][0]['appSecret'] r = subprocess.run(['curl', '-s', '-X', 'POST', 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal', '-H', 'Content-Type: application/json', '-d', json.dumps({"app_id": "cli_a931175d41799cc7", "app_secret": APP_SECRET})], capture_output=True, text=True) TOKEN = json.loads(r.stdout)['tenant_access_token'] SST = 'It4AsFkC7hXHc4te9yUcyLHRnOe' SID = 'wMQVyV' # ============================================================ # All 16 component configurations → (row, config_text) # ============================================================ configs = [ # 1. Row10: 对话朗读 1217401 — S1主线 "准备回家" (10, """【任务标题】准备回家 【资源配置】无 【情境引入】Alex : Okay. Let's get home. 【互动内容】 (朗读台词) User : I need to get home too. 【后置对话】无"""), # 2. Row15: 对话朗读 1217402 — S2主线 "回不了家了" (15, """【任务标题】回不了家了 【资源配置】无 【情境引入】大门被风吹关上了,Alex 的钥匙和 User 的包都在屋里。 【互动内容】 (朗读台词) User : I can't get home now! 【后置对话】Vicky : Now we are all stuck here."""), # 3. Row36: 对话朗读 1217403 — S4主线 "查看猫门" (36, """【任务标题】查看猫门 【资源配置】无 【情境引入】Vicky : Is it open now? 【互动内容】 (朗读台词) User : Yes. The cat door is open. 【后置对话】无"""), # 4. Row48: 对话挖空 1217404 — S5主线 "拜托Peter" (48, """【任务标题】拜托Peter 【资源配置】无 【情境引入】Vicky : Peter, how about you? 【互动内容】 (听力挖空) User : Please, Peter. We want to ___ ___. 答案词:get home 【互动反馈】 get home 正确 → Vicky : Peter, you're our only hope! get home 错误 → Vicky : Try again. What do we want to do? 【后置对话】Vicky : Peter, you're my best little brother."""), # 5. Row58: 对话挖空-配图 1217405 — S6主线 "称赞Peter" (58, """【任务标题】称赞Peter 【资源配置】【配图】1217405_img 【情境引入】Peter 从猫门钻进了屋子。 【互动内容】 (听力挖空) User : Great! You're ___ now. 答案词:home 【互动反馈】 home 正确 → Alex : Yes! Peter is inside the house. home 错误 → Alex : Listen again. Where is Peter? 【后置对话】无"""), # 6. Row59: 图片单选-配图 1217406 — S7主线 "让Peter开门" (59, """【任务标题】让Peter开门 【资源配置】【配图】1217406_optA.png、1217406_optB.png、1217406_optC.png 【情境引入】Peter 已经进了屋,但需要他帮忙开门。 【互动内容】 题目:What did User ask Peter to do? 选项A:Open the door(正确) - 反馈 Vicky : Yes! We asked Peter to open the door. 选项B:Close the door - 反馈 Vicky : No. We need to get in, not stay out. 选项C:Find the keys - 反馈 Vicky : Hmm, the keys are inside. What did we ask Peter? 【后置对话】Peter : Hmm... Who are you?"""), # 7. Row76: 对话朗读-配图 1217407 — S8主线 "门开了" (76, """【任务标题】门开了 【资源配置】【配图】1217407_img 【情境引入】Vicky 用捉迷藏游戏引诱 Peter 偷看,门果然开了。 【互动内容】 (朗读台词并显示配图) User : Look! The door is open! 【后置对话】无"""), # 8. Row111: 对话选择-配图 1217408 — S10主线 "坏掉的门" (111, """【任务标题】坏掉的门 【资源配置】【配图】1217408_optA.png、1217408_optB.png 【情境引入】Alex : Look. This door is broken. It's always open. 【互动内容】 题目:What is wrong with this door? 选项A:The door is open.(正确) - 反馈 Alex : Right. The door is broken, so it's always open. 选项B:The door is closed. - 反馈 Alex : No. Look again at the door. 【后置对话】User : Let me see who's hiding inside."""), # 9. Row120: 对话选择-配图 1217409 — S11主线 "关闭的房门" (120, """【任务标题】关闭的房门 【资源配置】【配图】1217409_optA.png、1217409_optB.png 【情境引入】Eva : This is Vicky's and my room. 【互动内容】 题目:How is the door? 选项A:The door is open. - 反馈 Eva : No. Look again. Is the door open? 选项B:The door is closed.(正确) - 反馈 Eva : Yes! The door is closed. Someone must be inside. 【后置对话】User : Someone must be hiding in there."""), # 10. Row129: 对话挖空-配图 1217410 — S13主线 "还剩一扇门" (129, """【任务标题】还剩一扇门 【资源配置】【配图】1217410_img 【情境引入】Vicky : Good job! Now, let's find Peter. 【互动内容】 (听力挖空) User : Only one ___ left. 答案词:door 【互动反馈】 door 正确 → Vicky : Right! Only one door left. Peter must be there! door 错误 → Vicky : Let's think. What is left to check? 【后置对话】User : Peter must be in there!"""), # 11. Row133: 对话组句-配图 1217411 — S14主线 "发现门关着" (133, """【任务标题】发现门关着 【资源配置】【配图】1217411_img 【情境引入】终于找到了最后一扇门,但门是关着的。 【互动内容】 (组句) 拼出句子:The door is closed. 【互动反馈】 正确 → Vicky : Yes! The door is closed. Peter is hiding inside! 错误 → Vicky : Let's try again. Is the door open or closed? 【后置对话】无"""), # 12. Row144: 对话组句-配图 1217412 — S15主线 "门打开了" (144, """【任务标题】门打开了 【资源配置】【配图】1217412_img 【情境引入】Alex 和 User 一起用力推开了门,找到了 Peter。 【互动内容】 (组句) 拼出句子:The door is open. 【互动反馈】 正确 → Peter : Haha! You got me! 错误 → Peter : Try again! How is the door now? 【后置对话】无"""), # 13. Row153: 看图拼词 1217413 — S16主线 "修理指南" (153, """【任务标题】修理指南 【资源配置】【配图】1217413_img 【情境引入】Alex : Look, I have a book about doors. 【互动内容】 (看图拼词) 图中是一个关闭的门,拼出对应的单词:closed 答案词:closed 【互动反馈】 正确 → Alex : Correct! Closed doors don't open easily. 错误 → Alex : This word means "not open". Try again. 【后置对话】Alex : Let's fix it."""), # 14. Row169: 对话挖空 1217414 — S17主线 "回忆窗户状态" (169, """【任务标题】回忆窗户状态 【资源配置】无 【情境引入】Alex : That window was closed before the game. 【互动内容】 (听力挖空) User : I remember that. The door was ___ before. 答案词:closed 【互动反馈】 closed 正确 → Alex : Yes! It was closed before. closed 错误 → Alex : Think back. Was the door open or closed? 【后置对话】无"""), # 15. Row170: 对话挖空 1217415 — S18主线 "窗户开着" (170, """【任务标题】窗户开着 【资源配置】无 【情境引入】门之前是关着的,但现在... 【互动内容】 (听力挖空) User : But now it's ___. 答案词:open 【互动反馈】 open 正确 → Alex : Yes! Now it's open. Very strange! open 错误 → Alex : Look now. The door is not closed anymore. 【后置对话】无"""), # 16. Row189: 对话朗读 1217416 — S19主线 "问候Grace和Dan" (189, """【任务标题】问候Grace和Dan 【资源配置】无 【情境引入】Wood 先生和太太终于回家了! 【互动内容】 (朗读台词) User : I'm glad you get home! 【后置对话】Grace : Thank you for staying with the kids!"""), ] # ============================================================ # Write each config to F column using single-cell write # ============================================================ success = 0 fail = 0 for row, text in configs: cell = f"{SID}!F{row}:F{row}" body = json.dumps({"valueRange": {"range": cell, "values": [[text]]}}, ensure_ascii=False) r = subprocess.run(['curl', '-s', '-X', 'PUT', f'https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{SST}/values', '-H', f'Authorization: Bearer {TOKEN}', '-H', 'Content-Type: application/json; charset=utf-8', '-d', body], capture_output=True, text=True) resp = json.loads(r.stdout) if resp.get('code') == 0: success += 1 print(f' ✅ Row {row:3d} | {text.split(chr(10))[0][5:]}') else: fail += 1 print(f' ❌ Row {row:3d} | {resp.get("msg", "unknown")}') print(f'\n写入完成:{success} 成功 / {fail} 失败') # ============================================================ # Verify: read back F column for all configured rows # ============================================================ if fail == 0: print('\n=== 回读验证 ===') for row, _ in configs: cell = f"{SID}!F{row}:F{row}" r = subprocess.run(['curl', '-s', '-X', 'GET', f'https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{SST}/values/{cell}', '-H', f'Authorization: Bearer {TOKEN}'], capture_output=True, text=True) resp = json.loads(r.stdout) vals = resp.get('data', {}).get('valueRange', {}).get('values', [[]]) content = vals[0][0] if vals and vals[0] else None if content: title = content.split('\n')[0].replace('【任务标题】', '') if content else 'EMPTY' print(f' ✅ Row{row}: {title}') else: print(f' ❌ Row{row}: EMPTY!')