gangvy 5 miesięcy temu
rodzic
commit
bdb4837a1a
100 zmienionych plików z 9873 dodań i 2248 usunięć
  1. 23 7
      competitor-analysis/competitor-bsr-tracking/api-config.json
  2. 23 7
      competitor-analysis/competitor-discovery/api-config.json
  3. 23 7
      competitor-analysis/competitor-pricing-analysis/api-config.json
  4. 23 7
      competitor-analysis/competitor-product-comparison/api-config.json
  5. 3 1
      dist/download-urls.json
  6. BIN
      dist/openclaw-all.zip
  7. BIN
      dist/openclaw-voc-skills.zip
  8. 98 23
      dist/skills/asin-reverse-keywords/api-config.json
  9. 98 23
      dist/skills/asin-sales-volume/api-config.json
  10. 183 20
      dist/skills/brand-context-builder/api-config.json
  11. 315 64
      dist/skills/brand-profile/api-config.json
  12. 235 65
      dist/skills/category-landscape/api-config.json
  13. 98 23
      dist/skills/category-products/api-config.json
  14. 98 23
      dist/skills/category-tree/api-config.json
  15. 246 47
      dist/skills/competitor-bsr-tracking/api-config.json
  16. 226 58
      dist/skills/competitor-discovery/api-config.json
  17. 217 57
      dist/skills/competitor-pricing-analysis/api-config.json
  18. 261 53
      dist/skills/competitor-product-comparison/api-config.json
  19. 98 23
      dist/skills/douyin-comment-replies/api-config.json
  20. 121 27
      dist/skills/douyin-general-search/api-config.json
  21. 121 27
      dist/skills/douyin-hashtag-search/api-config.json
  22. 98 23
      dist/skills/douyin-user-profile/api-config.json
  23. 98 23
      dist/skills/douyin-user-search/api-config.json
  24. 98 23
      dist/skills/douyin-video-comments/api-config.json
  25. 98 23
      dist/skills/douyin-video-detail/api-config.json
  26. 153 40
      dist/skills/html-report-generator/api-config.json
  27. 150 39
      dist/skills/instagram-brand-voc/api-config.json
  28. 98 23
      dist/skills/instagram-search/api-config.json
  29. 98 23
      dist/skills/instagram-user-info/api-config.json
  30. 98 23
      dist/skills/instagram-user-posts/api-config.json
  31. 52 24
      dist/skills/jimeng-actor-v2/api-config.json
  32. 52 24
      dist/skills/jimeng-actor/api-config.json
  33. 52 24
      dist/skills/jimeng-clothes-v2/api-config.json
  34. 52 24
      dist/skills/jimeng-img-v4-goods/api-config.json
  35. 52 24
      dist/skills/jimeng-img-v4-pod/api-config.json
  36. 52 24
      dist/skills/jimeng-img-v4/api-config.json
  37. 52 24
      dist/skills/jimeng-img2img-v3/api-config.json
  38. 52 24
      dist/skills/jimeng-inpaint/api-config.json
  39. 52 24
      dist/skills/jimeng-oh-detect/api-config.json
  40. 52 24
      dist/skills/jimeng-oh-generate/api-config.json
  41. 52 24
      dist/skills/jimeng-oh-identify/api-config.json
  42. 52 24
      dist/skills/jimeng-oh-query/api-config.json
  43. 52 24
      dist/skills/jimeng-super-resolution/api-config.json
  44. 52 24
      dist/skills/jimeng-task-query/api-config.json
  45. 52 24
      dist/skills/jimeng-text2img-v3/api-config.json
  46. 52 24
      dist/skills/jimeng-text2img-v31/api-config.json
  47. 52 24
      dist/skills/jimeng-video-v3-1080p/api-config.json
  48. 52 24
      dist/skills/jimeng-video-v3-720p/api-config.json
  49. 52 24
      dist/skills/jimeng-video-v3-pro/api-config.json
  50. 98 23
      dist/skills/keyword-product-ranking/api-config.json
  51. 98 23
      dist/skills/keyword-search-trend/api-config.json
  52. 98 23
      dist/skills/keyword-search/api-config.json
  53. 383 91
      dist/skills/product-deep-analysis/api-config.json
  54. 98 23
      dist/skills/product-detail-query/api-config.json
  55. 98 23
      dist/skills/product-monitor/api-config.json
  56. 98 23
      dist/skills/product-reviews-query/api-config.json
  57. 98 23
      dist/skills/product-search/api-config.json
  58. 243 53
      dist/skills/review-batch-collection/api-config.json
  59. 190 38
      dist/skills/review-highlight-extraction/api-config.json
  60. 185 44
      dist/skills/review-keyword-cloud/api-config.json
  61. 194 43
      dist/skills/review-pain-point-extraction/api-config.json
  62. 267 53
      dist/skills/review-sentiment-analysis/api-config.json
  63. 98 23
      dist/skills/similar-products/api-config.json
  64. 217 48
      dist/skills/social-trend-analysis/api-config.json
  65. 163 42
      dist/skills/tiktok-brand-voc/api-config.json
  66. 179 47
      dist/skills/tiktok-category-voc/api-config.json
  67. 98 23
      dist/skills/tiktok-hashtag-detail/api-config.json
  68. 98 23
      dist/skills/tiktok-hashtag-videos/api-config.json
  69. 98 23
      dist/skills/tiktok-user-posts/api-config.json
  70. 98 23
      dist/skills/tiktok-user-profile/api-config.json
  71. 98 23
      dist/skills/tiktok-user-search/api-config.json
  72. 98 23
      dist/skills/tiktok-video-comments/api-config.json
  73. 98 23
      dist/skills/tiktok-video-detail/api-config.json
  74. 98 23
      dist/skills/tiktok-video-search/api-config.json
  75. 236 0
      dist/skills/transcript-to-video/SKILL.md
  76. 529 0
      dist/skills/transcript-to-video/api-config.json
  77. 193 48
      dist/skills/user-persona/api-config.json
  78. 232 54
      dist/skills/voc-proposal/api-config.json
  79. BIN
      dist/social-media.zip
  80. BIN
      dist/voc-core.zip
  81. BIN
      dist/workshop.zip
  82. 258 0
      docs/voc-forward-403-决策报告.md
  83. 20 4
      douyin/douyin-comment-replies/api-config.json
  84. 20 4
      douyin/douyin-general-search/api-config.json
  85. 20 4
      douyin/douyin-hashtag-search/api-config.json
  86. 20 4
      douyin/douyin-user-profile/api-config.json
  87. 20 4
      douyin/douyin-user-search/api-config.json
  88. 20 4
      douyin/douyin-video-comments/api-config.json
  89. 20 4
      douyin/douyin-video-detail/api-config.json
  90. 19 3
      jimeng/jimeng-actor-v2/api-config.json
  91. 19 3
      jimeng/jimeng-actor/api-config.json
  92. 19 3
      jimeng/jimeng-clothes-v2/api-config.json
  93. 19 3
      jimeng/jimeng-img-v4-goods/api-config.json
  94. 19 3
      jimeng/jimeng-img-v4-pod/api-config.json
  95. 19 3
      jimeng/jimeng-img-v4/api-config.json
  96. 19 3
      jimeng/jimeng-img2img-v3/api-config.json
  97. 19 3
      jimeng/jimeng-inpaint/api-config.json
  98. 19 3
      jimeng/jimeng-oh-detect/api-config.json
  99. 19 3
      jimeng/jimeng-oh-generate/api-config.json
  100. 19 3
      jimeng/jimeng-oh-identify/api-config.json

+ 23 - 7
competitor-analysis/competitor-bsr-tracking/api-config.json

@@ -281,13 +281,13 @@
     "resolutionOrder": [
       "configFile"
     ],
-    "apigId": "Vo3ROWEvDy",
+    "apigId": "7HwdQZk55B",
     "paymentUrlResolution": {
       "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
       "steps": [
         "1. 从 voc-credentials.json 获取当前 session token",
         "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
-        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
         "4. 将该URL展示给用户,引导扫码支付"
       ],
       "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
@@ -298,14 +298,14 @@
       "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
       "paymentParams": {
         "user": "{resolvedUserId}",
-        "apigid": "Vo3ROWEvDy",
+        "apigid": "7HwdQZk55B",
         "fun_id": "HOkkX72PMF"
       },
       "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
     },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
       "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
       "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
@@ -338,7 +338,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -347,7 +361,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],
@@ -379,4 +395,4 @@
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 23 - 7
competitor-analysis/competitor-discovery/api-config.json

@@ -308,13 +308,13 @@
     "resolutionOrder": [
       "configFile"
     ],
-    "apigId": "Vo3ROWEvDy",
+    "apigId": "7HwdQZk55B",
     "paymentUrlResolution": {
       "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
       "steps": [
         "1. 从 voc-credentials.json 获取当前 session token",
         "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
-        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
         "4. 将该URL展示给用户,引导扫码支付"
       ],
       "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
@@ -325,14 +325,14 @@
       "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
       "paymentParams": {
         "user": "{resolvedUserId}",
-        "apigid": "Vo3ROWEvDy",
+        "apigid": "7HwdQZk55B",
         "fun_id": "HOkkX72PMF"
       },
       "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
     },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
       "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
       "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
@@ -365,7 +365,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -374,7 +388,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],
@@ -406,4 +422,4 @@
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 23 - 7
competitor-analysis/competitor-pricing-analysis/api-config.json

@@ -265,13 +265,13 @@
     "resolutionOrder": [
       "configFile"
     ],
-    "apigId": "Vo3ROWEvDy",
+    "apigId": "7HwdQZk55B",
     "paymentUrlResolution": {
       "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
       "steps": [
         "1. 从 voc-credentials.json 获取当前 session token",
         "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
-        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
         "4. 将该URL展示给用户,引导扫码支付"
       ],
       "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
@@ -282,14 +282,14 @@
       "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
       "paymentParams": {
         "user": "{resolvedUserId}",
-        "apigid": "Vo3ROWEvDy",
+        "apigid": "7HwdQZk55B",
         "fun_id": "HOkkX72PMF"
       },
       "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
     },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
       "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
       "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
@@ -322,7 +322,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -331,7 +345,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],
@@ -363,4 +379,4 @@
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 23 - 7
competitor-analysis/competitor-product-comparison/api-config.json

@@ -300,13 +300,13 @@
     "resolutionOrder": [
       "configFile"
     ],
-    "apigId": "Vo3ROWEvDy",
+    "apigId": "7HwdQZk55B",
     "paymentUrlResolution": {
       "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
       "steps": [
         "1. 从 voc-credentials.json 获取当前 session token",
         "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
-        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
         "4. 将该URL展示给用户,引导扫码支付"
       ],
       "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
@@ -317,14 +317,14 @@
       "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
       "paymentParams": {
         "user": "{resolvedUserId}",
-        "apigid": "Vo3ROWEvDy",
+        "apigid": "7HwdQZk55B",
         "fun_id": "HOkkX72PMF"
       },
       "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
     },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
       "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
       "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
@@ -357,7 +357,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -366,7 +380,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],
@@ -398,4 +414,4 @@
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 3 - 1
dist/download-urls.json

@@ -1,4 +1,6 @@
 {
   "voc-core": "https://repos.fmode.cn/x/openclaw-skills/packages/voc-core.zip",
-  "social-media": "https://repos.fmode.cn/x/openclaw-skills/packages/social-media.zip"
+  "social-media": "https://repos.fmode.cn/x/openclaw-skills/packages/social-media.zip",
+  "workshop": "https://repos.fmode.cn/x/openclaw-skills/packages/workshop.zip",
+  "openclaw-all": "https://repos.fmode.cn/x/openclaw-skills/packages/openclaw-all.zip"
 }

BIN
dist/openclaw-all.zip


BIN
dist/openclaw-voc-skills.zip


+ 98 - 23
dist/skills/asin-reverse-keywords/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "asin-reverse-keywords",
   "displayName": "ASIN 反查关键词",
   "description": "根据 ASIN 反向查询该产品关联的搜索关键词列表,包括搜索排名、搜索量等。用于竞品关键词策略分析、广告关键词挖掘。",
@@ -9,7 +9,7 @@
     "url": "https://server.fmode.cn/api/voc-ecom/forward",
     "headers": {
       "Content-Type": "application/json",
-    "Authorization": "Bearer {{vocToken}}"
+      "Authorization": "Bearer {{vocToken}}"
     }
   },
   "parameters": {
@@ -97,46 +97,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "7HwdQZk55B",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "7HwdQZk55B",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 98 - 23
dist/skills/asin-sales-volume/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "asin-sales-volume",
   "displayName": "ASIN 销量查询",
   "description": "查询指定 ASIN 的销量数据,包括日销量、周销量、月销量趋势。用于市场规模估算、品类销售额计算。",
@@ -9,7 +9,7 @@
     "url": "https://server.fmode.cn/api/voc-ecom/forward",
     "headers": {
       "Content-Type": "application/json",
-    "Authorization": "Bearer {{vocToken}}"
+      "Authorization": "Bearer {{vocToken}}"
     }
   },
   "parameters": {
@@ -99,46 +99,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "7HwdQZk55B",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "7HwdQZk55B",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 183 - 20
dist/skills/brand-context-builder/api-config.json

@@ -12,7 +12,10 @@
       "mode": {
         "type": "string",
         "description": "建档模式: full=完整建档(默认), update=增量更新",
-        "enum": ["full", "update"],
+        "enum": [
+          "full",
+          "update"
+        ],
         "default": "full"
       },
       "brandName": {
@@ -21,38 +24,56 @@
       },
       "categoryKeywords": {
         "type": "array",
-        "items": { "type": "string" },
+        "items": {
+          "type": "string"
+        },
         "description": "品类核心英文关键词,至少1个,建议2-3个"
       },
       "amazonDomain": {
         "type": "integer",
         "description": "Amazon站点: 1=US(默认) 2=UK 3=DE 4=JP",
         "default": 1,
-        "enum": [1, 2, 3, 4]
+        "enum": [
+          1,
+          2,
+          3,
+          4
+        ]
       },
       "brandAsins": {
         "type": "array",
-        "items": { "type": "string", "pattern": "^B0[A-Z0-9]{8}$" },
+        "items": {
+          "type": "string",
+          "pattern": "^B0[A-Z0-9]{8}$"
+        },
         "description": "品牌代表性ASIN列表,3-5个,B0开头10位"
       },
       "knownCompetitors": {
         "type": "array",
-        "items": { "type": "string" },
+        "items": {
+          "type": "string"
+        },
         "description": "已知竞品品牌名(可选)"
       },
       "competitorAsins": {
         "type": "array",
-        "items": { "type": "string" },
+        "items": {
+          "type": "string"
+        },
         "description": "已知竞品ASIN(可选)"
       },
       "tiktokKeywords": {
         "type": "array",
-        "items": { "type": "string" },
+        "items": {
+          "type": "string"
+        },
         "description": "TikTok搜索关键词(可选,Session 4补充)"
       },
       "douyinKeywords": {
         "type": "array",
-        "items": { "type": "string" },
+        "items": {
+          "type": "string"
+        },
         "description": "抖音搜索关键词(可选,Session 4补充)"
       },
       "workshopGoal": {
@@ -77,10 +98,18 @@
     "type": "object",
     "description": "品牌上下文对象,写入 memory/brand-context.json",
     "properties": {
-      "success": { "type": "boolean" },
-      "brandContext": { "type": "object" },
-      "readyForSession1": { "type": "boolean" },
-      "missingFields": { "type": "array" }
+      "success": {
+        "type": "boolean"
+      },
+      "brandContext": {
+        "type": "object"
+      },
+      "readyForSession1": {
+        "type": "boolean"
+      },
+      "missingFields": {
+        "type": "array"
+      }
     }
   },
   "memoryFiles": {
@@ -97,9 +126,16 @@
       "input": {
         "mode": "full",
         "brandName": "COCORRINA",
-        "categoryKeywords": ["reed diffuser", "aroma diffuser"],
+        "categoryKeywords": [
+          "reed diffuser",
+          "aroma diffuser"
+        ],
         "amazonDomain": 1,
-        "brandAsins": ["B0CJ5KXXXX", "B0DJ6LYYYY", "B0EK7MZZZZ"],
+        "brandAsins": [
+          "B0CJ5KXXXX",
+          "B0DJ6LYYYY",
+          "B0EK7MZZZZ"
+        ],
         "workshopGoal": "想了解品类机会和用户真正在意什么"
       },
       "description": "新客户首次建档,采集全部必要信息"
@@ -108,8 +144,14 @@
       "name": "增量更新-补充竞品",
       "input": {
         "mode": "update",
-        "knownCompetitors": ["NEST New York", "Yankee Candle"],
-        "competitorAsins": ["B0AAAA1111", "B0BBBB2222"]
+        "knownCompetitors": [
+          "NEST New York",
+          "Yankee Candle"
+        ],
+        "competitorAsins": [
+          "B0AAAA1111",
+          "B0BBBB2222"
+        ]
       },
       "description": "Session 2 后补充确认的竞品信息"
     },
@@ -117,8 +159,14 @@
       "name": "增量更新-补充社媒关键词",
       "input": {
         "mode": "update",
-        "tiktokKeywords": ["reed diffuser", "#homedecor"],
-        "douyinKeywords": ["香薰", "无火香薰"]
+        "tiktokKeywords": [
+          "reed diffuser",
+          "#homedecor"
+        ],
+        "douyinKeywords": [
+          "香薰",
+          "无火香薰"
+        ]
       },
       "description": "Session 4 前补充社媒搜索关键词"
     }
@@ -132,9 +180,124 @@
     "completeness": "建档完整度"
   },
   "tokenConfig": {
-    "required": false
+    "type": "bearer",
+    "configFile": "~/.openclaw/voc-credentials.json",
+    "tokenField": "vocToken",
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
+    "onMissing": {
+      "action": "showPaymentQR",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+      "title": "扫码开通 VOC-AI 数据服务",
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
+    },
+    "onBalanceInsufficient": {
+      "action": "resolveUserThenShowPayment",
+      "title": "VOC-AI Token 余额不足,请扫码充值",
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
+    }
   },
   "errorHandling": {
-    "conditions": []
+    "balanceInsufficient": {
+      "conditions": [
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
+      ],
+      "matchMode": "any",
+      "trigger": "tokenConfig.onBalanceInsufficient"
+    },
+    "unauthorized": {
+      "conditions": [
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
+      ],
+      "matchMode": "any",
+      "trigger": "tokenConfig.onMissing"
+    }
   }
 }

+ 315 - 64
dist/skills/brand-profile/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "brand-profile",
   "displayName": "品牌六维画像",
   "description": "生成品牌六维量化画像,标注机会/风险标签、识别核心短板、输出竞争定位建议和《品牌认知校准卡》",
@@ -13,7 +13,9 @@
     },
     "brandAsins": {
       "type": "array",
-      "items": { "type": "string" },
+      "items": {
+        "type": "string"
+      },
       "required": true,
       "description": "品牌核心ASIN列表"
     },
@@ -44,9 +46,18 @@
         "endpoint": "/api/ProductRequest",
         "method": "POST",
         "forwardUrl": "https://server.fmode.cn/api/voc-ecom/forward",
-        "headers": { "Authorization": "Bearer {{vocToken}}" },
-        "requestBody": { "ASIN": "${asin}", "Trend": 1, "QueryTrendStartDt": "", "QueryTrendEndDt": "" },
-        "queryParams": { "domain": "${domain}" }
+        "headers": {
+          "Authorization": "Bearer {{vocToken}}"
+        },
+        "requestBody": {
+          "ASIN": "${asin}",
+          "Trend": 1,
+          "QueryTrendStartDt": "",
+          "QueryTrendEndDt": ""
+        },
+        "queryParams": {
+          "domain": "${domain}"
+        }
       },
       "output": "productDetails",
       "responseExtract": "{ Title, Brand, SalesPrice, Ratings, RatingsCount, BSR, Category, MonthlySales, fiveStartRatings, fourStartRatings, threeStartRatings, twoStartRatings, oneStartRatings }"
@@ -59,8 +70,12 @@
         "service": "SorftimeApiService.getAsinSalesVolume",
         "endpoint": "/api/AsinSalesVolume",
         "method": "POST",
-        "requestBody": { "ASIN": "${asin}" },
-        "queryParams": { "domain": "${domain}" }
+        "requestBody": {
+          "ASIN": "${asin}"
+        },
+        "queryParams": {
+          "domain": "${domain}"
+        }
       },
       "output": "salesData"
     },
@@ -73,9 +88,16 @@
         "endpoint": "/api/ProductReviewsQuery",
         "method": "POST",
         "forwardUrl": "https://server.fmode.cn/api/voc-ecom/forward",
-        "headers": { "Authorization": "Bearer {{vocToken}}" },
-        "requestBody": { "ASIN": "${asin}", "PageIndex": "1" },
-        "queryParams": { "domain": "${domain}" }
+        "headers": {
+          "Authorization": "Bearer {{vocToken}}"
+        },
+        "requestBody": {
+          "ASIN": "${asin}",
+          "PageIndex": "1"
+        },
+        "queryParams": {
+          "domain": "${domain}"
+        }
       },
       "output": "reviewSamples"
     },
@@ -88,9 +110,18 @@
         "endpoint": "/api/ProductQuery",
         "method": "POST",
         "forwardUrl": "https://server.fmode.cn/api/voc-ecom/forward",
-        "headers": { "Authorization": "Bearer {{vocToken}}" },
-        "requestBody": { "Page": 1, "Query": "1", "QueryType": "7", "Pattern": "${categoryKeyword}" },
-        "queryParams": { "domain": "${domain}" }
+        "headers": {
+          "Authorization": "Bearer {{vocToken}}"
+        },
+        "requestBody": {
+          "Page": 1,
+          "Query": "1",
+          "QueryType": "7",
+          "Pattern": "${categoryKeyword}"
+        },
+        "queryParams": {
+          "domain": "${domain}"
+        }
       },
       "output": "categoryBaseline"
     },
@@ -100,12 +131,30 @@
       "type": "compute",
       "logic": "calcSixDimensions(productDetails, salesData, reviewSamples, categoryBaseline || categoryLandscape)",
       "algorithm": {
-        "pricing": { "weight": 0.20, "method": "品牌均价 vs 品类中位价的偏离度" },
-        "rating": { "weight": 0.20, "method": "平均评分 + 差评率(1-2星占比)" },
-        "traffic": { "weight": 0.15, "method": "BSR中位数在品类中的百分位" },
-        "salesEfficiency": { "weight": 0.15, "method": "品牌月销量 vs 品类均值" },
-        "growthPotential": { "weight": 0.15, "method": "新品比例 + 销量趋势 + 品类CR5位置" },
-        "vocReputation": { "weight": 0.15, "method": "好评率 + 评论增速 + Helpful比例" }
+        "pricing": {
+          "weight": 0.2,
+          "method": "品牌均价 vs 品类中位价的偏离度"
+        },
+        "rating": {
+          "weight": 0.2,
+          "method": "平均评分 + 差评率(1-2星占比)"
+        },
+        "traffic": {
+          "weight": 0.15,
+          "method": "BSR中位数在品类中的百分位"
+        },
+        "salesEfficiency": {
+          "weight": 0.15,
+          "method": "品牌月销量 vs 品类均值"
+        },
+        "growthPotential": {
+          "weight": 0.15,
+          "method": "新品比例 + 销量趋势 + 品类CR5位置"
+        },
+        "vocReputation": {
+          "weight": 0.15,
+          "method": "好评率 + 评论增速 + Helpful比例"
+        }
       },
       "output": "dimensions"
     },
@@ -127,41 +176,161 @@
   "response": {
     "type": "object",
     "properties": {
-      "brandName": { "type": "string" },
+      "brandName": {
+        "type": "string"
+      },
       "dimensions": {
         "type": "object",
         "description": "六维评分",
         "properties": {
-          "pricing": { "type": "object", "properties": { "score": { "type": "integer" }, "label": { "type": "string" }, "detail": { "type": "string" } } },
-          "rating": { "type": "object", "properties": { "score": { "type": "integer" }, "label": { "type": "string" }, "detail": { "type": "string" } } },
-          "traffic": { "type": "object", "properties": { "score": { "type": "integer" }, "label": { "type": "string" }, "detail": { "type": "string" } } },
-          "salesEfficiency": { "type": "object", "properties": { "score": { "type": "integer" }, "label": { "type": "string" }, "detail": { "type": "string" } } },
-          "growthPotential": { "type": "object", "properties": { "score": { "type": "integer" }, "label": { "type": "string" }, "detail": { "type": "string" } } },
-          "vocReputation": { "type": "object", "properties": { "score": { "type": "integer" }, "label": { "type": "string" }, "detail": { "type": "string" } } }
+          "pricing": {
+            "type": "object",
+            "properties": {
+              "score": {
+                "type": "integer"
+              },
+              "label": {
+                "type": "string"
+              },
+              "detail": {
+                "type": "string"
+              }
+            }
+          },
+          "rating": {
+            "type": "object",
+            "properties": {
+              "score": {
+                "type": "integer"
+              },
+              "label": {
+                "type": "string"
+              },
+              "detail": {
+                "type": "string"
+              }
+            }
+          },
+          "traffic": {
+            "type": "object",
+            "properties": {
+              "score": {
+                "type": "integer"
+              },
+              "label": {
+                "type": "string"
+              },
+              "detail": {
+                "type": "string"
+              }
+            }
+          },
+          "salesEfficiency": {
+            "type": "object",
+            "properties": {
+              "score": {
+                "type": "integer"
+              },
+              "label": {
+                "type": "string"
+              },
+              "detail": {
+                "type": "string"
+              }
+            }
+          },
+          "growthPotential": {
+            "type": "object",
+            "properties": {
+              "score": {
+                "type": "integer"
+              },
+              "label": {
+                "type": "string"
+              },
+              "detail": {
+                "type": "string"
+              }
+            }
+          },
+          "vocReputation": {
+            "type": "object",
+            "properties": {
+              "score": {
+                "type": "integer"
+              },
+              "label": {
+                "type": "string"
+              },
+              "detail": {
+                "type": "string"
+              }
+            }
+          }
         }
       },
-      "overallScore": { "type": "number" },
+      "overallScore": {
+        "type": "number"
+      },
       "positioning": {
         "type": "object",
         "properties": {
-          "quadrant": { "type": "string" },
-          "x": { "type": "number" },
-          "y": { "type": "number" },
-          "xLabel": { "type": "string" },
-          "yLabel": { "type": "string" }
+          "quadrant": {
+            "type": "string"
+          },
+          "x": {
+            "type": "number"
+          },
+          "y": {
+            "type": "number"
+          },
+          "xLabel": {
+            "type": "string"
+          },
+          "yLabel": {
+            "type": "string"
+          }
+        }
+      },
+      "strengths": {
+        "type": "array",
+        "items": {
+          "type": "string"
+        }
+      },
+      "weaknesses": {
+        "type": "array",
+        "items": {
+          "type": "string"
+        }
+      },
+      "opportunityTags": {
+        "type": "array",
+        "items": {
+          "type": "string"
+        }
+      },
+      "riskTags": {
+        "type": "array",
+        "items": {
+          "type": "string"
         }
       },
-      "strengths": { "type": "array", "items": { "type": "string" } },
-      "weaknesses": { "type": "array", "items": { "type": "string" } },
-      "opportunityTags": { "type": "array", "items": { "type": "string" } },
-      "riskTags": { "type": "array", "items": { "type": "string" } },
       "coreShortcoming": {
         "type": "object",
         "properties": {
-          "dimension": { "type": "string" },
-          "score": { "type": "integer" },
-          "diagnosis": { "type": "string" },
-          "advice": { "type": "string" }
+          "dimension": {
+            "type": "string"
+          },
+          "score": {
+            "type": "integer"
+          },
+          "diagnosis": {
+            "type": "string"
+          },
+          "advice": {
+            "type": "string"
+          }
         }
       },
       "priorityActions": {
@@ -169,12 +338,19 @@
         "items": {
           "type": "object",
           "properties": {
-            "action": { "type": "string" },
-            "priority": { "type": "integer" }
+            "action": {
+              "type": "string"
+            },
+            "priority": {
+              "type": "integer"
+            }
           }
         }
       },
-      "calibrationCard": { "type": "string", "description": "品牌认知校准卡(Markdown格式)" }
+      "calibrationCard": {
+        "type": "string",
+        "description": "品牌认知校准卡(Markdown格式)"
+      }
     }
   },
   "timeout": 300000,
@@ -187,46 +363,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "7HwdQZk55B",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "7HwdQZk55B",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 235 - 65
dist/skills/category-landscape/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "category-landscape",
   "displayName": "品类格局分析",
   "description": "品类全景分析,计算CR5/HHI市场集中度,生成风险预警汇总和优先行动清单,输出《品类认知校准表》",
@@ -8,7 +8,9 @@
   "parameters": {
     "keywords": {
       "type": "array",
-      "items": { "type": "string" },
+      "items": {
+        "type": "string"
+      },
       "required": true,
       "description": "品类核心关键词列表"
     },
@@ -35,9 +37,18 @@
         "endpoint": "/api/ProductQuery",
         "method": "POST",
         "forwardUrl": "https://server.fmode.cn/api/voc-ecom/forward",
-        "headers": { "Authorization": "Bearer {{vocToken}}" },
-        "requestBody": { "Page": 1, "Query": "1", "QueryType": "7", "Pattern": "${keyword}" },
-        "queryParams": { "domain": "${domain}" }
+        "headers": {
+          "Authorization": "Bearer {{vocToken}}"
+        },
+        "requestBody": {
+          "Page": 1,
+          "Query": "1",
+          "QueryType": "7",
+          "Pattern": "${keyword}"
+        },
+        "queryParams": {
+          "domain": "${domain}"
+        }
       },
       "output": "searchResults",
       "responseExtract": "Array<{ Asin, Title, Price, Rating, RatingsCount, MonthlySales, Brand, BSR, Photo }>"
@@ -50,8 +61,12 @@
         "service": "SorftimeApiService.getAsinSalesVolume",
         "endpoint": "/api/AsinSalesVolume",
         "method": "POST",
-        "requestBody": { "ASIN": "${asin}" },
-        "queryParams": { "domain": "${domain}" }
+        "requestBody": {
+          "ASIN": "${asin}"
+        },
+        "queryParams": {
+          "domain": "${domain}"
+        }
       },
       "output": "salesData"
     },
@@ -62,8 +77,12 @@
         "service": "SorftimeApiService.getCategoryTree",
         "endpoint": "/api/CategoryTree",
         "method": "POST",
-        "requestBody": { "keyword": "${keywords[0]}" },
-        "queryParams": { "domain": "${domain}" }
+        "requestBody": {
+          "keyword": "${keywords[0]}"
+        },
+        "queryParams": {
+          "domain": "${domain}"
+        }
       },
       "output": "categoryTree"
     },
@@ -75,8 +94,12 @@
         "service": "SorftimeApiService.searchKeywords",
         "endpoint": "/api/KeywordQuery",
         "method": "POST",
-        "requestBody": { "Keyword": "${keyword}" },
-        "queryParams": { "domain": "${domain}" }
+        "requestBody": {
+          "Keyword": "${keyword}"
+        },
+        "queryParams": {
+          "domain": "${domain}"
+        }
       },
       "output": "keywordData"
     },
@@ -88,8 +111,12 @@
         "service": "SorftimeApiService.getKeywordTrend",
         "endpoint": "/api/KeywordSearchTrend",
         "method": "POST",
-        "requestBody": { "Keyword": "${keyword}" },
-        "queryParams": { "domain": "${domain}" }
+        "requestBody": {
+          "Keyword": "${keyword}"
+        },
+        "queryParams": {
+          "domain": "${domain}"
+        }
       },
       "output": "keywordTrend"
     },
@@ -143,22 +170,44 @@
       "marketOverview": {
         "type": "object",
         "properties": {
-          "totalProducts": { "type": "integer" },
-          "totalMonthlySales": { "type": "integer" },
-          "totalMonthlyRevenue": { "type": "number" },
-          "avgPrice": { "type": "number" },
-          "medianPrice": { "type": "number" },
-          "avgRating": { "type": "number" },
-          "categoryStage": { "type": "string" }
+          "totalProducts": {
+            "type": "integer"
+          },
+          "totalMonthlySales": {
+            "type": "integer"
+          },
+          "totalMonthlyRevenue": {
+            "type": "number"
+          },
+          "avgPrice": {
+            "type": "number"
+          },
+          "medianPrice": {
+            "type": "number"
+          },
+          "avgRating": {
+            "type": "number"
+          },
+          "categoryStage": {
+            "type": "string"
+          }
         }
       },
       "concentration": {
         "type": "object",
         "properties": {
-          "cr5": { "type": "number" },
-          "cr10": { "type": "number" },
-          "hhi": { "type": "integer" },
-          "interpretation": { "type": "string" }
+          "cr5": {
+            "type": "number"
+          },
+          "cr10": {
+            "type": "number"
+          },
+          "hhi": {
+            "type": "integer"
+          },
+          "interpretation": {
+            "type": "string"
+          }
         }
       },
       "topBrands": {
@@ -166,11 +215,21 @@
         "items": {
           "type": "object",
           "properties": {
-            "brand": { "type": "string" },
-            "marketShare": { "type": "number" },
-            "productCount": { "type": "integer" },
-            "avgPrice": { "type": "number" },
-            "avgRating": { "type": "number" }
+            "brand": {
+              "type": "string"
+            },
+            "marketShare": {
+              "type": "number"
+            },
+            "productCount": {
+              "type": "integer"
+            },
+            "avgPrice": {
+              "type": "number"
+            },
+            "avgRating": {
+              "type": "number"
+            }
           }
         }
       },
@@ -179,31 +238,61 @@
         "items": {
           "type": "object",
           "properties": {
-            "range": { "type": "string" },
-            "productCount": { "type": "integer" },
-            "salesShare": { "type": "number" },
-            "avgRating": { "type": "number" }
+            "range": {
+              "type": "string"
+            },
+            "productCount": {
+              "type": "integer"
+            },
+            "salesShare": {
+              "type": "number"
+            },
+            "avgRating": {
+              "type": "number"
+            }
           }
         }
       },
       "searchTrend": {
         "type": "object",
         "properties": {
-          "mainKeyword": { "type": "string" },
-          "monthlySearchVolume": { "type": "integer" },
-          "trendDirection": { "type": "string" },
-          "growthRate": { "type": "number" }
+          "mainKeyword": {
+            "type": "string"
+          },
+          "monthlySearchVolume": {
+            "type": "integer"
+          },
+          "trendDirection": {
+            "type": "string"
+          },
+          "growthRate": {
+            "type": "number"
+          }
         }
       },
-      "calibrationTable": { "type": "string", "description": "品类认知校准表(Markdown格式)" },
+      "calibrationTable": {
+        "type": "string",
+        "description": "品类认知校准表(Markdown格式)"
+      },
       "riskAlerts": {
         "type": "array",
         "items": {
           "type": "object",
           "properties": {
-            "level": { "type": "string", "enum": ["high", "medium", "low"] },
-            "title": { "type": "string" },
-            "description": { "type": "string" }
+            "level": {
+              "type": "string",
+              "enum": [
+                "high",
+                "medium",
+                "low"
+              ]
+            },
+            "title": {
+              "type": "string"
+            },
+            "description": {
+              "type": "string"
+            }
           }
         }
       },
@@ -212,9 +301,15 @@
         "items": {
           "type": "object",
           "properties": {
-            "action": { "type": "string" },
-            "priority": { "type": "integer" },
-            "trigger": { "type": "string" }
+            "action": {
+              "type": "string"
+            },
+            "priority": {
+              "type": "integer"
+            },
+            "trigger": {
+              "type": "string"
+            }
           }
         }
       }
@@ -230,46 +325,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "7HwdQZk55B",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "7HwdQZk55B",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 98 - 23
dist/skills/category-products/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "category-products",
   "displayName": "Amazon 类目产品查询",
   "description": "根据类目 ID 获取该类目下的产品列表。用于获取品类 Top 产品、分析品类竞争格局、统计品牌分布和中国卖家占比。",
@@ -9,7 +9,7 @@
     "url": "https://server.fmode.cn/api/voc-ecom/forward",
     "headers": {
       "Content-Type": "application/json",
-    "Authorization": "Bearer {{vocToken}}"
+      "Authorization": "Bearer {{vocToken}}"
     }
   },
   "parameters": {
@@ -111,46 +111,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "7HwdQZk55B",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "7HwdQZk55B",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 98 - 23
dist/skills/category-tree/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "category-tree",
   "displayName": "Amazon 类目树查询",
   "description": "获取 Amazon 类目层级树结构,用于定位目标品类的类目 ID,再通过 category_products 获取该类目下的产品列表。",
@@ -9,7 +9,7 @@
     "url": "https://server.fmode.cn/api/voc-ecom/forward",
     "headers": {
       "Content-Type": "application/json",
-    "Authorization": "Bearer {{vocToken}}"
+      "Authorization": "Bearer {{vocToken}}"
     }
   },
   "parameters": {
@@ -83,46 +83,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "7HwdQZk55B",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "7HwdQZk55B",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 246 - 47
dist/skills/competitor-bsr-tracking/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "competitor-bsr-tracking",
   "displayName": "竞品BSR排名追踪",
   "description": "追踪竞品BSR/销量/价格变化趋势,生成增长路径分析和风险预警汇总",
@@ -8,7 +8,9 @@
   "parameters": {
     "competitorAsins": {
       "type": "array",
-      "items": { "type": "string" },
+      "items": {
+        "type": "string"
+      },
       "required": true,
       "description": "竞品ASIN列表"
     },
@@ -29,9 +31,15 @@
         "endpoint": "/api/MonitorQuery",
         "method": "POST",
         "forwardUrl": "https://server.fmode.cn/api/voc-ecom/forward",
-        "headers": { "Authorization": "Bearer {{vocToken}}" },
-        "requestBody": { "ASIN": "${asin}" },
-        "queryParams": { "domain": "${domain}" }
+        "headers": {
+          "Authorization": "Bearer {{vocToken}}"
+        },
+        "requestBody": {
+          "ASIN": "${asin}"
+        },
+        "queryParams": {
+          "domain": "${domain}"
+        }
       },
       "output": "monitorData",
       "responseExtract": "{ PriceHistory, RankHistory, RatingHistory, ReviewCountHistory, SellerCount }"
@@ -45,9 +53,18 @@
         "endpoint": "/api/ProductRequest",
         "method": "POST",
         "forwardUrl": "https://server.fmode.cn/api/voc-ecom/forward",
-        "headers": { "Authorization": "Bearer {{vocToken}}" },
-        "requestBody": { "ASIN": "${asin}", "Trend": 1, "QueryTrendStartDt": "", "QueryTrendEndDt": "" },
-        "queryParams": { "domain": "${domain}" }
+        "headers": {
+          "Authorization": "Bearer {{vocToken}}"
+        },
+        "requestBody": {
+          "ASIN": "${asin}",
+          "Trend": 1,
+          "QueryTrendStartDt": "",
+          "QueryTrendEndDt": ""
+        },
+        "queryParams": {
+          "domain": "${domain}"
+        }
       },
       "output": "competitorDetails",
       "responseExtract": "{ Title, Brand, SalesPrice, Ratings, RatingsCount, BSR, MonthlySales, Category }"
@@ -103,32 +120,128 @@
         "items": {
           "type": "object",
           "properties": {
-            "asin": { "type": "string" },
-            "brand": { "type": "string" },
-            "currentBsr": { "type": "integer" },
-            "bsrTrend": { "type": "object", "properties": { "7d": { "type": "number" }, "14d": { "type": "number" }, "30d": { "type": "number" } } },
-            "salesTrend": { "type": "object", "properties": { "7d": { "type": "number" }, "14d": { "type": "number" }, "30d": { "type": "number" } } },
-            "priceChange": { "type": "object", "properties": { "current": { "type": "number" }, "previous": { "type": "number" }, "changePercent": { "type": "number" } } },
-            "ratingChange": { "type": "object", "properties": { "current": { "type": "number" }, "previous": { "type": "number" }, "newReviews": { "type": "integer" } } },
-            "alerts": { "type": "array", "items": { "type": "object", "properties": { "type": { "type": "string" }, "severity": { "type": "string" }, "message": { "type": "string" } } } }
+            "asin": {
+              "type": "string"
+            },
+            "brand": {
+              "type": "string"
+            },
+            "currentBsr": {
+              "type": "integer"
+            },
+            "bsrTrend": {
+              "type": "object",
+              "properties": {
+                "7d": {
+                  "type": "number"
+                },
+                "14d": {
+                  "type": "number"
+                },
+                "30d": {
+                  "type": "number"
+                }
+              }
+            },
+            "salesTrend": {
+              "type": "object",
+              "properties": {
+                "7d": {
+                  "type": "number"
+                },
+                "14d": {
+                  "type": "number"
+                },
+                "30d": {
+                  "type": "number"
+                }
+              }
+            },
+            "priceChange": {
+              "type": "object",
+              "properties": {
+                "current": {
+                  "type": "number"
+                },
+                "previous": {
+                  "type": "number"
+                },
+                "changePercent": {
+                  "type": "number"
+                }
+              }
+            },
+            "ratingChange": {
+              "type": "object",
+              "properties": {
+                "current": {
+                  "type": "number"
+                },
+                "previous": {
+                  "type": "number"
+                },
+                "newReviews": {
+                  "type": "integer"
+                }
+              }
+            },
+            "alerts": {
+              "type": "array",
+              "items": {
+                "type": "object",
+                "properties": {
+                  "type": {
+                    "type": "string"
+                  },
+                  "severity": {
+                    "type": "string"
+                  },
+                  "message": {
+                    "type": "string"
+                  }
+                }
+              }
+            }
           }
         }
       },
       "summary": {
         "type": "object",
         "properties": {
-          "mostActive": { "type": "string" },
-          "biggestThreat": { "type": "string" },
-          "opportunityWindow": { "type": "string" }
+          "mostActive": {
+            "type": "string"
+          },
+          "biggestThreat": {
+            "type": "string"
+          },
+          "opportunityWindow": {
+            "type": "string"
+          }
         }
       },
       "growthPath": {
         "type": "object",
         "properties": {
-          "currentTier": { "type": "string" },
-          "nextTierThreshold": { "type": "object", "properties": { "dailySales": { "type": "integer" }, "gap": { "type": "integer" } } },
-          "skuAdvice": { "type": "string" },
-          "keywordAdvice": { "type": "string" }
+          "currentTier": {
+            "type": "string"
+          },
+          "nextTierThreshold": {
+            "type": "object",
+            "properties": {
+              "dailySales": {
+                "type": "integer"
+              },
+              "gap": {
+                "type": "integer"
+              }
+            }
+          },
+          "skuAdvice": {
+            "type": "string"
+          },
+          "keywordAdvice": {
+            "type": "string"
+          }
         }
       },
       "riskAlerts": {
@@ -136,9 +249,20 @@
         "items": {
           "type": "object",
           "properties": {
-            "level": { "type": "string", "enum": ["high", "medium", "low"] },
-            "title": { "type": "string" },
-            "description": { "type": "string" }
+            "level": {
+              "type": "string",
+              "enum": [
+                "high",
+                "medium",
+                "low"
+              ]
+            },
+            "title": {
+              "type": "string"
+            },
+            "description": {
+              "type": "string"
+            }
           }
         }
       }
@@ -154,46 +278,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "7HwdQZk55B",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "7HwdQZk55B",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 226 - 58
dist/skills/competitor-discovery/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "competitor-discovery",
   "displayName": "竞品发现与筛选",
   "description": "根据品类关键词和自身品牌信息,自动发现并筛选直接竞品",
@@ -18,7 +18,9 @@
     },
     "ownAsins": {
       "type": "array",
-      "items": { "type": "string" },
+      "items": {
+        "type": "string"
+      },
       "required": false,
       "description": "自身品牌核心ASIN列表"
     },
@@ -38,8 +40,12 @@
       "type": "object",
       "required": false,
       "properties": {
-        "min": { "type": "number" },
-        "max": { "type": "number" }
+        "min": {
+          "type": "number"
+        },
+        "max": {
+          "type": "number"
+        }
       },
       "description": "价格带过滤范围,不传则自动按自身价格±30%"
     }
@@ -53,9 +59,18 @@
         "endpoint": "/api/ProductQuery",
         "method": "POST",
         "forwardUrl": "https://server.fmode.cn/api/voc-ecom/forward",
-        "headers": { "Authorization": "Bearer {{vocToken}}" },
-        "requestBody": { "Page": 1, "Query": "1", "QueryType": "7", "Pattern": "${categoryKeyword}" },
-        "queryParams": { "domain": "${domain}" }
+        "headers": {
+          "Authorization": "Bearer {{vocToken}}"
+        },
+        "requestBody": {
+          "Page": 1,
+          "Query": "1",
+          "QueryType": "7",
+          "Pattern": "${categoryKeyword}"
+        },
+        "queryParams": {
+          "domain": "${domain}"
+        }
       },
       "output": "searchResults",
       "responseExtract": "extractProductList(resp) → Array<{ Asin, Title, Price, Rating, RatingsCount, MonthlySales, Brand, BSR, Photo }>"
@@ -68,8 +83,12 @@
         "service": "SorftimeApiService.getSimilarProducts",
         "endpoint": "/api/SimilarProductRealtimeRequest",
         "method": "POST",
-        "requestBody": { "ASIN": "${ownAsins[0]}" },
-        "queryParams": { "domain": "${domain}" },
+        "requestBody": {
+          "ASIN": "${ownAsins[0]}"
+        },
+        "queryParams": {
+          "domain": "${domain}"
+        },
         "note": "异步任务:需后续调用 /api/SimilarProductRealtimeRequestStatusQuery 和 /api/SimilarProductRealtimeRequestCollection"
       },
       "output": "similarResults"
@@ -81,8 +100,12 @@
         "service": "SorftimeApiService.getKeywordProductRanking",
         "endpoint": "/api/KeywordProductRanking",
         "method": "POST",
-        "requestBody": { "keyword": "${categoryKeyword}" },
-        "queryParams": { "domain": "${domain}" }
+        "requestBody": {
+          "keyword": "${categoryKeyword}"
+        },
+        "queryParams": {
+          "domain": "${domain}"
+        }
       },
       "output": "rankingResults",
       "responseExtract": "Array<{ Asin, Title, Rank, Price, Rating, RatingsCount, IsSponsored }>"
@@ -110,8 +133,15 @@
         "service": "SorftimeApiService.getProductDetail",
         "endpoint": "/api/ProductRequest",
         "method": "POST",
-        "requestBody": { "ASIN": "${competitor.asin}", "Trend": 1, "QueryTrendStartDt": "", "QueryTrendEndDt": "" },
-        "queryParams": { "domain": "${domain}" }
+        "requestBody": {
+          "ASIN": "${competitor.asin}",
+          "Trend": 1,
+          "QueryTrendStartDt": "",
+          "QueryTrendEndDt": ""
+        },
+        "queryParams": {
+          "domain": "${domain}"
+        }
       },
       "output": "competitorDetails",
       "responseExtract": "{ Title, Brand, SalesPrice, Ratings, RatingsCount, BSR, Category, Photo, Feature, Description, VariationASIN, MonthlySales }"
@@ -154,50 +184,113 @@
         "items": {
           "type": "object",
           "properties": {
-            "asin": { "type": "string" },
-            "title": { "type": "string" },
-            "brand": { "type": "string" },
-            "price": { "type": "number" },
-            "rating": { "type": "number" },
-            "ratingsCount": { "type": "integer" },
-            "monthlySales": { "type": "integer" },
-            "bsr": { "type": "integer" },
-            "category": { "type": "string" },
-            "matchScore": { "type": "number" },
-            "matchReasons": { "type": "array", "items": { "type": "string" } }
+            "asin": {
+              "type": "string"
+            },
+            "title": {
+              "type": "string"
+            },
+            "brand": {
+              "type": "string"
+            },
+            "price": {
+              "type": "number"
+            },
+            "rating": {
+              "type": "number"
+            },
+            "ratingsCount": {
+              "type": "integer"
+            },
+            "monthlySales": {
+              "type": "integer"
+            },
+            "bsr": {
+              "type": "integer"
+            },
+            "category": {
+              "type": "string"
+            },
+            "matchScore": {
+              "type": "number"
+            },
+            "matchReasons": {
+              "type": "array",
+              "items": {
+                "type": "string"
+              }
+            }
           }
         }
       },
       "searchMeta": {
         "type": "object",
         "properties": {
-          "totalCandidates": { "type": "integer" },
-          "filteredCount": { "type": "integer" },
-          "filterCriteria": { "type": "object" }
+          "totalCandidates": {
+            "type": "integer"
+          },
+          "filteredCount": {
+            "type": "integer"
+          },
+          "filterCriteria": {
+            "type": "object"
+          }
         }
       },
       "competitiveLandscape": {
         "type": "object",
         "description": "竞争格局分析(来自computeCompetition算法)",
         "properties": {
-          "cr5": { "type": "number", "description": "Top5品牌销量集中度(0-100)" },
-          "monopolyLevel": { "type": "string", "enum": ["low", "medium", "high"] },
-          "monopolyLabel": { "type": "string" },
+          "cr5": {
+            "type": "number",
+            "description": "Top5品牌销量集中度(0-100)"
+          },
+          "monopolyLevel": {
+            "type": "string",
+            "enum": [
+              "low",
+              "medium",
+              "high"
+            ]
+          },
+          "monopolyLabel": {
+            "type": "string"
+          },
           "brandComparison": {
             "type": "array",
             "items": {
               "type": "object",
               "properties": {
-                "brand": { "type": "string" },
-                "skus": { "type": "integer" },
-                "avgSales": { "type": "integer" },
-                "avgPrice": { "type": "number" },
-                "avgRating": { "type": "number" }
+                "brand": {
+                  "type": "string"
+                },
+                "skus": {
+                  "type": "integer"
+                },
+                "avgSales": {
+                  "type": "integer"
+                },
+                "avgPrice": {
+                  "type": "number"
+                },
+                "avgRating": {
+                  "type": "number"
+                }
               }
             }
           },
-          "differentiationAdvice": { "type": "array", "items": { "type": "string" } },
-          "attackStrategy": { "type": "array", "items": { "type": "string" } }
+          "differentiationAdvice": {
+            "type": "array",
+            "items": {
+              "type": "string"
+            }
+          },
+          "attackStrategy": {
+            "type": "array",
+            "items": {
+              "type": "string"
+            }
+          }
         }
       }
     }
@@ -212,46 +305,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "7HwdQZk55B",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "7HwdQZk55B",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 217 - 57
dist/skills/competitor-pricing-analysis/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "competitor-pricing-analysis",
   "displayName": "竞品定价策略分析",
   "description": "分析竞品定价策略,包括5分位价格带分布、黄金价格带评分、毛利估算、促销建议和盈亏平衡销量分析",
@@ -13,7 +13,9 @@
     },
     "competitorAsins": {
       "type": "array",
-      "items": { "type": "string" },
+      "items": {
+        "type": "string"
+      },
       "required": true,
       "description": "竞品ASIN列表"
     },
@@ -38,9 +40,18 @@
         "endpoint": "/api/ProductQuery",
         "method": "POST",
         "forwardUrl": "https://server.fmode.cn/api/voc-ecom/forward",
-        "headers": { "Authorization": "Bearer {{vocToken}}" },
-        "requestBody": { "Page": 1, "Query": "1", "QueryType": "7", "Pattern": "${categoryKeyword}" },
-        "queryParams": { "domain": "${domain}" }
+        "headers": {
+          "Authorization": "Bearer {{vocToken}}"
+        },
+        "requestBody": {
+          "Page": 1,
+          "Query": "1",
+          "QueryType": "7",
+          "Pattern": "${categoryKeyword}"
+        },
+        "queryParams": {
+          "domain": "${domain}"
+        }
       },
       "output": "categoryProducts",
       "responseExtract": "Array<{ Asin, Title, Price, Rating, RatingsCount, MonthlySales, Brand, BSR }>"
@@ -54,9 +65,18 @@
         "endpoint": "/api/ProductRequest",
         "method": "POST",
         "forwardUrl": "https://server.fmode.cn/api/voc-ecom/forward",
-        "headers": { "Authorization": "Bearer {{vocToken}}" },
-        "requestBody": { "ASIN": "${asin}", "Trend": 1, "QueryTrendStartDt": "", "QueryTrendEndDt": "" },
-        "queryParams": { "domain": "${domain}" }
+        "headers": {
+          "Authorization": "Bearer {{vocToken}}"
+        },
+        "requestBody": {
+          "ASIN": "${asin}",
+          "Trend": 1,
+          "QueryTrendStartDt": "",
+          "QueryTrendEndDt": ""
+        },
+        "queryParams": {
+          "domain": "${domain}"
+        }
       },
       "output": "competitorDetails",
       "responseExtract": "{ Title, Brand, SalesPrice, ListPrice, CouponInfo, FBAFee, Ratings, RatingsCount, MonthlySales }"
@@ -70,9 +90,15 @@
         "endpoint": "/api/MonitorQuery",
         "method": "POST",
         "forwardUrl": "https://server.fmode.cn/api/voc-ecom/forward",
-        "headers": { "Authorization": "Bearer {{vocToken}}" },
-        "requestBody": { "ASIN": "${asin}" },
-        "queryParams": { "domain": "${domain}" }
+        "headers": {
+          "Authorization": "Bearer {{vocToken}}"
+        },
+        "requestBody": {
+          "ASIN": "${asin}"
+        },
+        "queryParams": {
+          "domain": "${domain}"
+        }
       },
       "output": "priceHistory",
       "responseExtract": "{ PriceHistory, RankHistory }"
@@ -113,12 +139,24 @@
         "items": {
           "type": "object",
           "properties": {
-            "range": { "type": "string" },
-            "label": { "type": "string" },
-            "productCount": { "type": "integer" },
-            "avgRating": { "type": "number" },
-            "avgSales": { "type": "integer" },
-            "isGolden": { "type": "boolean" }
+            "range": {
+              "type": "string"
+            },
+            "label": {
+              "type": "string"
+            },
+            "productCount": {
+              "type": "integer"
+            },
+            "avgRating": {
+              "type": "number"
+            },
+            "avgSales": {
+              "type": "integer"
+            },
+            "isGolden": {
+              "type": "boolean"
+            }
           }
         }
       },
@@ -128,43 +166,90 @@
         "items": {
           "type": "object",
           "properties": {
-            "asin": { "type": "string" },
-            "brand": { "type": "string" },
-            "currentPrice": { "type": "number" },
-            "listPrice": { "type": "number" },
-            "coupon": { "type": "number" },
-            "pricingStrategy": { "type": "string" },
-            "priceHistory": { "type": "array" },
-            "estimatedMargin": { "type": "number" }
+            "asin": {
+              "type": "string"
+            },
+            "brand": {
+              "type": "string"
+            },
+            "currentPrice": {
+              "type": "number"
+            },
+            "listPrice": {
+              "type": "number"
+            },
+            "coupon": {
+              "type": "number"
+            },
+            "pricingStrategy": {
+              "type": "string"
+            },
+            "priceHistory": {
+              "type": "array"
+            },
+            "estimatedMargin": {
+              "type": "number"
+            }
           }
         }
       },
       "ownPricePosition": {
         "type": "object",
         "properties": {
-          "band": { "type": "string" },
-          "percentile": { "type": "number" },
-          "competitiveness": { "type": "string" }
+          "band": {
+            "type": "string"
+          },
+          "percentile": {
+            "type": "number"
+          },
+          "competitiveness": {
+            "type": "string"
+          }
         }
       },
       "recommendation": {
         "type": "object",
         "properties": {
-          "optimalRange": { "type": "array", "items": { "type": "number" } },
-          "goldenBand": { "type": "string" },
-          "strategy": { "type": "string" },
-          "reasons": { "type": "array", "items": { "type": "string" } }
+          "optimalRange": {
+            "type": "array",
+            "items": {
+              "type": "number"
+            }
+          },
+          "goldenBand": {
+            "type": "string"
+          },
+          "strategy": {
+            "type": "string"
+          },
+          "reasons": {
+            "type": "array",
+            "items": {
+              "type": "string"
+            }
+          }
         }
       },
       "marginEstimate": {
         "type": "object",
         "properties": {
-          "currentMargin": { "type": "number" },
-          "suggestedMargin": { "type": "number" },
-          "breakEvenSales": { "type": "integer" }
+          "currentMargin": {
+            "type": "number"
+          },
+          "suggestedMargin": {
+            "type": "number"
+          },
+          "breakEvenSales": {
+            "type": "integer"
+          }
         }
       },
-      "promotionAdvice": { "type": "array", "items": { "type": "string" } }
+      "promotionAdvice": {
+        "type": "array",
+        "items": {
+          "type": "string"
+        }
+      }
     }
   },
   "timeout": 120000,
@@ -177,46 +262,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "7HwdQZk55B",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "7HwdQZk55B",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 261 - 53
dist/skills/competitor-product-comparison/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "competitor-product-comparison",
   "displayName": "竞品产品对比",
   "description": "对自身产品与竞品进行多维度横向对比,生成5维健康度仪表盘并标注机会/风险标签",
@@ -8,13 +8,17 @@
   "parameters": {
     "ownAsins": {
       "type": "array",
-      "items": { "type": "string" },
+      "items": {
+        "type": "string"
+      },
       "required": true,
       "description": "自身品牌ASIN列表"
     },
     "competitorAsins": {
       "type": "array",
-      "items": { "type": "string" },
+      "items": {
+        "type": "string"
+      },
       "required": true,
       "description": "竞品ASIN列表(来自 competitor-discovery 输出)"
     },
@@ -26,7 +30,9 @@
     },
     "dimensions": {
       "type": "array",
-      "items": { "type": "string" },
+      "items": {
+        "type": "string"
+      },
       "required": false,
       "description": "对比维度,默认全部"
     }
@@ -41,9 +47,18 @@
         "endpoint": "/api/ProductRequest",
         "method": "POST",
         "forwardUrl": "https://server.fmode.cn/api/voc-ecom/forward",
-        "headers": { "Authorization": "Bearer {{vocToken}}" },
-        "requestBody": { "ASIN": "${asin}", "Trend": 1, "QueryTrendStartDt": "", "QueryTrendEndDt": "" },
-        "queryParams": { "domain": "${domain}" }
+        "headers": {
+          "Authorization": "Bearer {{vocToken}}"
+        },
+        "requestBody": {
+          "ASIN": "${asin}",
+          "Trend": 1,
+          "QueryTrendStartDt": "",
+          "QueryTrendEndDt": ""
+        },
+        "queryParams": {
+          "domain": "${domain}"
+        }
       },
       "output": "allProductDetails",
       "responseExtract": "{ Title, Brand, SalesPrice, Ratings, RatingsCount, BSR, Category, Photo, Feature, Description, VariationASIN, MonthlySales }"
@@ -56,8 +71,12 @@
         "service": "SorftimeApiService.getAsinSalesVolume",
         "endpoint": "/api/AsinSalesVolume",
         "method": "POST",
-        "requestBody": { "ASIN": "${asin}" },
-        "queryParams": { "domain": "${domain}" }
+        "requestBody": {
+          "ASIN": "${asin}"
+        },
+        "queryParams": {
+          "domain": "${domain}"
+        }
       },
       "output": "salesData"
     },
@@ -107,48 +126,162 @@
         "items": {
           "type": "object",
           "properties": {
-            "asin": { "type": "string" },
-            "brand": { "type": "string" },
-            "isOwn": { "type": "boolean" },
+            "asin": {
+              "type": "string"
+            },
+            "brand": {
+              "type": "string"
+            },
+            "isOwn": {
+              "type": "boolean"
+            },
             "metrics": {
               "type": "object",
               "properties": {
-                "price": { "type": "object", "properties": { "value": { "type": "number" }, "score": { "type": "integer" } } },
-                "rating": { "type": "object", "properties": { "value": { "type": "number" }, "score": { "type": "integer" } } },
-                "monthlySales": { "type": "object", "properties": { "value": { "type": "integer" }, "score": { "type": "integer" } } },
-                "reviewCount": { "type": "object", "properties": { "value": { "type": "integer" }, "score": { "type": "integer" } } },
-                "bsr": { "type": "object", "properties": { "value": { "type": "integer" }, "score": { "type": "integer" } } },
-                "featureCount": { "type": "object", "properties": { "value": { "type": "integer" }, "score": { "type": "integer" } } },
-                "variantCount": { "type": "object", "properties": { "value": { "type": "integer" }, "score": { "type": "integer" } } }
+                "price": {
+                  "type": "object",
+                  "properties": {
+                    "value": {
+                      "type": "number"
+                    },
+                    "score": {
+                      "type": "integer"
+                    }
+                  }
+                },
+                "rating": {
+                  "type": "object",
+                  "properties": {
+                    "value": {
+                      "type": "number"
+                    },
+                    "score": {
+                      "type": "integer"
+                    }
+                  }
+                },
+                "monthlySales": {
+                  "type": "object",
+                  "properties": {
+                    "value": {
+                      "type": "integer"
+                    },
+                    "score": {
+                      "type": "integer"
+                    }
+                  }
+                },
+                "reviewCount": {
+                  "type": "object",
+                  "properties": {
+                    "value": {
+                      "type": "integer"
+                    },
+                    "score": {
+                      "type": "integer"
+                    }
+                  }
+                },
+                "bsr": {
+                  "type": "object",
+                  "properties": {
+                    "value": {
+                      "type": "integer"
+                    },
+                    "score": {
+                      "type": "integer"
+                    }
+                  }
+                },
+                "featureCount": {
+                  "type": "object",
+                  "properties": {
+                    "value": {
+                      "type": "integer"
+                    },
+                    "score": {
+                      "type": "integer"
+                    }
+                  }
+                },
+                "variantCount": {
+                  "type": "object",
+                  "properties": {
+                    "value": {
+                      "type": "integer"
+                    },
+                    "score": {
+                      "type": "integer"
+                    }
+                  }
+                }
               }
             },
-            "overallScore": { "type": "number" }
+            "overallScore": {
+              "type": "number"
+            }
           }
         }
       },
-      "advantages": { "type": "array", "items": { "type": "string" } },
-      "gaps": { "type": "array", "items": { "type": "string" } },
-      "recommendation": { "type": "string" },
+      "advantages": {
+        "type": "array",
+        "items": {
+          "type": "string"
+        }
+      },
+      "gaps": {
+        "type": "array",
+        "items": {
+          "type": "string"
+        }
+      },
+      "recommendation": {
+        "type": "string"
+      },
       "healthDashboard": {
         "type": "object",
         "description": "5维健康度仪表盘,key为ASIN",
         "additionalProperties": {
           "type": "object",
           "properties": {
-            "overallScore": { "type": "number" },
+            "overallScore": {
+              "type": "number"
+            },
             "dimensions": {
               "type": "object",
               "properties": {
-                "pricingCompetitiveness": { "type": "integer" },
-                "ratingHealth": { "type": "integer" },
-                "trafficRank": { "type": "integer" },
-                "salesEfficiency": { "type": "integer" },
-                "growthPotential": { "type": "integer" }
+                "pricingCompetitiveness": {
+                  "type": "integer"
+                },
+                "ratingHealth": {
+                  "type": "integer"
+                },
+                "trafficRank": {
+                  "type": "integer"
+                },
+                "salesEfficiency": {
+                  "type": "integer"
+                },
+                "growthPotential": {
+                  "type": "integer"
+                }
+              }
+            },
+            "opportunityTags": {
+              "type": "array",
+              "items": {
+                "type": "string"
               }
             },
-            "opportunityTags": { "type": "array", "items": { "type": "string" } },
-            "riskTags": { "type": "array", "items": { "type": "string" } },
-            "coreShortcoming": { "type": "string" }
+            "riskTags": {
+              "type": "array",
+              "items": {
+                "type": "string"
+              }
+            },
+            "coreShortcoming": {
+              "type": "string"
+            }
           }
         }
       }
@@ -164,46 +297,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "7HwdQZk55B",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "7HwdQZk55B",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 98 - 23
dist/skills/douyin-comment-replies/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "douyin-comment-replies",
   "displayName": "抖音评论回复查询",
   "description": "获取抖音指定视频中某条评论的全部回复,适用于深度舆情追踪、争议点分析、用户回复习惯研究。常配合 douyin-video-comments 使用。",
@@ -8,7 +8,7 @@
     "method": "GET",
     "url": "https://server.fmode.cn/api/voc-social/douyin/app/v3/fetch_video_comment_replies",
     "headers": {
-      "Authorization": "Bearer r:a5a19ea9868043b15d9b10423234ca43",
+      "Authorization": "Bearer ${vocToken}",
       "Accept": "application/json"
     }
   },
@@ -105,46 +105,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 121 - 27
dist/skills/douyin-general-search/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "douyin-general-search",
   "displayName": "抖音综合搜索 V2",
   "description": "按关键词在抖音综合搜索,获取相关视频列表及作者/互动数据。适用于品类内容趋势分析、竞品视频监控、VOC素材采集、爆款选题发现。",
@@ -8,7 +8,7 @@
     "method": "POST",
     "url": "https://server.fmode.cn/api/voc-social/douyin/search/fetch_general_search_v2",
     "headers": {
-      "Authorization": "Bearer r:a5a19ea9868043b15d9b10423234ca43",
+      "Authorization": "Bearer ${vocToken}",
       "Content-Type": "application/json",
       "Accept": "application/json"
     }
@@ -31,25 +31,44 @@
       "sort_type": {
         "type": "string",
         "description": "排序方式:'0'=综合排序(推荐优先);'1'=最多点赞(爆款优先);'2'=最新发布(时效优先)",
-        "enum": ["0", "1", "2"],
+        "enum": [
+          "0",
+          "1",
+          "2"
+        ],
         "default": "0"
       },
       "publish_time": {
         "type": "string",
         "description": "发布时间范围筛选:'0'=不限;'1'=最近一天;'7'=最近一周;'180'=最近半年",
-        "enum": ["0", "1", "7", "180"],
+        "enum": [
+          "0",
+          "1",
+          "7",
+          "180"
+        ],
         "default": "0"
       },
       "filter_duration": {
         "type": "string",
         "description": "视频时长筛选:'0'=不限;'0-1'=1分钟以内(短片/种草);'1-5'=1-5分钟(中视频);'5-10000'=5分钟以上(深度内容)",
-        "enum": ["0", "0-1", "1-5", "5-10000"],
+        "enum": [
+          "0",
+          "0-1",
+          "1-5",
+          "5-10000"
+        ],
         "default": "0"
       },
       "content_type": {
         "type": "string",
         "description": "内容类型筛选:'0'=不限;'1'=视频;'2'=图文/图片;'3'=文章",
-        "enum": ["0", "1", "2", "3"],
+        "enum": [
+          "0",
+          "1",
+          "2",
+          "3"
+        ],
         "default": "0"
       },
       "search_id": {
@@ -189,46 +208,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 121 - 27
dist/skills/douyin-hashtag-search/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "douyin-hashtag-search",
   "displayName": "抖音话题搜索 V2",
   "description": "按关键词搜索抖音话题(挑战/#标签),返回话题浏览量、参与人数、话题描述等。适用于品类话题热度分析、竞品话题监控、内容营销切入点发现。",
@@ -8,7 +8,7 @@
     "method": "POST",
     "url": "https://server.fmode.cn/api/voc-social/douyin/search/fetch_challenge_search_v2",
     "headers": {
-      "Authorization": "Bearer r:a5a19ea9868043b15d9b10423234ca43",
+      "Authorization": "Bearer ${vocToken}",
       "Content-Type": "application/json",
       "Accept": "application/json"
     }
@@ -31,25 +31,44 @@
       "sort_type": {
         "type": "string",
         "description": "排序方式:'0'=综合排序;'1'=最多点赞(爆款话题);'2'=最新发布(新兴话题)",
-        "enum": ["0", "1", "2"],
+        "enum": [
+          "0",
+          "1",
+          "2"
+        ],
         "default": "0"
       },
       "publish_time": {
         "type": "string",
         "description": "发布时间范围:'0'=不限;'1'=最近一天;'7'=最近一周;'180'=最近半年",
-        "enum": ["0", "1", "7", "180"],
+        "enum": [
+          "0",
+          "1",
+          "7",
+          "180"
+        ],
         "default": "0"
       },
       "filter_duration": {
         "type": "string",
         "description": "视频时长:'0'=不限;'0-1'=1分钟以内;'1-5'=1-5分钟;'5-10000'=5分钟以上",
-        "enum": ["0", "0-1", "1-5", "5-10000"],
+        "enum": [
+          "0",
+          "0-1",
+          "1-5",
+          "5-10000"
+        ],
         "default": "0"
       },
       "content_type": {
         "type": "string",
         "description": "内容类型:'0'=不限;'1'=视频;'2'=图文/图片;'3'=文章",
-        "enum": ["0", "1", "2", "3"],
+        "enum": [
+          "0",
+          "1",
+          "2",
+          "3"
+        ],
         "default": "0"
       },
       "search_id": {
@@ -147,46 +166,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 98 - 23
dist/skills/douyin-user-profile/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "douyin-user-profile",
   "displayName": "抖音用户信息查询",
   "description": "根据 sec_user_id 获取抖音用户完整主页数据,包括粉丝数、总获赞数、作品数、个人简介、认证信息等。适用于KOL档案建立、竞品品牌账号分析、达人粉丝画像评估。",
@@ -8,7 +8,7 @@
     "method": "GET",
     "url": "https://server.fmode.cn/api/voc-social/douyin/app/v3/handler_user_profile",
     "headers": {
-      "Authorization": "Bearer r:a5a19ea9868043b15d9b10423234ca43",
+      "Authorization": "Bearer ${vocToken}",
       "Accept": "application/json"
     }
   },
@@ -86,46 +86,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 98 - 23
dist/skills/douyin-user-search/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "douyin-user-search",
   "displayName": "抖音用户搜索 V2",
   "description": "按关键词搜索抖音达人/用户,返回匹配的账号列表及基础数据。适用于红人库建设、品类达人批量筛选、竞品代言人定位。",
@@ -8,7 +8,7 @@
     "method": "POST",
     "url": "https://server.fmode.cn/api/voc-social/douyin/search/fetch_user_search_v2",
     "headers": {
-      "Authorization": "Bearer r:a5a19ea9868043b15d9b10423234ca43",
+      "Authorization": "Bearer ${vocToken}",
       "Content-Type": "application/json",
       "Accept": "application/json"
     }
@@ -109,46 +109,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 98 - 23
dist/skills/douyin-video-comments/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "douyin-video-comments",
   "displayName": "抖音视频评论查询",
   "description": "获取抖音视频的用户评论列表,支持翻页。直接反映用户对产品/内容的真实评价,是VOC情感分析、痛点挖掘、需求发现的核心数据源。",
@@ -8,7 +8,7 @@
     "method": "GET",
     "url": "https://server.fmode.cn/api/voc-social/douyin/app/v3/fetch_video_comments",
     "headers": {
-      "Authorization": "Bearer r:a5a19ea9868043b15d9b10423234ca43",
+      "Authorization": "Bearer ${vocToken}",
       "Accept": "application/json"
     }
   },
@@ -114,46 +114,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 98 - 23
dist/skills/douyin-video-detail/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "douyin-video-detail",
   "displayName": "抖音单个作品数据查询 V3",
   "description": "根据视频ID获取抖音单个作品完整数据(播放量/点赞/评论/分享/作者/话题标签等),V3版本无版权限制。适用于爆款视频深度分析、竞品内容解析、KOL内容效果评估。",
@@ -8,7 +8,7 @@
     "method": "GET",
     "url": "https://server.fmode.cn/api/voc-social/douyin/app/v3/fetch_one_video_v3",
     "headers": {
-      "Authorization": "Bearer r:a5a19ea9868043b15d9b10423234ca43",
+      "Authorization": "Bearer ${vocToken}",
       "Accept": "application/json"
     }
   },
@@ -87,46 +87,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 153 - 40
dist/skills/html-report-generator/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "html-report-generator",
   "displayName": "HTML竞品分析报告生成器",
   "description": "整合所有前置Skill输出,AI生成REPORT_DATA JSON,注入report_template.html模板,输出完整可渲染的13屏HTML VOC分析报告",
@@ -124,36 +124,74 @@
         "type": "object",
         "description": "生成的 REPORT_DATA JSON 对象(可调试复查)",
         "properties": {
-          "metrics": { "type": "array" },
-          "coreFindings": { "type": "array" },
-          "categories": { "type": "array" },
-          "competitors": { "type": "array" },
-          "vocAnalysis": { "type": "object" },
-          "categoryMatrix": { "type": "array" },
-          "strategy": { "type": "object" },
-          "conclusion": { "type": "object" }
+          "metrics": {
+            "type": "array"
+          },
+          "coreFindings": {
+            "type": "array"
+          },
+          "categories": {
+            "type": "array"
+          },
+          "competitors": {
+            "type": "array"
+          },
+          "vocAnalysis": {
+            "type": "object"
+          },
+          "categoryMatrix": {
+            "type": "array"
+          },
+          "strategy": {
+            "type": "object"
+          },
+          "conclusion": {
+            "type": "object"
+          }
         }
       },
       "templateVars": {
         "type": "object",
         "description": "填充后的 {{placeholder}} 变量表",
         "properties": {
-          "industryName": { "type": "string" },
-          "coverBrandEnglish": { "type": "string" },
-          "totalReviews": { "type": "string" },
-          "categoryCount": { "type": "string" },
-          "competitorCount": { "type": "string" },
-          "competitorNames": { "type": "string" },
-          "reportDate": { "type": "string" }
+          "industryName": {
+            "type": "string"
+          },
+          "coverBrandEnglish": {
+            "type": "string"
+          },
+          "totalReviews": {
+            "type": "string"
+          },
+          "categoryCount": {
+            "type": "string"
+          },
+          "competitorCount": {
+            "type": "string"
+          },
+          "competitorNames": {
+            "type": "string"
+          },
+          "reportDate": {
+            "type": "string"
+          }
         }
       },
       "reportStats": {
         "type": "object",
         "description": "报告生成统计",
         "properties": {
-          "totalSlides": { "type": "integer" },
-          "dataCompleteness": { "type": "number", "description": "0-100数据完整度百分比" },
-          "generatedAt": { "type": "string", "description": "生成时间戳" }
+          "totalSlides": {
+            "type": "integer"
+          },
+          "dataCompleteness": {
+            "type": "number",
+            "description": "0-100数据完整度百分比"
+          },
+          "generatedAt": {
+            "type": "string",
+            "description": "生成时间戳"
+          }
         }
       }
     }
@@ -168,46 +206,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "7HwdQZk55B",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "7HwdQZk55B",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 150 - 39
dist/skills/instagram-brand-voc/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "instagram-brand-voc",
   "displayName": "Instagram品牌VOC采集",
   "description": "搜索竞品品牌Instagram账号,采集帖子和互动数据,分析品牌IG策略",
@@ -8,7 +8,9 @@
   "parameters": {
     "brandNames": {
       "type": "array",
-      "items": { "type": "string" },
+      "items": {
+        "type": "string"
+      },
       "required": true,
       "description": "竞品品牌名称列表"
     },
@@ -28,8 +30,13 @@
         "skill": "social-media/instagram-search",
         "endpoint": "https://server.fmode.cn/api/voc-social/instagram/v1/fetch_search",
         "method": "GET",
-        "headers": { "Authorization": "Bearer ${TIKHUB_TOKEN}" },
-        "queryParams": { "query": "${brandName}", "select": "users" }
+        "headers": {
+          "Authorization": "Bearer ${vocToken}"
+        },
+        "queryParams": {
+          "query": "${brandName}",
+          "select": "users"
+        }
       },
       "output": "searchResults",
       "responseExtract": "users[] → { user: { pk, username, full_name, is_verified, profile_pic_url, follower_count, is_private } }",
@@ -43,8 +50,12 @@
         "skill": "social-media/instagram-user-info",
         "endpoint": "https://server.fmode.cn/api/voc-social/instagram/v1/fetch_user_info_by_username",
         "method": "GET",
-        "headers": { "Authorization": "Bearer ${TIKHUB_TOKEN}" },
-        "queryParams": { "username": "${account.username}" }
+        "headers": {
+          "Authorization": "Bearer ${vocToken}"
+        },
+        "queryParams": {
+          "username": "${account.username}"
+        }
       },
       "output": "brandProfiles",
       "responseExtract": "{ user: { pk, username, full_name, biography, follower_count, following_count, media_count, is_verified, profile_pic_url } }"
@@ -57,8 +68,13 @@
         "skill": "social-media/instagram-user-posts",
         "endpoint": "https://server.fmode.cn/api/voc-social/instagram/v1/fetch_user_posts",
         "method": "GET",
-        "headers": { "Authorization": "Bearer ${TIKHUB_TOKEN}" },
-        "queryParams": { "user_id": "${profile.user.pk}", "count": "${postsPerBrand}" }
+        "headers": {
+          "Authorization": "Bearer ${vocToken}"
+        },
+        "queryParams": {
+          "user_id": "${profile.user.pk}",
+          "count": "${postsPerBrand}"
+        }
       },
       "output": "brandPosts",
       "responseExtract": "items[] → { id, caption:{text}, like_count, comment_count, media_type, taken_at, image_versions2 }"
@@ -87,13 +103,27 @@
         "items": {
           "type": "object",
           "properties": {
-            "brandName": { "type": "string" },
-            "username": { "type": "string" },
-            "followerCount": { "type": "integer" },
-            "mediaCount": { "type": "integer" },
-            "avgEngagementRate": { "type": "number" },
-            "topHashtags": { "type": "array" },
-            "contentThemes": { "type": "array" }
+            "brandName": {
+              "type": "string"
+            },
+            "username": {
+              "type": "string"
+            },
+            "followerCount": {
+              "type": "integer"
+            },
+            "mediaCount": {
+              "type": "integer"
+            },
+            "avgEngagementRate": {
+              "type": "number"
+            },
+            "topHashtags": {
+              "type": "array"
+            },
+            "contentThemes": {
+              "type": "array"
+            }
           }
         }
       },
@@ -101,9 +131,15 @@
         "type": "object",
         "description": "品牌间横向对比",
         "properties": {
-          "followerRanking": { "type": "array" },
-          "engagementRanking": { "type": "array" },
-          "contentStrategyComparison": { "type": "object" }
+          "followerRanking": {
+            "type": "array"
+          },
+          "engagementRanking": {
+            "type": "array"
+          },
+          "contentStrategyComparison": {
+            "type": "object"
+          }
         }
       }
     }
@@ -118,46 +154,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 98 - 23
dist/skills/instagram-search/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "instagram-search",
   "displayName": "Instagram 搜索",
   "description": "按关键词搜索 Instagram 用户账号或话颒标签,返回匹配的用户列表或标签列表。适用于竞品品牌 Instagram 账号定位、KOL 初筛、品类 话颒标签发现。",
@@ -8,7 +8,7 @@
     "method": "GET",
     "url": "https://server.fmode.cn/api/voc-social/instagram/v1/fetch_search",
     "headers": {
-      "Authorization": "Bearer r:a5a19ea9868043b15d9b10423234ca43",
+      "Authorization": "Bearer ${vocToken}",
       "Accept": "application/json"
     }
   },
@@ -143,46 +143,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 98 - 23
dist/skills/instagram-user-info/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "instagram-user-info",
   "displayName": "Instagram 用户详情",
   "description": "根据用户名获取 Instagram 账号完整资料,包括粉丝数、帖子数、个人简介、认证状态、商业账号类型等。适用于竞品品牌 IG 影响力画像建立、KOL 资质评估、达人商业价弹分析。",
@@ -8,7 +8,7 @@
     "method": "GET",
     "url": "https://server.fmode.cn/api/voc-social/instagram/v1/fetch_user_info_by_username_v3",
     "headers": {
-      "Authorization": "Bearer r:a5a19ea9868043b15d9b10423234ca43",
+      "Authorization": "Bearer ${vocToken}",
       "Accept": "application/json"
     }
   },
@@ -143,46 +143,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 98 - 23
dist/skills/instagram-user-posts/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "instagram-user-posts",
   "displayName": "Instagram 用户帖子列表",
   "description": "获取指定 Instagram 用户发布的帖子列表,包括点赞数、评论数、帖子文案等。适用于竞品品牌 IG 内容策略分析、KOL 帖子互动表现评估、品牌运营频率分析。",
@@ -8,7 +8,7 @@
     "method": "GET",
     "url": "https://server.fmode.cn/api/voc-social/instagram/v1/fetch_user_posts_v2",
     "headers": {
-      "Authorization": "Bearer r:a5a19ea9868043b15d9b10423234ca43",
+      "Authorization": "Bearer ${vocToken}",
       "Accept": "application/json"
     }
   },
@@ -163,46 +163,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 52 - 24
dist/skills/jimeng-actor-v2/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "jimeng-actor-v2",
   "displayName": "动作模仿2.0",
   "description": "新一代视频动作模仿大模型,支持多人驱动和非真人驱动视频。",
@@ -82,34 +82,46 @@
   },
   "timeout": 30000,
   "tokenConfig": {
-    "type": "body",
-    "tokenField": "token",
-    "format": "Bearer r:{{jimengToken}}",
+    "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
-    "currentToken": "r:f0333969e312a40e4703e8fe4ed1c600",
+    "tokenField": "vocToken",
     "resolutionOrder": [
-      "configFile",
-      "currentToken"
+      "configFile"
     ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "扫码开通即梦AI生成服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+      "title": "扫码开通 VOC-AI 数据服务",
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "即梦AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "action": "resolveUserThenShowPayment",
+      "title": "VOC-AI Token 余额不足,请扫码充值",
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
@@ -133,7 +145,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -142,7 +168,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],

+ 52 - 24
dist/skills/jimeng-actor/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "jimeng-actor",
   "displayName": "动作模仿1.0",
   "description": "输入一张图片和一段模版视频,将图片中的人物按照视频的动作/表情/口型驱动起来。",
@@ -72,34 +72,46 @@
   },
   "timeout": 30000,
   "tokenConfig": {
-    "type": "body",
-    "tokenField": "token",
-    "format": "Bearer r:{{jimengToken}}",
+    "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
-    "currentToken": "r:f0333969e312a40e4703e8fe4ed1c600",
+    "tokenField": "vocToken",
     "resolutionOrder": [
-      "configFile",
-      "currentToken"
+      "configFile"
     ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "扫码开通即梦AI生成服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+      "title": "扫码开通 VOC-AI 数据服务",
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "即梦AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "action": "resolveUserThenShowPayment",
+      "title": "VOC-AI Token 余额不足,请扫码充值",
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
@@ -123,7 +135,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -132,7 +158,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],

+ 52 - 24
dist/skills/jimeng-clothes-v2/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "jimeng-clothes-v2",
   "displayName": "图片换装V2",
   "description": "输入模特图和上装/下装图URL,智能完成虚拟换装。",
@@ -134,34 +134,46 @@
   ],
   "timeout": 30000,
   "tokenConfig": {
-    "type": "body",
-    "tokenField": "token",
-    "format": "Bearer r:{{jimengToken}}",
+    "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
-    "currentToken": "r:f0333969e312a40e4703e8fe4ed1c600",
+    "tokenField": "vocToken",
     "resolutionOrder": [
-      "configFile",
-      "currentToken"
+      "configFile"
     ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "扫码开通即梦AI生成服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+      "title": "扫码开通 VOC-AI 数据服务",
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "即梦AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "action": "resolveUserThenShowPayment",
+      "title": "VOC-AI Token 余额不足,请扫码充值",
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
@@ -185,7 +197,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -194,7 +220,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],

+ 52 - 24
dist/skills/jimeng-img-v4-goods/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "jimeng-img-v4-goods",
   "displayName": "图片生成4.0-商品提取",
   "description": "智能提取商品主体并匹配最佳展示视角,支持服装、鞋包、饰品、家具、日用品。",
@@ -100,34 +100,46 @@
   },
   "timeout": 30000,
   "tokenConfig": {
-    "type": "body",
-    "tokenField": "token",
-    "format": "Bearer r:{{jimengToken}}",
+    "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
-    "currentToken": "r:f0333969e312a40e4703e8fe4ed1c600",
+    "tokenField": "vocToken",
     "resolutionOrder": [
-      "configFile",
-      "currentToken"
+      "configFile"
     ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "扫码开通即梦AI生成服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+      "title": "扫码开通 VOC-AI 数据服务",
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "即梦AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "action": "resolveUserThenShowPayment",
+      "title": "VOC-AI Token 余额不足,请扫码充值",
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
@@ -151,7 +163,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -160,7 +186,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],

+ 52 - 24
dist/skills/jimeng-img-v4-pod/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "jimeng-img-v4-pod",
   "displayName": "图片生成4.0-素材提取(POD)",
   "description": "从实物商品中精准提取并矢量化核心图案,生成平面设计图,适用于电商POD场景。",
@@ -104,34 +104,46 @@
   },
   "timeout": 30000,
   "tokenConfig": {
-    "type": "body",
-    "tokenField": "token",
-    "format": "Bearer r:{{jimengToken}}",
+    "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
-    "currentToken": "r:f0333969e312a40e4703e8fe4ed1c600",
+    "tokenField": "vocToken",
     "resolutionOrder": [
-      "configFile",
-      "currentToken"
+      "configFile"
     ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "扫码开通即梦AI生成服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+      "title": "扫码开通 VOC-AI 数据服务",
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "即梦AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "action": "resolveUserThenShowPayment",
+      "title": "VOC-AI Token 余额不足,请扫码充值",
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
@@ -155,7 +167,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -164,7 +190,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],

+ 52 - 24
dist/skills/jimeng-img-v4/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "jimeng-img-v4",
   "displayName": "即梦图片生成4.0",
   "description": "即梦4.0图片生成,支持文生图、图像编辑及多图组合生成,单次输入最多10张图像,支持4K超高清输出,一次性输出最多15张内容关联图像。",
@@ -139,34 +139,46 @@
     "backoffMultiplier": 2
   },
   "tokenConfig": {
-    "type": "body",
-    "tokenField": "token",
-    "format": "Bearer r:{{jimengToken}}",
+    "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
-    "currentToken": "r:f0333969e312a40e4703e8fe4ed1c600",
+    "tokenField": "vocToken",
     "resolutionOrder": [
-      "configFile",
-      "currentToken"
+      "configFile"
     ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "扫码开通即梦AI生成服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+      "title": "扫码开通 VOC-AI 数据服务",
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "即梦AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "action": "resolveUserThenShowPayment",
+      "title": "VOC-AI Token 余额不足,请扫码充值",
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
@@ -190,7 +202,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -199,7 +225,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],

+ 52 - 24
dist/skills/jimeng-img2img-v3/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "jimeng-img2img-v3",
   "displayName": "即梦图生图3.0智能参考",
   "description": "基于输入图片+文本指令进行图像编辑,精准执行编辑指令,保持图像内容完整性。",
@@ -92,34 +92,46 @@
   },
   "timeout": 30000,
   "tokenConfig": {
-    "type": "body",
-    "tokenField": "token",
-    "format": "Bearer r:{{jimengToken}}",
+    "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
-    "currentToken": "r:f0333969e312a40e4703e8fe4ed1c600",
+    "tokenField": "vocToken",
     "resolutionOrder": [
-      "configFile",
-      "currentToken"
+      "configFile"
     ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "扫码开通即梦AI生成服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+      "title": "扫码开通 VOC-AI 数据服务",
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "即梦AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "action": "resolveUserThenShowPayment",
+      "title": "VOC-AI Token 余额不足,请扫码充值",
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
@@ -143,7 +155,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -152,7 +178,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],

+ 52 - 24
dist/skills/jimeng-inpaint/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "jimeng-inpaint",
   "displayName": "交互编辑(局部重绘/消除笔)",
   "description": "通过涂抹选区建立重绘区域,支持局部重绘和消除笔功能。",
@@ -77,34 +77,46 @@
   },
   "timeout": 30000,
   "tokenConfig": {
-    "type": "body",
-    "tokenField": "token",
-    "format": "Bearer r:{{jimengToken}}",
+    "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
-    "currentToken": "r:f0333969e312a40e4703e8fe4ed1c600",
+    "tokenField": "vocToken",
     "resolutionOrder": [
-      "configFile",
-      "currentToken"
+      "configFile"
     ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "扫码开通即梦AI生成服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+      "title": "扫码开通 VOC-AI 数据服务",
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "即梦AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "action": "resolveUserThenShowPayment",
+      "title": "VOC-AI Token 余额不足,请扫码充值",
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
@@ -128,7 +140,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -137,7 +163,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],

+ 52 - 24
dist/skills/jimeng-oh-detect/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "jimeng-oh-detect",
   "displayName": "数字人v1.5-主体检测",
   "description": "数字人v1.5步骤2:检测图片中的主体并返回mask图(可选步骤)。",
@@ -71,34 +71,46 @@
   ],
   "timeout": 30000,
   "tokenConfig": {
-    "type": "body",
-    "tokenField": "token",
-    "format": "Bearer r:{{jimengToken}}",
+    "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
-    "currentToken": "r:f0333969e312a40e4703e8fe4ed1c600",
+    "tokenField": "vocToken",
     "resolutionOrder": [
-      "configFile",
-      "currentToken"
+      "configFile"
     ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "扫码开通即梦AI生成服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+      "title": "扫码开通 VOC-AI 数据服务",
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "即梦AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "action": "resolveUserThenShowPayment",
+      "title": "VOC-AI Token 余额不足,请扫码充值",
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
@@ -122,7 +134,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -131,7 +157,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],

+ 52 - 24
dist/skills/jimeng-oh-generate/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "jimeng-oh-generate",
   "displayName": "数字人v1.5-视频生成",
   "description": "OmniHuman1.5数字人模型,根据单张图片+音频生成高质量数字人视频。",
@@ -101,34 +101,46 @@
   },
   "timeout": 30000,
   "tokenConfig": {
-    "type": "body",
-    "tokenField": "token",
-    "format": "Bearer r:{{jimengToken}}",
+    "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
-    "currentToken": "r:f0333969e312a40e4703e8fe4ed1c600",
+    "tokenField": "vocToken",
     "resolutionOrder": [
-      "configFile",
-      "currentToken"
+      "configFile"
     ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "扫码开通即梦AI生成服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+      "title": "扫码开通 VOC-AI 数据服务",
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "即梦AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "action": "resolveUserThenShowPayment",
+      "title": "VOC-AI Token 余额不足,请扫码充值",
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
@@ -152,7 +164,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -161,7 +187,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],

+ 52 - 24
dist/skills/jimeng-oh-identify/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "jimeng-oh-identify",
   "displayName": "数字人v1.5-主体识别",
   "description": "数字人v1.5步骤1:识别图片中是否包含人、类人、拟人等主体。",
@@ -67,34 +67,46 @@
   },
   "timeout": 30000,
   "tokenConfig": {
-    "type": "body",
-    "tokenField": "token",
-    "format": "Bearer r:{{jimengToken}}",
+    "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
-    "currentToken": "r:f0333969e312a40e4703e8fe4ed1c600",
+    "tokenField": "vocToken",
     "resolutionOrder": [
-      "configFile",
-      "currentToken"
+      "configFile"
     ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "扫码开通即梦AI生成服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+      "title": "扫码开通 VOC-AI 数据服务",
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "即梦AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "action": "resolveUserThenShowPayment",
+      "title": "VOC-AI Token 余额不足,请扫码充值",
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
@@ -118,7 +130,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -127,7 +153,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],

+ 52 - 24
dist/skills/jimeng-oh-query/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "jimeng-oh-query",
   "displayName": "数字人任务查询",
   "description": "查询数字人流程中主体识别和视频生成的任务状态。",
@@ -125,34 +125,46 @@
   ],
   "timeout": 15000,
   "tokenConfig": {
-    "type": "body",
-    "tokenField": "token",
-    "format": "Bearer r:{{jimengToken}}",
+    "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
-    "currentToken": "r:f0333969e312a40e4703e8fe4ed1c600",
+    "tokenField": "vocToken",
     "resolutionOrder": [
-      "configFile",
-      "currentToken"
+      "configFile"
     ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "扫码开通即梦AI生成服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+      "title": "扫码开通 VOC-AI 数据服务",
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "即梦AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "action": "resolveUserThenShowPayment",
+      "title": "VOC-AI Token 余额不足,请扫码充值",
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
@@ -176,7 +188,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -185,7 +211,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],

+ 52 - 24
dist/skills/jimeng-super-resolution/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "jimeng-super-resolution",
   "displayName": "智能超清",
   "description": "基于seedream基模将图像超清到4K/8K,全面提升画面质感。",
@@ -86,34 +86,46 @@
   },
   "timeout": 30000,
   "tokenConfig": {
-    "type": "body",
-    "tokenField": "token",
-    "format": "Bearer r:{{jimengToken}}",
+    "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
-    "currentToken": "r:f0333969e312a40e4703e8fe4ed1c600",
+    "tokenField": "vocToken",
     "resolutionOrder": [
-      "configFile",
-      "currentToken"
+      "configFile"
     ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "扫码开通即梦AI生成服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+      "title": "扫码开通 VOC-AI 数据服务",
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "即梦AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "action": "resolveUserThenShowPayment",
+      "title": "VOC-AI Token 余额不足,请扫码充值",
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
@@ -137,7 +149,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -146,7 +172,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],

+ 52 - 24
dist/skills/jimeng-task-query/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "jimeng-task-query",
   "displayName": "即梦任务结果查询",
   "description": "查询即梦AI生成任务状态,轮询获取图片/视频生成结果,支持所有即梦生成接口的结果查询。",
@@ -138,34 +138,46 @@
     "backoffMultiplier": 2
   },
   "tokenConfig": {
-    "type": "body",
-    "tokenField": "token",
-    "format": "Bearer r:{{jimengToken}}",
+    "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
-    "currentToken": "r:f0333969e312a40e4703e8fe4ed1c600",
+    "tokenField": "vocToken",
     "resolutionOrder": [
-      "configFile",
-      "currentToken"
+      "configFile"
     ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "扫码开通即梦AI生成服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+      "title": "扫码开通 VOC-AI 数据服务",
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "即梦AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "action": "resolveUserThenShowPayment",
+      "title": "VOC-AI Token 余额不足,请扫码充值",
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
@@ -189,7 +201,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -198,7 +224,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],

+ 52 - 24
dist/skills/jimeng-text2img-v3/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "jimeng-text2img-v3",
   "displayName": "即梦文生图3.0",
   "description": "即梦文生图3.0,文字响应准确度高,支持艺术字体和不同字重,人像质感逼真,支持高清大图输出。",
@@ -92,34 +92,46 @@
   },
   "timeout": 30000,
   "tokenConfig": {
-    "type": "body",
-    "tokenField": "token",
-    "format": "Bearer r:{{jimengToken}}",
+    "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
-    "currentToken": "r:f0333969e312a40e4703e8fe4ed1c600",
+    "tokenField": "vocToken",
     "resolutionOrder": [
-      "configFile",
-      "currentToken"
+      "configFile"
     ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "扫码开通即梦AI生成服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+      "title": "扫码开通 VOC-AI 数据服务",
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "即梦AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "action": "resolveUserThenShowPayment",
+      "title": "VOC-AI Token 余额不足,请扫码充值",
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
@@ -143,7 +155,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -152,7 +178,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],

+ 52 - 24
dist/skills/jimeng-text2img-v31/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "jimeng-text2img-v31",
   "displayName": "即梦文生图3.1",
   "description": "即梦文生图3.1,画面效果升级版,画面美感塑造、风格精准多样及画面细节丰富度方面大幅提升。",
@@ -87,34 +87,46 @@
   },
   "timeout": 30000,
   "tokenConfig": {
-    "type": "body",
-    "tokenField": "token",
-    "format": "Bearer r:{{jimengToken}}",
+    "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
-    "currentToken": "r:f0333969e312a40e4703e8fe4ed1c600",
+    "tokenField": "vocToken",
     "resolutionOrder": [
-      "configFile",
-      "currentToken"
+      "configFile"
     ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "扫码开通即梦AI生成服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+      "title": "扫码开通 VOC-AI 数据服务",
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "即梦AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "action": "resolveUserThenShowPayment",
+      "title": "VOC-AI Token 余额不足,请扫码充值",
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
@@ -138,7 +150,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -147,7 +173,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],

+ 52 - 24
dist/skills/jimeng-video-v3-1080p/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "jimeng-video-v3-1080p",
   "displayName": "视频生成3.0(1080p)",
   "description": "即梦视频3.0 1080P,支持文生视频、图生视频(首帧/首尾帧),最高1080P高清渲染。",
@@ -111,34 +111,46 @@
   },
   "timeout": 30000,
   "tokenConfig": {
-    "type": "body",
-    "tokenField": "token",
-    "format": "Bearer r:{{jimengToken}}",
+    "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
-    "currentToken": "r:f0333969e312a40e4703e8fe4ed1c600",
+    "tokenField": "vocToken",
     "resolutionOrder": [
-      "configFile",
-      "currentToken"
+      "configFile"
     ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "扫码开通即梦AI生成服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+      "title": "扫码开通 VOC-AI 数据服务",
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "即梦AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "action": "resolveUserThenShowPayment",
+      "title": "VOC-AI Token 余额不足,请扫码充值",
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
@@ -162,7 +174,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -171,7 +197,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],

+ 52 - 24
dist/skills/jimeng-video-v3-720p/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "jimeng-video-v3-720p",
   "displayName": "视频生成3.0(720p)",
   "description": "即梦视频3.0 720P,支持文生视频、图生视频(首帧/首尾帧/运镜),高性价比之选。",
@@ -142,34 +142,46 @@
   },
   "timeout": 30000,
   "tokenConfig": {
-    "type": "body",
-    "tokenField": "token",
-    "format": "Bearer r:{{jimengToken}}",
+    "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
-    "currentToken": "r:f0333969e312a40e4703e8fe4ed1c600",
+    "tokenField": "vocToken",
     "resolutionOrder": [
-      "configFile",
-      "currentToken"
+      "configFile"
     ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "扫码开通即梦AI生成服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+      "title": "扫码开通 VOC-AI 数据服务",
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "即梦AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "action": "resolveUserThenShowPayment",
+      "title": "VOC-AI Token 余额不足,请扫码充值",
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
@@ -193,7 +205,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -202,7 +228,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],

+ 52 - 24
dist/skills/jimeng-video-v3-pro/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "jimeng-video-v3-pro",
   "displayName": "即梦视频生成3.0Pro",
   "description": "即梦视频3.0Pro,具备多镜头叙事能力,1080P专业级质感视频。",
@@ -102,34 +102,46 @@
   },
   "timeout": 30000,
   "tokenConfig": {
-    "type": "body",
-    "tokenField": "token",
-    "format": "Bearer r:{{jimengToken}}",
+    "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
-    "currentToken": "r:f0333969e312a40e4703e8fe4ed1c600",
+    "tokenField": "vocToken",
     "resolutionOrder": [
-      "configFile",
-      "currentToken"
+      "configFile"
     ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "扫码开通即梦AI生成服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+      "title": "扫码开通 VOC-AI 数据服务",
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
-      "title": "即梦AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "action": "resolveUserThenShowPayment",
+      "title": "VOC-AI Token 余额不足,请扫码充值",
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
@@ -153,7 +165,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -162,7 +188,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],

+ 98 - 23
dist/skills/keyword-product-ranking/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "keyword-product-ranking",
   "displayName": "关键词产品排名查询",
   "description": "查询指定关键词下的产品排名列表,获取该关键词搜索结果中的产品排序。用于竞品在关键词下的位置分析、广告优化。",
@@ -9,7 +9,7 @@
     "url": "https://server.fmode.cn/api/voc-ecom/forward",
     "headers": {
       "Content-Type": "application/json",
-    "Authorization": "Bearer {{vocToken}}"
+      "Authorization": "Bearer {{vocToken}}"
     }
   },
   "parameters": {
@@ -108,46 +108,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "7HwdQZk55B",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "7HwdQZk55B",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 98 - 23
dist/skills/keyword-search-trend/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "keyword-search-trend",
   "displayName": "关键词搜索趋势查询",
   "description": "查询指定关键词的搜索结果趋势变化,包括搜索量随时间的变化。用于发现飙升关键词、季节性趋势分析。",
@@ -9,7 +9,7 @@
     "url": "https://server.fmode.cn/api/voc-ecom/forward",
     "headers": {
       "Content-Type": "application/json",
-    "Authorization": "Bearer {{vocToken}}"
+      "Authorization": "Bearer {{vocToken}}"
     }
   },
   "parameters": {
@@ -97,46 +97,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "7HwdQZk55B",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "7HwdQZk55B",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 98 - 23
dist/skills/keyword-search/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "keyword-search",
   "displayName": "Amazon 关键词查询",
   "description": "查询 Amazon 关键词的搜索量、搜索趋势、竞争度等数据。用于广告关键词推荐、趋势雷达、飙升卖点词分析。",
@@ -9,7 +9,7 @@
     "url": "https://server.fmode.cn/api/voc-ecom/forward",
     "headers": {
       "Content-Type": "application/json",
-    "Authorization": "Bearer {{vocToken}}"
+      "Authorization": "Bearer {{vocToken}}"
     }
   },
   "parameters": {
@@ -104,46 +104,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "7HwdQZk55B",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "7HwdQZk55B",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 383 - 91
dist/skills/product-deep-analysis/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "product-deep-analysis",
   "displayName": "单品深度诊断",
   "description": "针对单个ASIN进行多维度深度分析:流量架构透视、定价策略、Listing优化、VOC痛点、广告策略、市场机会,并由AI生成核心诊断和运营建议",
@@ -27,7 +27,9 @@
     },
     "competitorAsins": {
       "type": "array",
-      "items": { "type": "string" },
+      "items": {
+        "type": "string"
+      },
       "default": [],
       "description": "可选的竞品ASIN列表,用于对比分析"
     }
@@ -40,9 +42,18 @@
         "endpoint": "/api/ProductRequest",
         "method": "POST",
         "forwardUrl": "https://server.fmode.cn/api/voc-ecom/forward",
-        "headers": { "Authorization": "Bearer {{vocToken}}" },
-        "requestBody": { "ASIN": "${asin}", "Trend": 1, "QueryTrendStartDt": "", "QueryTrendEndDt": "" },
-        "queryParams": { "domain": "${domain}" }
+        "headers": {
+          "Authorization": "Bearer {{vocToken}}"
+        },
+        "requestBody": {
+          "ASIN": "${asin}",
+          "Trend": 1,
+          "QueryTrendStartDt": "",
+          "QueryTrendEndDt": ""
+        },
+        "queryParams": {
+          "domain": "${domain}"
+        }
       },
       "output": "productDetail",
       "responseExtract": {
@@ -69,9 +80,15 @@
         "endpoint": "/api/ASINRequestKeyword",
         "method": "POST",
         "forwardUrl": "https://server.fmode.cn/api/voc-ecom/forward",
-        "headers": { "Authorization": "Bearer {{vocToken}}" },
-        "requestBody": { "ASIN": "${asin}" },
-        "queryParams": { "domain": "${domain}" }
+        "headers": {
+          "Authorization": "Bearer {{vocToken}}"
+        },
+        "requestBody": {
+          "ASIN": "${asin}"
+        },
+        "queryParams": {
+          "domain": "${domain}"
+        }
       },
       "output": "asinKeywords",
       "responseExtract": "Array<{ Keyword, KeywordCNName, SearchVolume, SearchRank, SPR, TitleDensity, ProductCount, ShareClickRate, ShareConversionRate, CPC, GrowthRate, Season, Top3Brand, Top3Asin, WordCount }>"
@@ -83,9 +100,15 @@
         "endpoint": "/api/MonitorQuery",
         "method": "POST",
         "forwardUrl": "https://server.fmode.cn/api/voc-ecom/forward",
-        "headers": { "Authorization": "Bearer {{vocToken}}" },
-        "requestBody": { "ASIN": "${asin}" },
-        "queryParams": { "domain": "${domain}" }
+        "headers": {
+          "Authorization": "Bearer {{vocToken}}"
+        },
+        "requestBody": {
+          "ASIN": "${asin}"
+        },
+        "queryParams": {
+          "domain": "${domain}"
+        }
       },
       "output": "monitorData",
       "responseExtract": "{ PriceHistory, RankHistory, RatingHistory, ReviewCountHistory, SellerCount }"
@@ -94,14 +117,26 @@
       "step": 4,
       "name": "采集评论(可选)",
       "condition": "includeReviews == true",
-      "loop": { "from": 1, "to": "${reviewPages}", "var": "pageIndex", "delay": 400 },
+      "loop": {
+        "from": 1,
+        "to": "${reviewPages}",
+        "var": "pageIndex",
+        "delay": 400
+      },
       "api": {
         "endpoint": "/api/ProductReviewsQuery",
         "method": "POST",
         "forwardUrl": "https://server.fmode.cn/api/voc-ecom/forward",
-        "headers": { "Authorization": "Bearer {{vocToken}}" },
-        "requestBody": { "ASIN": "${asin}", "PageIndex": "${pageIndex}" },
-        "queryParams": { "domain": "${domain}" }
+        "headers": {
+          "Authorization": "Bearer {{vocToken}}"
+        },
+        "requestBody": {
+          "ASIN": "${asin}",
+          "PageIndex": "${pageIndex}"
+        },
+        "queryParams": {
+          "domain": "${domain}"
+        }
       },
       "output": "reviews",
       "responseExtract": "Array<{ Star, Title, Content, ReviewsDate, ReviewedCountry, IsVP, Helpful, ConsumerName, Asin, AsinProperty }>"
@@ -285,29 +320,59 @@
         "type": "object",
         "description": "产品基本信息摘要",
         "properties": {
-          "asin": { "type": "string" },
-          "title": { "type": "string" },
-          "brand": { "type": "string" },
-          "price": { "type": "number", "description": "美元" },
-          "rating": { "type": "number" },
-          "monthlySales": { "type": "integer" },
-          "bsr": { "type": "integer" },
-          "category": { "type": "string" }
+          "asin": {
+            "type": "string"
+          },
+          "title": {
+            "type": "string"
+          },
+          "brand": {
+            "type": "string"
+          },
+          "price": {
+            "type": "number",
+            "description": "美元"
+          },
+          "rating": {
+            "type": "number"
+          },
+          "monthlySales": {
+            "type": "integer"
+          },
+          "bsr": {
+            "type": "integer"
+          },
+          "category": {
+            "type": "string"
+          }
         }
       },
       "overallScore": {
         "type": "object",
         "description": "综合健康评分",
         "properties": {
-          "score": { "type": "integer", "description": "0-100" },
-          "verdict": { "type": "string" },
+          "score": {
+            "type": "integer",
+            "description": "0-100"
+          },
+          "verdict": {
+            "type": "string"
+          },
           "breakdown": {
             "type": "object",
             "properties": {
-              "keyword": { "type": "integer" },
-              "pricing": { "type": "integer" },
-              "rating": { "type": "integer" },
-              "review": { "type": "integer" }
+              "keyword": {
+                "type": "integer"
+              },
+              "pricing": {
+                "type": "integer"
+              },
+              "rating": {
+                "type": "integer"
+              },
+              "review": {
+                "type": "integer"
+              }
             }
           }
         }
@@ -322,15 +387,48 @@
             "items": {
               "type": "object",
               "properties": {
-                "keyword": { "type": "string" },
-                "keywordCN": { "type": "string" },
-                "trafficShare": { "type": "number", "description": "流量占比%" },
-                "searchVolume": { "type": "integer", "description": "月搜索量" },
-                "searchRank": { "type": "integer", "description": "自然排名" },
-                "competitionLevel": { "type": "string", "enum": ["low", "medium", "high"] },
-                "valueScore": { "type": "integer", "description": "0-100" },
-                "diagnosis": { "type": "string", "description": "竞争分析诊断文本" },
-                "priority": { "type": "string", "enum": ["core", "secondary", "longtail"] }
+                "keyword": {
+                  "type": "string"
+                },
+                "keywordCN": {
+                  "type": "string"
+                },
+                "trafficShare": {
+                  "type": "number",
+                  "description": "流量占比%"
+                },
+                "searchVolume": {
+                  "type": "integer",
+                  "description": "月搜索量"
+                },
+                "searchRank": {
+                  "type": "integer",
+                  "description": "自然排名"
+                },
+                "competitionLevel": {
+                  "type": "string",
+                  "enum": [
+                    "low",
+                    "medium",
+                    "high"
+                  ]
+                },
+                "valueScore": {
+                  "type": "integer",
+                  "description": "0-100"
+                },
+                "diagnosis": {
+                  "type": "string",
+                  "description": "竞争分析诊断文本"
+                },
+                "priority": {
+                  "type": "string",
+                  "enum": [
+                    "core",
+                    "secondary",
+                    "longtail"
+                  ]
+                }
               }
             }
           },
@@ -338,9 +436,18 @@
             "type": "object",
             "description": "流量结构摘要",
             "properties": {
-              "organicPct": { "type": "number", "description": "自然流量占比" },
-              "adPct": { "type": "number", "description": "广告流量占比" },
-              "topKeywordConcentration": { "type": "number", "description": "Top5关键词流量集中度" }
+              "organicPct": {
+                "type": "number",
+                "description": "自然流量占比"
+              },
+              "adPct": {
+                "type": "number",
+                "description": "广告流量占比"
+              },
+              "topKeywordConcentration": {
+                "type": "number",
+                "description": "Top5关键词流量集中度"
+              }
             }
           }
         }
@@ -349,22 +456,62 @@
         "type": "object",
         "description": "定价策略分析",
         "properties": {
-          "currentPrice": { "type": "number" },
-          "optimalPrice": { "type": "number" },
-          "recommendedRange": { "type": "object", "properties": { "min": { "type": "number" }, "max": { "type": "number" } } },
-          "currentPosition": { "type": "string", "enum": ["below", "within", "above"] },
-          "bandName": { "type": "string" },
-          "goldenBand": { "type": "string", "description": "量利平衡最优带名称" },
-          "priceStrategy": { "type": "string" },
+          "currentPrice": {
+            "type": "number"
+          },
+          "optimalPrice": {
+            "type": "number"
+          },
+          "recommendedRange": {
+            "type": "object",
+            "properties": {
+              "min": {
+                "type": "number"
+              },
+              "max": {
+                "type": "number"
+              }
+            }
+          },
+          "currentPosition": {
+            "type": "string",
+            "enum": [
+              "below",
+              "within",
+              "above"
+            ]
+          },
+          "bandName": {
+            "type": "string"
+          },
+          "goldenBand": {
+            "type": "string",
+            "description": "量利平衡最优带名称"
+          },
+          "priceStrategy": {
+            "type": "string"
+          },
           "marginEstimate": {
             "type": "object",
             "properties": {
-              "currentMargin": { "type": "number", "description": "当前毛利率%" },
-              "suggestedMargin": { "type": "number" },
-              "breakEvenSales": { "type": "integer" }
+              "currentMargin": {
+                "type": "number",
+                "description": "当前毛利率%"
+              },
+              "suggestedMargin": {
+                "type": "number"
+              },
+              "breakEvenSales": {
+                "type": "integer"
+              }
             }
           },
-          "promotionAdvice": { "type": "array", "items": { "type": "string" } }
+          "promotionAdvice": {
+            "type": "array",
+            "items": {
+              "type": "string"
+            }
+          }
         }
       },
       "listingAnalysis": {
@@ -373,12 +520,42 @@
         "items": {
           "type": "object",
           "properties": {
-            "dimension": { "type": "string", "enum": ["title", "bullet", "searchTerm", "image", "a+content"] },
-            "currentScore": { "type": "integer" },
-            "potentialScore": { "type": "integer" },
-            "tips": { "type": "array", "items": { "type": "string" } },
-            "keywordsToAdd": { "type": "array", "items": { "type": "string" } },
-            "priority": { "type": "string", "enum": ["high", "medium", "low"] }
+            "dimension": {
+              "type": "string",
+              "enum": [
+                "title",
+                "bullet",
+                "searchTerm",
+                "image",
+                "a+content"
+              ]
+            },
+            "currentScore": {
+              "type": "integer"
+            },
+            "potentialScore": {
+              "type": "integer"
+            },
+            "tips": {
+              "type": "array",
+              "items": {
+                "type": "string"
+              }
+            },
+            "keywordsToAdd": {
+              "type": "array",
+              "items": {
+                "type": "string"
+              }
+            },
+            "priority": {
+              "type": "string",
+              "enum": [
+                "high",
+                "medium",
+                "low"
+              ]
+            }
           }
         }
       },
@@ -388,11 +565,27 @@
         "items": {
           "type": "object",
           "properties": {
-            "painPoint": { "type": "string" },
-            "severity": { "type": "integer", "description": "0-100" },
-            "frequency": { "type": "integer" },
-            "suggestion": { "type": "string" },
-            "expectedImpact": { "type": "string", "enum": ["high", "medium", "low"] }
+            "painPoint": {
+              "type": "string"
+            },
+            "severity": {
+              "type": "integer",
+              "description": "0-100"
+            },
+            "frequency": {
+              "type": "integer"
+            },
+            "suggestion": {
+              "type": "string"
+            },
+            "expectedImpact": {
+              "type": "string",
+              "enum": [
+                "high",
+                "medium",
+                "low"
+              ]
+            }
           }
         }
       },
@@ -402,13 +595,37 @@
         "items": {
           "type": "object",
           "properties": {
-            "keyword": { "type": "string" },
-            "matchType": { "type": "string", "enum": ["exact", "phrase", "broad"] },
-            "suggestedBid": { "type": "number" },
-            "expectedAcos": { "type": "number" },
-            "dailyBudget": { "type": "number" },
-            "priority": { "type": "string", "enum": ["high", "medium", "low"] },
-            "reason": { "type": "string" }
+            "keyword": {
+              "type": "string"
+            },
+            "matchType": {
+              "type": "string",
+              "enum": [
+                "exact",
+                "phrase",
+                "broad"
+              ]
+            },
+            "suggestedBid": {
+              "type": "number"
+            },
+            "expectedAcos": {
+              "type": "number"
+            },
+            "dailyBudget": {
+              "type": "number"
+            },
+            "priority": {
+              "type": "string",
+              "enum": [
+                "high",
+                "medium",
+                "low"
+              ]
+            },
+            "reason": {
+              "type": "string"
+            }
           }
         }
       },
@@ -428,46 +645,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "7HwdQZk55B",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "7HwdQZk55B",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 98 - 23
dist/skills/product-detail-query/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "product-detail-query",
   "displayName": "Amazon 产品详情查询",
   "description": "根据 ASIN 获取 Amazon 产品详情,包括标题、价格、评分、销量、BSR、品牌、类目、变体、趋势等完整信息。用于竞品分析、市场全景、定价策略。",
@@ -9,7 +9,7 @@
     "url": "https://server.fmode.cn/api/voc-ecom/forward",
     "headers": {
       "Content-Type": "application/json",
-    "Authorization": "Bearer {{vocToken}}"
+      "Authorization": "Bearer {{vocToken}}"
     }
   },
   "parameters": {
@@ -221,46 +221,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "7HwdQZk55B",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "7HwdQZk55B",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 98 - 23
dist/skills/product-monitor/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "product-monitor",
   "displayName": "产品监控数据查询",
   "description": "获取产品的监控追踪数据,包括价格变化、排名变化、评分变化等历史数据。用于竞品动态追踪、价格监控、新品上架预警。",
@@ -9,7 +9,7 @@
     "url": "https://server.fmode.cn/api/voc-ecom/forward",
     "headers": {
       "Content-Type": "application/json",
-    "Authorization": "Bearer {{vocToken}}"
+      "Authorization": "Bearer {{vocToken}}"
     }
   },
   "parameters": {
@@ -96,46 +96,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "7HwdQZk55B",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "7HwdQZk55B",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 98 - 23
dist/skills/product-reviews-query/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "product-reviews-query",
   "displayName": "Amazon 产品评论查询",
   "description": "根据 ASIN 抓取 Amazon 产品用户评论,支持按星级、日期、是否验证购买筛选。用于 VOC 用户洞察、痛点提取、喜爱点分析、使用场景挖掘。",
@@ -9,7 +9,7 @@
     "url": "https://server.fmode.cn/api/voc-ecom/forward",
     "headers": {
       "Content-Type": "application/json",
-    "Authorization": "Bearer {{vocToken}}"
+      "Authorization": "Bearer {{vocToken}}"
     }
   },
   "parameters": {
@@ -216,46 +216,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "7HwdQZk55B",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "7HwdQZk55B",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 98 - 23
dist/skills/product-search/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "product-search",
   "displayName": "Amazon 关键词搜索产品",
   "description": "按关键词搜索 Amazon 产品列表,返回多个产品的标题、价格、评分、销量等信息。用于品类市场全景分析、Top100 产品列表获取。",
@@ -9,7 +9,7 @@
     "url": "https://server.fmode.cn/api/voc-ecom/forward",
     "headers": {
       "Content-Type": "application/json",
-    "Authorization": "Bearer {{vocToken}}"
+      "Authorization": "Bearer {{vocToken}}"
     }
   },
   "parameters": {
@@ -137,46 +137,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "7HwdQZk55B",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "7HwdQZk55B",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 243 - 53
dist/skills/review-batch-collection/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "review-batch-collection",
   "displayName": "评论批量采集",
   "description": "对多个ASIN批量采集Amazon评论,支持翻页和星级过滤,输出结构化评论语料库",
@@ -8,7 +8,9 @@
   "parameters": {
     "asins": {
       "type": "array",
-      "items": { "type": "string" },
+      "items": {
+        "type": "string"
+      },
       "required": true,
       "description": "ASIN列表"
     },
@@ -20,7 +22,16 @@
     },
     "starFilter": {
       "type": "array",
-      "items": { "type": "integer", "enum": [1, 2, 3, 4, 5] },
+      "items": {
+        "type": "integer",
+        "enum": [
+          1,
+          2,
+          3,
+          4,
+          5
+        ]
+      },
       "required": false,
       "description": "星级过滤,不传则全部"
     },
@@ -47,7 +58,9 @@
         "endpoint": "/api/ProductReviewsQuery",
         "method": "POST",
         "forwardUrl": "https://server.fmode.cn/api/voc-ecom/forward",
-        "headers": { "Authorization": "Bearer {{vocToken}}" },
+        "headers": {
+          "Authorization": "Bearer {{vocToken}}"
+        },
         "requestBody": {
           "ASIN": "${asin}",
           "Star": "${star || ''}",
@@ -55,7 +68,9 @@
           "OnlyPurchase": "${onlyVerifiedPurchase ? 1 : 0}",
           "QueryStartDt": ""
         },
-        "queryParams": { "domain": "${domain}" },
+        "queryParams": {
+          "domain": "${domain}"
+        },
         "rateLimit": "400ms between requests per ASIN"
       },
       "output": "rawReviews",
@@ -131,17 +146,45 @@
         "items": {
           "type": "object",
           "properties": {
-            "asin": { "type": "string" },
-            "star": { "type": "integer", "description": "1-5" },
-            "title": { "type": "string" },
-            "content": { "type": "string" },
-            "consumerName": { "type": "string" },
-            "reviewDate": { "type": "string", "description": "原始ReviewsDate格式20260204" },
-            "isVerifiedPurchase": { "type": "boolean", "description": "原始IsVP" },
-            "helpful": { "type": "integer" },
-            "reviewLink": { "type": "string", "description": "原始ReviewsLink" },
-            "variant": { "type": "string", "description": "原始AsinProperty" },
-            "country": { "type": "string", "description": "原始ReviewedCountry" }
+            "asin": {
+              "type": "string"
+            },
+            "star": {
+              "type": "integer",
+              "description": "1-5"
+            },
+            "title": {
+              "type": "string"
+            },
+            "content": {
+              "type": "string"
+            },
+            "consumerName": {
+              "type": "string"
+            },
+            "reviewDate": {
+              "type": "string",
+              "description": "原始ReviewsDate格式20260204"
+            },
+            "isVerifiedPurchase": {
+              "type": "boolean",
+              "description": "原始IsVP"
+            },
+            "helpful": {
+              "type": "integer"
+            },
+            "reviewLink": {
+              "type": "string",
+              "description": "原始ReviewsLink"
+            },
+            "variant": {
+              "type": "string",
+              "description": "原始AsinProperty"
+            },
+            "country": {
+              "type": "string",
+              "description": "原始ReviewedCountry"
+            }
           }
         }
       },
@@ -149,12 +192,24 @@
         "type": "object",
         "description": "采集统计概况",
         "properties": {
-          "totalReviews": { "type": "integer" },
-          "asinsCollected": { "type": "integer" },
-          "avgRating": { "type": "number" },
-          "positiveRate": { "type": "number" },
-          "negativeRate": { "type": "number" },
-          "perAsinStats": { "type": "object" }
+          "totalReviews": {
+            "type": "integer"
+          },
+          "asinsCollected": {
+            "type": "integer"
+          },
+          "avgRating": {
+            "type": "number"
+          },
+          "positiveRate": {
+            "type": "number"
+          },
+          "negativeRate": {
+            "type": "number"
+          },
+          "perAsinStats": {
+            "type": "object"
+          }
         }
       },
       "vocComparison": {
@@ -164,21 +219,81 @@
           "own": {
             "type": "object",
             "properties": {
-              "count": { "type": "integer" },
-              "avgRating": { "type": "number" },
-              "totalReviews": { "type": "integer" },
-              "negativeRate": { "type": "number" },
-              "products": { "type": "array", "items": { "type": "object", "properties": { "asin": {"type":"string"}, "title": {"type":"string"}, "rating": {"type":"number"}, "ratingsCount": {"type":"integer"}, "negativeRate": {"type":"number"} } } }
+              "count": {
+                "type": "integer"
+              },
+              "avgRating": {
+                "type": "number"
+              },
+              "totalReviews": {
+                "type": "integer"
+              },
+              "negativeRate": {
+                "type": "number"
+              },
+              "products": {
+                "type": "array",
+                "items": {
+                  "type": "object",
+                  "properties": {
+                    "asin": {
+                      "type": "string"
+                    },
+                    "title": {
+                      "type": "string"
+                    },
+                    "rating": {
+                      "type": "number"
+                    },
+                    "ratingsCount": {
+                      "type": "integer"
+                    },
+                    "negativeRate": {
+                      "type": "number"
+                    }
+                  }
+                }
+              }
             }
           },
           "competitor": {
             "type": "object",
             "properties": {
-              "count": { "type": "integer" },
-              "avgRating": { "type": "number" },
-              "totalReviews": { "type": "integer" },
-              "negativeRate": { "type": "number" },
-              "products": { "type": "array", "items": { "type": "object", "properties": { "asin": {"type":"string"}, "title": {"type":"string"}, "rating": {"type":"number"}, "ratingsCount": {"type":"integer"}, "negativeRate": {"type":"number"} } } }
+              "count": {
+                "type": "integer"
+              },
+              "avgRating": {
+                "type": "number"
+              },
+              "totalReviews": {
+                "type": "integer"
+              },
+              "negativeRate": {
+                "type": "number"
+              },
+              "products": {
+                "type": "array",
+                "items": {
+                  "type": "object",
+                  "properties": {
+                    "asin": {
+                      "type": "string"
+                    },
+                    "title": {
+                      "type": "string"
+                    },
+                    "rating": {
+                      "type": "number"
+                    },
+                    "ratingsCount": {
+                      "type": "integer"
+                    },
+                    "negativeRate": {
+                      "type": "number"
+                    }
+                  }
+                }
+              }
             }
           }
         }
@@ -195,46 +310,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "7HwdQZk55B",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "7HwdQZk55B",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 190 - 38
dist/skills/review-highlight-extraction/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "review-highlight-extraction",
   "displayName": "好评亮点提取",
   "description": "从好评中提取用户最认可的产品亮点,识别竞品核心卖点和可借鉴的优势",
@@ -13,15 +13,26 @@
     },
     "targetAsins": {
       "type": "array",
-      "items": { "type": "string" },
+      "items": {
+        "type": "string"
+      },
       "required": false,
       "description": "指定分析的ASIN"
     },
     "highlightCategories": {
       "type": "array",
-      "items": { "type": "string" },
+      "items": {
+        "type": "string"
+      },
       "required": false,
-      "default": ["品质感知", "功能表现", "设计美学", "使用体验", "性价比", "包装送礼"],
+      "default": [
+        "品质感知",
+        "功能表现",
+        "设计美学",
+        "使用体验",
+        "性价比",
+        "包装送礼"
+      ],
       "description": "预定义亮点类别"
     }
   },
@@ -106,18 +117,34 @@
         "items": {
           "type": "object",
           "properties": {
-            "topic": { "type": "string" },
-            "score": { "type": "integer", "description": "0-100热度" },
-            "category": { "type": "string" },
-            "frequency": { "type": "integer" },
-            "examples": { "type": "array", "items": { "type": "string" } }
+            "topic": {
+              "type": "string"
+            },
+            "score": {
+              "type": "integer",
+              "description": "0-100热度"
+            },
+            "category": {
+              "type": "string"
+            },
+            "frequency": {
+              "type": "integer"
+            },
+            "examples": {
+              "type": "array",
+              "items": {
+                "type": "string"
+              }
+            }
           }
         }
       },
       "competitorAdvantages": {
         "type": "object",
         "description": "各竞品的独有亮点",
-        "additionalProperties": { "type": "array" }
+        "additionalProperties": {
+          "type": "array"
+        }
       },
       "actionableInsights": {
         "type": "array",
@@ -125,9 +152,20 @@
         "items": {
           "type": "object",
           "properties": {
-            "insight": { "type": "string" },
-            "action": { "type": "string" },
-            "priority": { "type": "string", "enum": ["high", "medium", "low"] }
+            "insight": {
+              "type": "string"
+            },
+            "action": {
+              "type": "string"
+            },
+            "priority": {
+              "type": "string",
+              "enum": [
+                "high",
+                "medium",
+                "low"
+              ]
+            }
           }
         }
       },
@@ -135,10 +173,49 @@
         "type": "object",
         "description": "Listing卖点植入建议",
         "properties": {
-          "titleKeywords": { "type": "array", "items": { "type": "string" }, "description": "建议植入标题的亮点词根" },
-          "bulletHighlights": { "type": "array", "items": { "type": "string" }, "description": "建议在bullet中突出的卖点" },
-          "aplusThemes": { "type": "array", "items": { "type": "string" }, "description": "A+页面建议展示的场景主题" },
-          "sellpointPriority": { "type": "array", "items": { "type": "object", "properties": { "sellpoint": {"type":"string"}, "type": {"type":"string", "enum":["required","differentiation","reference"]}, "source": {"type":"string"} } } }
+          "titleKeywords": {
+            "type": "array",
+            "items": {
+              "type": "string"
+            },
+            "description": "建议植入标题的亮点词根"
+          },
+          "bulletHighlights": {
+            "type": "array",
+            "items": {
+              "type": "string"
+            },
+            "description": "建议在bullet中突出的卖点"
+          },
+          "aplusThemes": {
+            "type": "array",
+            "items": {
+              "type": "string"
+            },
+            "description": "A+页面建议展示的场景主题"
+          },
+          "sellpointPriority": {
+            "type": "array",
+            "items": {
+              "type": "object",
+              "properties": {
+                "sellpoint": {
+                  "type": "string"
+                },
+                "type": {
+                  "type": "string",
+                  "enum": [
+                    "required",
+                    "differentiation",
+                    "reference"
+                  ]
+                },
+                "source": {
+                  "type": "string"
+                }
+              }
+            }
+          }
         }
       }
     }
@@ -153,46 +230,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "7HwdQZk55B",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "7HwdQZk55B",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 185 - 44
dist/skills/review-keyword-cloud/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "review-keyword-cloud",
   "displayName": "评论关键词云",
   "description": "从评论语料生成关键词云,结合ASIN反查关键词,每个关键词带情感标签,构建VOC关键词库",
@@ -13,7 +13,9 @@
     },
     "asins": {
       "type": "array",
-      "items": { "type": "string" },
+      "items": {
+        "type": "string"
+      },
       "required": false,
       "description": "ASIN列表,用于调用反查关键词补充"
     },
@@ -59,9 +61,15 @@
         "endpoint": "/api/ASINRequestKeyword",
         "method": "POST",
         "forwardUrl": "https://server.fmode.cn/api/voc-ecom/forward",
-        "headers": { "Authorization": "Bearer {{vocToken}}" },
-        "requestBody": { "ASIN": "${asin}" },
-        "queryParams": { "domain": "${domain}" }
+        "headers": {
+          "Authorization": "Bearer {{vocToken}}"
+        },
+        "requestBody": {
+          "ASIN": "${asin}"
+        },
+        "queryParams": {
+          "domain": "${domain}"
+        }
       },
       "output": "searchKeywords",
       "responseExtract": "Array<{ Keyword, KeywordCNName, SearchVolume, SearchRank }>"
@@ -90,13 +98,37 @@
         "items": {
           "type": "object",
           "properties": {
-            "keyword": { "type": "string" },
-            "weight": { "type": "integer" },
-            "frequency": { "type": "integer" },
-            "source": { "type": "string", "enum": ["review", "search", "both"] },
-            "sentiment": { "type": "string", "enum": ["positive", "negative", "neutral"] },
-            "searchVolume": { "type": "integer" },
-            "relatedAsins": { "type": "integer" }
+            "keyword": {
+              "type": "string"
+            },
+            "weight": {
+              "type": "integer"
+            },
+            "frequency": {
+              "type": "integer"
+            },
+            "source": {
+              "type": "string",
+              "enum": [
+                "review",
+                "search",
+                "both"
+              ]
+            },
+            "sentiment": {
+              "type": "string",
+              "enum": [
+                "positive",
+                "negative",
+                "neutral"
+              ]
+            },
+            "searchVolume": {
+              "type": "integer"
+            },
+            "relatedAsins": {
+              "type": "integer"
+            }
           }
         }
       },
@@ -104,10 +136,30 @@
         "type": "object",
         "description": "关键词分类",
         "properties": {
-          "产品特性": { "type": "array", "items": { "type": "string" } },
-          "使用场景": { "type": "array", "items": { "type": "string" } },
-          "购买决策": { "type": "array", "items": { "type": "string" } },
-          "问题反馈": { "type": "array", "items": { "type": "string" } }
+          "产品特性": {
+            "type": "array",
+            "items": {
+              "type": "string"
+            }
+          },
+          "使用场景": {
+            "type": "array",
+            "items": {
+              "type": "string"
+            }
+          },
+          "购买决策": {
+            "type": "array",
+            "items": {
+              "type": "string"
+            }
+          },
+          "问题反馈": {
+            "type": "array",
+            "items": {
+              "type": "string"
+            }
+          }
         }
       },
       "searchKeywords": {
@@ -115,16 +167,30 @@
         "items": {
           "type": "object",
           "properties": {
-            "keyword": { "type": "string" },
-            "searchVolume": { "type": "integer" },
-            "rank": { "type": "integer" }
+            "keyword": {
+              "type": "string"
+            },
+            "searchVolume": {
+              "type": "integer"
+            },
+            "rank": {
+              "type": "integer"
+            }
           }
         }
       },
-      "totalKeywords": { "type": "integer" },
-      "reviewKeywordsCount": { "type": "integer" },
-      "searchKeywordsCount": { "type": "integer" },
-      "overlapKeywords": { "type": "integer" }
+      "totalKeywords": {
+        "type": "integer"
+      },
+      "reviewKeywordsCount": {
+        "type": "integer"
+      },
+      "searchKeywordsCount": {
+        "type": "integer"
+      },
+      "overlapKeywords": {
+        "type": "integer"
+      }
     }
   },
   "timeout": 300000,
@@ -137,46 +203,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "7HwdQZk55B",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "7HwdQZk55B",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 194 - 43
dist/skills/review-pain-point-extraction/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "review-pain-point-extraction",
   "displayName": "差评痛点提取",
   "description": "从差评中提取用户痛点,按类别聚类,量化频率和严重度,找到竞品死穴",
@@ -13,15 +13,26 @@
     },
     "targetAsins": {
       "type": "array",
-      "items": { "type": "string" },
+      "items": {
+        "type": "string"
+      },
       "required": false,
       "description": "指定分析的ASIN列表"
     },
     "painCategories": {
       "type": "array",
-      "items": { "type": "string" },
+      "items": {
+        "type": "string"
+      },
       "required": false,
-      "default": ["产品质量", "尺寸规格", "功能缺陷", "外观", "物流包装", "性价比"],
+      "default": [
+        "产品质量",
+        "尺寸规格",
+        "功能缺陷",
+        "外观",
+        "物流包装",
+        "性价比"
+      ],
       "description": "预定义痛点类别"
     }
   },
@@ -119,12 +130,31 @@
         "items": {
           "type": "object",
           "properties": {
-            "topic": { "type": "string" },
-            "score": { "type": "integer", "description": "0-100严重度" },
-            "category": { "type": "string" },
-            "frequency": { "type": "integer" },
-            "examples": { "type": "array", "items": { "type": "string" } },
-            "affectedAsins": { "type": "array", "items": { "type": "string" } }
+            "topic": {
+              "type": "string"
+            },
+            "score": {
+              "type": "integer",
+              "description": "0-100严重度"
+            },
+            "category": {
+              "type": "string"
+            },
+            "frequency": {
+              "type": "integer"
+            },
+            "examples": {
+              "type": "array",
+              "items": {
+                "type": "string"
+              }
+            },
+            "affectedAsins": {
+              "type": "array",
+              "items": {
+                "type": "string"
+              }
+            }
           }
         }
       },
@@ -135,7 +165,9 @@
       "competitorSpecific": {
         "type": "object",
         "description": "各竞品独有的痛点",
-        "additionalProperties": { "type": "array" }
+        "additionalProperties": {
+          "type": "array"
+        }
       },
       "opportunityGaps": {
         "type": "array",
@@ -143,10 +175,23 @@
         "items": {
           "type": "object",
           "properties": {
-            "painPoint": { "type": "string" },
-            "severity": { "type": "integer" },
-            "suggestion": { "type": "string" },
-            "expectedImpact": { "type": "string", "enum": ["high", "medium", "low"] }
+            "painPoint": {
+              "type": "string"
+            },
+            "severity": {
+              "type": "integer"
+            },
+            "suggestion": {
+              "type": "string"
+            },
+            "expectedImpact": {
+              "type": "string",
+              "enum": [
+                "high",
+                "medium",
+                "low"
+              ]
+            }
           }
         }
       },
@@ -154,13 +199,44 @@
         "type": "object",
         "description": "VOC驱动优化建议",
         "properties": {
-          "ratingGap": { "type": "number", "description": "与标枆4.6的差距" },
-          "conversionImpact": { "type": "string", "description": "差距对转化率的影响估算" },
-          "topPositiveThemes": { "type": "array", "items": { "type": "string" } },
-          "topNegativeThemes": { "type": "array", "items": { "type": "string" } },
-          "listingAdvice": { "type": "array", "items": { "type": "string" } },
-          "productIterationAdvice": { "type": "array", "items": { "type": "string" } },
-          "afterSalesAdvice": { "type": "array", "items": { "type": "string" } }
+          "ratingGap": {
+            "type": "number",
+            "description": "与标枆4.6的差距"
+          },
+          "conversionImpact": {
+            "type": "string",
+            "description": "差距对转化率的影响估算"
+          },
+          "topPositiveThemes": {
+            "type": "array",
+            "items": {
+              "type": "string"
+            }
+          },
+          "topNegativeThemes": {
+            "type": "array",
+            "items": {
+              "type": "string"
+            }
+          },
+          "listingAdvice": {
+            "type": "array",
+            "items": {
+              "type": "string"
+            }
+          },
+          "productIterationAdvice": {
+            "type": "array",
+            "items": {
+              "type": "string"
+            }
+          },
+          "afterSalesAdvice": {
+            "type": "array",
+            "items": {
+              "type": "string"
+            }
+          }
         }
       }
     }
@@ -175,46 +251,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "7HwdQZk55B",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "7HwdQZk55B",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 267 - 53
dist/skills/review-sentiment-analysis/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "review-sentiment-analysis",
   "displayName": "评论情感分析",
   "description": "对评论语料库进行情感分析,分类正面/负面/中性,提取情感关键短语并按ASIN/品牌聚合",
@@ -20,10 +20,17 @@
     "sentimentThreshold": {
       "type": "object",
       "required": false,
-      "default": { "positiveMin": 0.6, "negativeMax": 0.4 },
+      "default": {
+        "positiveMin": 0.6,
+        "negativeMax": 0.4
+      },
       "properties": {
-        "positiveMin": { "type": "number" },
-        "negativeMax": { "type": "number" }
+        "positiveMin": {
+          "type": "number"
+        },
+        "negativeMax": {
+          "type": "number"
+        }
       },
       "description": "情感分类阈值"
     }
@@ -76,26 +83,98 @@
         "sentimentPhraseRules": {
           "description": "Regex模式匹配多词情感短语,短语优先于单词",
           "negativePhrases": [
-            "too small", "too big", "too short", "too long", "too tight", "too thin",
-            "poor quality", "bad quality", "cheaply made",
-            "fell apart", "doesn't fit", "not worth", "waste of money",
+            "too small",
+            "too big",
+            "too short",
+            "too long",
+            "too tight",
+            "too thin",
+            "poor quality",
+            "bad quality",
+            "cheaply made",
+            "fell apart",
+            "doesn't fit",
+            "not worth",
+            "waste of money",
             "not as described/pictured/shown/advertised",
-            "wrong size", "wrong color", "bad smell", "chemical smell",
-            "sent back", "returned it", "ripped/torn", "stained"
+            "wrong size",
+            "wrong color",
+            "bad smell",
+            "chemical smell",
+            "sent back",
+            "returned it",
+            "ripped/torn",
+            "stained"
           ],
           "positivePhrases": [
-            "well made", "high quality", "great quality", "good quality",
-            "perfect fit", "fits perfectly/great/well",
-            "highly recommend", "fast shipping",
-            "great value/price/deal", "worth the money/penny",
-            "loved it", "very comfortable/soft/warm",
-            "true to size", "exceeded expectations",
-            "beautiful/gorgeous", "super soft", "pleasantly surprised"
+            "well made",
+            "high quality",
+            "great quality",
+            "good quality",
+            "perfect fit",
+            "fits perfectly/great/well",
+            "highly recommend",
+            "fast shipping",
+            "great value/price/deal",
+            "worth the money/penny",
+            "loved it",
+            "very comfortable/soft/warm",
+            "true to size",
+            "exceeded expectations",
+            "beautiful/gorgeous",
+            "super soft",
+            "pleasantly surprised"
           ]
         },
         "sentimentWordDictionary": {
-          "positive": ["comfortable", "durable", "sturdy", "soft", "affordable", "flattering", "recommend", "amazing", "awesome", "excellent", "fantastic", "stylish", "elegant", "versatile", "lightweight", "breathable"],
-          "negative": ["disappointed", "disappointing", "flimsy", "cheap", "broke", "broken", "defective", "damaged", "uncomfortable", "itchy", "scratchy", "rough", "terrible", "horrible", "awful", "worst", "misleading", "refund", "shrunk", "faded", "wrinkled", "unraveled", "fraying", "pilling", "transparent", "see-through", "smelly", "stiff"]
+          "positive": [
+            "comfortable",
+            "durable",
+            "sturdy",
+            "soft",
+            "affordable",
+            "flattering",
+            "recommend",
+            "amazing",
+            "awesome",
+            "excellent",
+            "fantastic",
+            "stylish",
+            "elegant",
+            "versatile",
+            "lightweight",
+            "breathable"
+          ],
+          "negative": [
+            "disappointed",
+            "disappointing",
+            "flimsy",
+            "cheap",
+            "broke",
+            "broken",
+            "defective",
+            "damaged",
+            "uncomfortable",
+            "itchy",
+            "scratchy",
+            "rough",
+            "terrible",
+            "horrible",
+            "awful",
+            "worst",
+            "misleading",
+            "refund",
+            "shrunk",
+            "faded",
+            "wrinkled",
+            "unraveled",
+            "fraying",
+            "pilling",
+            "transparent",
+            "see-through",
+            "smelly",
+            "stiff"
+          ]
         },
         "mergeAndOutput": {
           "phraseMinCount": 2,
@@ -116,11 +195,26 @@
         "items": {
           "type": "object",
           "properties": {
-            "asin": { "type": "string" },
-            "star": { "type": "integer" },
-            "sentiment": { "type": "string", "enum": ["positive", "negative", "neutral"] },
-            "title": { "type": "string" },
-            "content": { "type": "string" }
+            "asin": {
+              "type": "string"
+            },
+            "star": {
+              "type": "integer"
+            },
+            "sentiment": {
+              "type": "string",
+              "enum": [
+                "positive",
+                "negative",
+                "neutral"
+              ]
+            },
+            "title": {
+              "type": "string"
+            },
+            "content": {
+              "type": "string"
+            }
           }
         }
       },
@@ -130,10 +224,18 @@
         "additionalProperties": {
           "type": "object",
           "properties": {
-            "total": { "type": "integer" },
-            "positivePct": { "type": "number" },
-            "neutralPct": { "type": "number" },
-            "negativePct": { "type": "number" }
+            "total": {
+              "type": "integer"
+            },
+            "positivePct": {
+              "type": "number"
+            },
+            "neutralPct": {
+              "type": "number"
+            },
+            "negativePct": {
+              "type": "number"
+            }
           }
         }
       },
@@ -141,8 +243,34 @@
         "type": "object",
         "description": "全局情感热词",
         "properties": {
-          "positive": { "type": "array", "items": { "type": "object", "properties": { "phrase": { "type": "string" }, "frequency": { "type": "integer" } } } },
-          "negative": { "type": "array", "items": { "type": "object", "properties": { "phrase": { "type": "string" }, "frequency": { "type": "integer" } } } }
+          "positive": {
+            "type": "array",
+            "items": {
+              "type": "object",
+              "properties": {
+                "phrase": {
+                  "type": "string"
+                },
+                "frequency": {
+                  "type": "integer"
+                }
+              }
+            }
+          },
+          "negative": {
+            "type": "array",
+            "items": {
+              "type": "object",
+              "properties": {
+                "phrase": {
+                  "type": "string"
+                },
+                "frequency": {
+                  "type": "integer"
+                }
+              }
+            }
+          }
         }
       },
       "sentimentKeywordCloud": {
@@ -151,9 +279,20 @@
         "items": {
           "type": "object",
           "properties": {
-            "text": { "type": "string" },
-            "weight": { "type": "integer", "description": "0-100权重" },
-            "sentiment": { "type": "string", "enum": ["positive", "negative"] }
+            "text": {
+              "type": "string"
+            },
+            "weight": {
+              "type": "integer",
+              "description": "0-100权重"
+            },
+            "sentiment": {
+              "type": "string",
+              "enum": [
+                "positive",
+                "negative"
+              ]
+            }
           }
         }
       }
@@ -173,46 +312,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "7HwdQZk55B",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "7HwdQZk55B",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 98 - 23
dist/skills/similar-products/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "similar-products",
   "displayName": "Amazon 相似产品查询",
   "description": "根据 ASIN 查询与该产品相似的产品列表,用于竞品发现、关联分析。",
@@ -9,7 +9,7 @@
     "url": "https://server.fmode.cn/api/voc-ecom/forward",
     "headers": {
       "Content-Type": "application/json",
-    "Authorization": "Bearer {{vocToken}}"
+      "Authorization": "Bearer {{vocToken}}"
     }
   },
   "parameters": {
@@ -88,46 +88,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "7HwdQZk55B",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "7HwdQZk55B",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 217 - 48
dist/skills/social-trend-analysis/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "social-trend-analysis",
   "displayName": "社媒趋势与热度分析",
   "description": "综合TikTok和Instagram数据,分析品类社媒趋势、热度走向和内容生态",
@@ -83,11 +83,36 @@
       "logic": "computeActions(platformComparison, trends, brandRanking, opportunities)",
       "algorithm": {
         "priorityRules": [
-          { "priority": "highest", "condition": "未覆盖热门话题存在", "action": "立即跟进未覆盖话题,发布相关内容", "deadline": "3天内" },
-          { "priority": "high", "condition": "互动率低于品类平均", "action": "优化内容形式,参考品类爆款视频结构", "deadline": "7天内" },
-          { "priority": "high", "condition": "发布频率低于竞品", "action": "提升发布频率至竞品平均水平", "deadline": "7天内" },
-          { "priority": "medium", "condition": "双平台不均衡", "action": "在弱势平台增加内容布局", "deadline": "15天内" },
-          { "priority": "medium", "condition": "always", "action": "建立KOL合作清单,筛选高互动率中腰部达人", "deadline": "15天内" }
+          {
+            "priority": "highest",
+            "condition": "未覆盖热门话题存在",
+            "action": "立即跟进未覆盖话题,发布相关内容",
+            "deadline": "3天内"
+          },
+          {
+            "priority": "high",
+            "condition": "互动率低于品类平均",
+            "action": "优化内容形式,参考品类爆款视频结构",
+            "deadline": "7天内"
+          },
+          {
+            "priority": "high",
+            "condition": "发布频率低于竞品",
+            "action": "提升发布频率至竞品平均水平",
+            "deadline": "7天内"
+          },
+          {
+            "priority": "medium",
+            "condition": "双平台不均衡",
+            "action": "在弱势平台增加内容布局",
+            "deadline": "15天内"
+          },
+          {
+            "priority": "medium",
+            "condition": "always",
+            "action": "建立KOL合作清单,筛选高互动率中腰部达人",
+            "deadline": "15天内"
+          }
         ]
       },
       "output": "actionItems"
@@ -100,10 +125,34 @@
         "type": "object",
         "description": "平台热度对比",
         "properties": {
-          "tiktok": { "type": "object", "properties": { "totalPlays": { "type": "integer" }, "avgEngagement": { "type": "number" } } },
-          "instagram": { "type": "object", "properties": { "totalFollowers": { "type": "integer" }, "avgEngagement": { "type": "number" } } },
-          "dominantPlatform": { "type": "string" },
-          "insight": { "type": "string" }
+          "tiktok": {
+            "type": "object",
+            "properties": {
+              "totalPlays": {
+                "type": "integer"
+              },
+              "avgEngagement": {
+                "type": "number"
+              }
+            }
+          },
+          "instagram": {
+            "type": "object",
+            "properties": {
+              "totalFollowers": {
+                "type": "integer"
+              },
+              "avgEngagement": {
+                "type": "number"
+              }
+            }
+          },
+          "dominantPlatform": {
+            "type": "string"
+          },
+          "insight": {
+            "type": "string"
+          }
         }
       },
       "trendingTopics": {
@@ -112,10 +161,18 @@
         "items": {
           "type": "object",
           "properties": {
-            "topic": { "type": "string" },
-            "trendScore": { "type": "number" },
-            "category": { "type": "string" },
-            "platforms": { "type": "array" }
+            "topic": {
+              "type": "string"
+            },
+            "trendScore": {
+              "type": "number"
+            },
+            "category": {
+              "type": "string"
+            },
+            "platforms": {
+              "type": "array"
+            }
           }
         }
       },
@@ -125,9 +182,15 @@
         "items": {
           "type": "object",
           "properties": {
-            "brand": { "type": "string" },
-            "socialScore": { "type": "number" },
-            "strategyType": { "type": "string" }
+            "brand": {
+              "type": "string"
+            },
+            "socialScore": {
+              "type": "number"
+            },
+            "strategyType": {
+              "type": "string"
+            }
           }
         }
       },
@@ -137,9 +200,20 @@
         "items": {
           "type": "object",
           "properties": {
-            "opportunity": { "type": "string" },
-            "platform": { "type": "string" },
-            "priority": { "type": "string", "enum": ["high", "medium", "low"] }
+            "opportunity": {
+              "type": "string"
+            },
+            "platform": {
+              "type": "string"
+            },
+            "priority": {
+              "type": "string",
+              "enum": [
+                "high",
+                "medium",
+                "low"
+              ]
+            }
           }
         }
       },
@@ -147,9 +221,15 @@
         "type": "object",
         "description": "受众洞察",
         "properties": {
-          "topCommentThemes": { "type": "array" },
-          "sentimentDistribution": { "type": "object" },
-          "engagementPatterns": { "type": "object" }
+          "topCommentThemes": {
+            "type": "array"
+          },
+          "sentimentDistribution": {
+            "type": "object"
+          },
+          "engagementPatterns": {
+            "type": "object"
+          }
         }
       },
       "actionItems": {
@@ -158,10 +238,24 @@
         "items": {
           "type": "object",
           "properties": {
-            "priority": { "type": "string", "enum": ["highest", "high", "medium", "low"] },
-            "action": { "type": "string" },
-            "deadline": { "type": "string" },
-            "expectedResult": { "type": "string" }
+            "priority": {
+              "type": "string",
+              "enum": [
+                "highest",
+                "high",
+                "medium",
+                "low"
+              ]
+            },
+            "action": {
+              "type": "string"
+            },
+            "deadline": {
+              "type": "string"
+            },
+            "expectedResult": {
+              "type": "string"
+            }
           }
         }
       }
@@ -177,46 +271,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 163 - 42
dist/skills/tiktok-brand-voc/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "tiktok-brand-voc",
   "displayName": "TikTok品牌VOC采集",
   "description": "搜索竞品品牌TikTok账号,采集发布内容和用户评论,分析品牌社媒策略",
@@ -8,7 +8,9 @@
   "parameters": {
     "brandNames": {
       "type": "array",
-      "items": { "type": "string" },
+      "items": {
+        "type": "string"
+      },
       "required": true,
       "description": "竞品品牌名称列表"
     },
@@ -40,8 +42,14 @@
         "skill": "social-media/tiktok-user-search",
         "endpoint": "https://server.fmode.cn/api/voc-social/tiktok/web/fetch_search_user",
         "method": "GET",
-        "headers": { "Authorization": "Bearer ${TIKHUB_TOKEN}" },
-        "queryParams": { "keyword": "${brandName}", "count": 5, "cursor": 0 }
+        "headers": {
+          "Authorization": "Bearer ${vocToken}"
+        },
+        "queryParams": {
+          "keyword": "${brandName}",
+          "count": 5,
+          "cursor": 0
+        }
       },
       "output": "brandAccounts",
       "responseExtract": "user_list[] → { user_info: { unique_id, nickname, follower_count, following_count, total_favorited, video_count, signature } }",
@@ -55,8 +63,12 @@
         "skill": "social-media/tiktok-user-profile",
         "endpoint": "https://server.fmode.cn/api/voc-social/tiktok/app/v3/handler_user_profile",
         "method": "GET",
-        "headers": { "Authorization": "Bearer ${TIKHUB_TOKEN}" },
-        "queryParams": { "unique_id": "${account.unique_id}" }
+        "headers": {
+          "Authorization": "Bearer ${vocToken}"
+        },
+        "queryParams": {
+          "unique_id": "${account.unique_id}"
+        }
       },
       "output": "brandProfiles",
       "responseExtract": "{ user: { nickname, unique_id, follower_count, total_favorited, video_count, signature, verified } }"
@@ -69,8 +81,14 @@
         "skill": "social-media/tiktok-user-posts",
         "endpoint": "https://server.fmode.cn/api/voc-social/tiktok/app/v3/fetch_user_post_videos",
         "method": "GET",
-        "headers": { "Authorization": "Bearer ${TIKHUB_TOKEN}" },
-        "queryParams": { "unique_id": "${account.unique_id}", "count": "${postsPerBrand}", "cursor": 0 }
+        "headers": {
+          "Authorization": "Bearer ${vocToken}"
+        },
+        "queryParams": {
+          "unique_id": "${account.unique_id}",
+          "count": "${postsPerBrand}",
+          "cursor": 0
+        }
       },
       "output": "brandPosts",
       "responseExtract": "aweme_list[] → { aweme_id, desc, statistics:{play_count,digg_count,comment_count,share_count}, create_time }"
@@ -84,8 +102,14 @@
         "skill": "social-media/tiktok-video-comments",
         "endpoint": "https://server.fmode.cn/api/voc-social/tiktok/app/v3/fetch_video_comments",
         "method": "GET",
-        "headers": { "Authorization": "Bearer ${TIKHUB_TOKEN}" },
-        "queryParams": { "aweme_id": "${post.aweme_id}", "count": "${commentsPerPost}", "cursor": 0 }
+        "headers": {
+          "Authorization": "Bearer ${vocToken}"
+        },
+        "queryParams": {
+          "aweme_id": "${post.aweme_id}",
+          "count": "${commentsPerPost}",
+          "cursor": 0
+        }
       },
       "output": "postComments",
       "responseExtract": "comments[] → { cid, text, digg_count, reply_comment_total, create_time }"
@@ -114,14 +138,30 @@
         "items": {
           "type": "object",
           "properties": {
-            "brandName": { "type": "string" },
-            "tiktokId": { "type": "string" },
-            "followerCount": { "type": "integer" },
-            "avgPlayCount": { "type": "integer" },
-            "avgEngagementRate": { "type": "number" },
-            "postFrequency": { "type": "string" },
-            "topContentThemes": { "type": "array" },
-            "commentSentiment": { "type": "object" }
+            "brandName": {
+              "type": "string"
+            },
+            "tiktokId": {
+              "type": "string"
+            },
+            "followerCount": {
+              "type": "integer"
+            },
+            "avgPlayCount": {
+              "type": "integer"
+            },
+            "avgEngagementRate": {
+              "type": "number"
+            },
+            "postFrequency": {
+              "type": "string"
+            },
+            "topContentThemes": {
+              "type": "array"
+            },
+            "commentSentiment": {
+              "type": "object"
+            }
           }
         }
       },
@@ -129,9 +169,15 @@
         "type": "object",
         "description": "品牌间横向对比",
         "properties": {
-          "followerRanking": { "type": "array" },
-          "engagementRanking": { "type": "array" },
-          "contentStrategyComparison": { "type": "object" }
+          "followerRanking": {
+            "type": "array"
+          },
+          "engagementRanking": {
+            "type": "array"
+          },
+          "contentStrategyComparison": {
+            "type": "object"
+          }
         }
       }
     }
@@ -146,46 +192,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 179 - 47
dist/skills/tiktok-category-voc/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "tiktok-category-voc",
   "displayName": "TikTok品类VOC采集",
   "description": "基于品类关键词搜索TikTok视频并批量采集评论,提取用户讨论热点和情感倾向",
@@ -8,7 +8,9 @@
   "parameters": {
     "keywords": {
       "type": "array",
-      "items": { "type": "string" },
+      "items": {
+        "type": "string"
+      },
       "required": true,
       "description": "品类关键词列表"
     },
@@ -26,7 +28,9 @@
     },
     "hashtags": {
       "type": "array",
-      "items": { "type": "string" },
+      "items": {
+        "type": "string"
+      },
       "required": false,
       "description": "关联话题标签"
     }
@@ -40,8 +44,14 @@
         "skill": "social-media/tiktok-video-search",
         "endpoint": "https://server.fmode.cn/api/voc-social/tiktok/app/v3/fetch_video_search_result",
         "method": "GET",
-        "headers": { "Authorization": "Bearer ${TIKHUB_TOKEN}" },
-        "queryParams": { "keyword": "${keyword}", "count": "${videoCount}", "cursor": 0 }
+        "headers": {
+          "Authorization": "Bearer ${vocToken}"
+        },
+        "queryParams": {
+          "keyword": "${keyword}",
+          "count": "${videoCount}",
+          "cursor": 0
+        }
       },
       "output": "searchResults",
       "responseExtract": "aweme_list || search_item_list[].aweme_info → Array<{ aweme_id, desc, statistics:{play_count,digg_count,comment_count,share_count}, author:{nickname,unique_id,follower_count}, cha_list }>"
@@ -54,8 +64,14 @@
         "skill": "social-media/tiktok-video-comments",
         "endpoint": "https://server.fmode.cn/api/voc-social/tiktok/app/v3/fetch_video_comments",
         "method": "GET",
-        "headers": { "Authorization": "Bearer ${TIKHUB_TOKEN}" },
-        "queryParams": { "aweme_id": "${video.aweme_id}", "count": "${commentsPerVideo}", "cursor": 0 }
+        "headers": {
+          "Authorization": "Bearer ${vocToken}"
+        },
+        "queryParams": {
+          "aweme_id": "${video.aweme_id}",
+          "count": "${commentsPerVideo}",
+          "cursor": 0
+        }
       },
       "output": "videoComments",
       "responseExtract": "comments[] → Array<{ cid, text, digg_count, reply_comment_total, create_time, user:{nickname,unique_id} }>"
@@ -69,8 +85,12 @@
         "skill": "social-media/tiktok-hashtag-detail",
         "endpoint": "https://server.fmode.cn/api/voc-social/tiktok/app/v3/fetch_hashtag_detail",
         "method": "GET",
-        "headers": { "Authorization": "Bearer ${TIKHUB_TOKEN}" },
-        "queryParams": { "ch_name": "${tag}" }
+        "headers": {
+          "Authorization": "Bearer ${vocToken}"
+        },
+        "queryParams": {
+          "ch_name": "${tag}"
+        }
       },
       "output": "hashtagDetails",
       "responseExtract": "{ ch_info: { cha_name, cid, desc, view_count, video_count } }"
@@ -84,8 +104,14 @@
         "skill": "social-media/tiktok-hashtag-videos",
         "endpoint": "https://server.fmode.cn/api/voc-social/tiktok/app/v3/fetch_hashtag_video_list",
         "method": "GET",
-        "headers": { "Authorization": "Bearer ${TIKHUB_TOKEN}" },
-        "queryParams": { "ch_id": "${hashtag.cid}", "count": 20, "cursor": 0 }
+        "headers": {
+          "Authorization": "Bearer ${vocToken}"
+        },
+        "queryParams": {
+          "ch_id": "${hashtag.cid}",
+          "count": 20,
+          "cursor": 0
+        }
       },
       "output": "hashtagVideos"
     },
@@ -112,26 +138,49 @@
         "items": {
           "type": "object",
           "properties": {
-            "aweme_id": { "type": "string" },
-            "desc": { "type": "string" },
-            "playCount": { "type": "integer" },
-            "diggCount": { "type": "integer" },
-            "commentCount": { "type": "integer" },
-            "shareCount": { "type": "integer" },
-            "author": { "type": "string" }
+            "aweme_id": {
+              "type": "string"
+            },
+            "desc": {
+              "type": "string"
+            },
+            "playCount": {
+              "type": "integer"
+            },
+            "diggCount": {
+              "type": "integer"
+            },
+            "commentCount": {
+              "type": "integer"
+            },
+            "shareCount": {
+              "type": "integer"
+            },
+            "author": {
+              "type": "string"
+            }
           }
         }
       },
-      "comments": { "type": "array", "description": "采集的评论列表" },
+      "comments": {
+        "type": "array",
+        "description": "采集的评论列表"
+      },
       "hashtags": {
         "type": "array",
         "description": "话题热度数据",
         "items": {
           "type": "object",
           "properties": {
-            "name": { "type": "string" },
-            "viewCount": { "type": "integer" },
-            "videoCount": { "type": "integer" }
+            "name": {
+              "type": "string"
+            },
+            "viewCount": {
+              "type": "integer"
+            },
+            "videoCount": {
+              "type": "integer"
+            }
           }
         }
       },
@@ -139,10 +188,18 @@
         "type": "object",
         "description": "初步分析结果",
         "properties": {
-          "totalPlayCount": { "type": "integer" },
-          "avgEngagementRate": { "type": "number" },
-          "topTopics": { "type": "array" },
-          "sentimentSummary": { "type": "object" }
+          "totalPlayCount": {
+            "type": "integer"
+          },
+          "avgEngagementRate": {
+            "type": "number"
+          },
+          "topTopics": {
+            "type": "array"
+          },
+          "sentimentSummary": {
+            "type": "object"
+          }
         }
       }
     }
@@ -157,46 +214,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 98 - 23
dist/skills/tiktok-hashtag-detail/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "tiktok-hashtag-detail",
   "displayName": "TikTok 话题详情",
   "description": "根据话题/标签 ID 获取 TikTok 话题详情,包括总播放量、视频使用数等。适用于品类 TikTok 话题热度量化、话题对标分析、内容营销话题选择。",
@@ -8,7 +8,7 @@
     "method": "GET",
     "url": "https://server.fmode.cn/api/voc-social/tiktok/app/v3/fetch_hashtag_detail",
     "headers": {
-      "Authorization": "Bearer r:a5a19ea9868043b15d9b10423234ca43",
+      "Authorization": "Bearer ${vocToken}",
       "Accept": "application/json"
     }
   },
@@ -105,46 +105,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 98 - 23
dist/skills/tiktok-hashtag-videos/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "tiktok-hashtag-videos",
   "displayName": "TikTok 话题视频列表",
   "description": "获取指定 TikTok 话题下的视频列表,包括播放量/点赞/作者等数据。适用于话题内容作战分析、品类爆款内容发现、话题 KOL 筛选。",
@@ -8,7 +8,7 @@
     "method": "GET",
     "url": "https://server.fmode.cn/api/voc-social/tiktok/app/v3/fetch_hashtag_video_list",
     "headers": {
-      "Authorization": "Bearer r:a5a19ea9868043b15d9b10423234ca43",
+      "Authorization": "Bearer ${vocToken}",
       "Accept": "application/json"
     }
   },
@@ -149,46 +149,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 98 - 23
dist/skills/tiktok-user-posts/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "tiktok-user-posts",
   "displayName": "TikTok 用户作品列表",
   "description": "获取指定 TikTok 用户发布的视频列表,包括播放量、点赞、评论等数据。适用于竞品品牌内容策略分析、KOL 年度内容表现评估、达人带货说服力分析。",
@@ -8,7 +8,7 @@
     "method": "GET",
     "url": "https://server.fmode.cn/api/voc-social/tiktok/app/v3/fetch_user_post_videos",
     "headers": {
-      "Authorization": "Bearer r:a5a19ea9868043b15d9b10423234ca43",
+      "Authorization": "Bearer ${vocToken}",
       "Accept": "application/json"
     }
   },
@@ -146,46 +146,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 98 - 23
dist/skills/tiktok-user-profile/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "tiktok-user-profile",
   "displayName": "TikTok 用户详情",
   "description": "根据用户名获取 TikTok 用户完整资料(粉丝数/总获赞/作品数/个人简介等)。适用于竞品品牌 TikTok 影响力分析、KOL 达人档案建立、达人商业价値评估。",
@@ -8,7 +8,7 @@
     "method": "GET",
     "url": "https://server.fmode.cn/api/voc-social/tiktok/web/fetch_user_profile",
     "headers": {
-      "Authorization": "Bearer r:a5a19ea9868043b15d9b10423234ca43",
+      "Authorization": "Bearer ${vocToken}",
       "Accept": "application/json"
     }
   },
@@ -152,46 +152,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 98 - 23
dist/skills/tiktok-user-search/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "tiktok-user-search",
   "displayName": "TikTok 用户搜索",
   "description": "按关键词搜索 TikTok 达人/用户,返回匹配账号列表及基础数据。适用于 KOL 候选人初筛、品类达人批量搜索、竞品品牌账号定位。",
@@ -8,7 +8,7 @@
     "method": "GET",
     "url": "https://server.fmode.cn/api/voc-social/tiktok/web/fetch_search_user",
     "headers": {
-      "Authorization": "Bearer r:a5a19ea9868043b15d9b10423234ca43",
+      "Authorization": "Bearer ${vocToken}",
       "Accept": "application/json"
     }
   },
@@ -142,46 +142,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 98 - 23
dist/skills/tiktok-video-comments/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "tiktok-video-comments",
   "displayName": "TikTok 视频评论查询",
   "description": "获取指定 TikTok 视频的用户评论列表,支持翻页。用户评论是 VOC 情感分析、痛点挖掘、需求发现的核心英文数据源。适用于品类用户评价采集、竞品带货视频反馈分析。",
@@ -8,7 +8,7 @@
     "method": "GET",
     "url": "https://server.fmode.cn/api/voc-social/tiktok/app/v3/fetch_video_comments",
     "headers": {
-      "Authorization": "Bearer r:a5a19ea9868043b15d9b10423234ca43",
+      "Authorization": "Bearer ${vocToken}",
       "Accept": "application/json"
     }
   },
@@ -151,46 +151,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 98 - 23
dist/skills/tiktok-video-detail/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "tiktok-video-detail",
   "displayName": "TikTok 视频详情",
   "description": "根据视频 ID 获取单条 TikTok 视频完整数据(播放量/点赞/评论/分享/话题标签/作者等)。适用于爆款视频深度分析、竞品内容解析、KOL 内容效果评估。",
@@ -8,7 +8,7 @@
     "method": "GET",
     "url": "https://server.fmode.cn/api/voc-social/tiktok/app/v3/fetch_one_video",
     "headers": {
-      "Authorization": "Bearer r:a5a19ea9868043b15d9b10423234ca43",
+      "Authorization": "Bearer ${vocToken}",
       "Accept": "application/json"
     }
   },
@@ -145,46 +145,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 98 - 23
dist/skills/tiktok-video-search/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "tiktok-video-search",
   "displayName": "TikTok 视频搜索",
   "description": "按关键词搜索 TikTok 视频,返回视频列表及播放量/点赞/评论/分享等数据。适用于品类 TikTok 爆款内容发现、竞品视频监控、社媒频道热度统计、KOL 内容效果对比。",
@@ -8,7 +8,7 @@
     "method": "GET",
     "url": "https://server.fmode.cn/api/voc-social/tiktok/app/v3/fetch_video_search_result",
     "headers": {
-      "Authorization": "Bearer r:a5a19ea9868043b15d9b10423234ca43",
+      "Authorization": "Bearer ${vocToken}",
       "Accept": "application/json"
     }
   },
@@ -196,46 +196,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 236 - 0
dist/skills/transcript-to-video/SKILL.md

@@ -0,0 +1,236 @@
+---
+name: transcript-to-video
+description: 逐字稿全自动视频生成工作流:输入逐字稿文本,AI拆分镜脚本,批量生成视频素材,输出视频片段URL列表+SRT字幕文件。
+version: 1.0.0
+author: nkkj-BrainHack
+---
+
+# 逐字稿 → AI视频生成工作流 (Transcript to Video)
+
+## 功能用途
+
+将一份逐字稿(文字脚本)全自动转化为AI视频素材。覆盖从文本拆分、分镜脚本生成、AI视频/图片批量生成、到结果汇总的完整链路。
+
+**核心业务场景:**
+- 自媒体内容创作:逐字稿 → 分镜 → AI视频素材 → 剪映成片
+- 批量短视频生产:一份长脚本 → N个视频片段
+- 知识付费/教程:讲稿 → 配图/配视频素材
+
+## 调用链(Workflow)
+
+```
+输入: 逐字稿文本(中文)
+  ↓
+Stage 1: AI 分镜脚本生成
+  Agent 将逐字稿拆分为分镜 JSON + SRT 字幕文件
+  每段包含: id, narration(中文旁白), prompt(英文视频提示词), duration(秒)
+  ↓
+Stage 2: 批量生成视频素材(并行)
+  对每个分镜段,调用 jimeng-video-v3-720p(文生视频)
+  或先调用 jimeng-img-v4(文生图)再调用 jimeng-video-v3-720p method=2(图生视频)
+  ↓
+Stage 3: 轮询获取结果(并行)
+  对每个任务调用 jimeng-task-query 轮询
+  完成后调用 jimeng-work-result 获取视频URL
+  ↓
+Stage 4: 结果汇总
+  输出: 视频片段URL列表 + SRT字幕文件 + 分镜脚本JSON
+  ↓
+可选 Stage 5: 一键成片
+  将部分素材传入 quickly-video-create 生成短视频(最长30秒)
+  或用户导入剪映/CapCut手动按SRT时间轴对齐
+```
+
+## 输入参数
+
+| 参数 | 类型 | 必填 | 说明 |
+|------|------|------|------|
+| transcript | string | ✅ | 逐字稿全文(中文) |
+| segmentDuration | number | ❌ | 每段目标时长(秒),默认15 |
+| videoModel | string | ❌ | 视频生成模型:`720p`(默认) / `1080p` / `pro` |
+| videoMethod | string | ❌ | 生成方式:`text2video`(默认,纯文生视频) / `img2video`(先生图再图生视频,效果更可控) |
+| aspectRatio | string | ❌ | 视频比例,默认 `16:9`,可选 `9:16` / `1:1` / `4:3` |
+| frames | number | ❌ | 帧数:121(5秒,默认) 或 241(10秒) |
+
+## 执行流程
+
+### Stage 1: AI 分镜脚本生成(Agent 执行)
+
+Agent 根据逐字稿,按每 `segmentDuration` 秒拆分为分镜段,输出:
+
+**分镜 JSON 格式:**
+```json
+[
+  {
+    "id": "S-01",
+    "act": "开场",
+    "narration": "回到开头那个数字,500美元。这个数字之所以让人震撼...",
+    "type": "ai-gen",
+    "prompt": "Extreme wide shot: a single desk with a glowing monitor floating in an infinite dark void...",
+    "duration": "15s"
+  },
+  {
+    "id": "S-02",
+    "act": "正文",
+    "narration": "然后他——或者说他——用这套工具在这个几乎不可能赚到钱的...",
+    "type": "ai-gen",
+    "prompt": "Final shot callback: the massive fortress wall from the opening...",
+    "duration": "15s"
+  }
+]
+```
+
+**SRT 字幕文件格式:**
+```srt
+1
+00:00:00,000 --> 00:00:15,000
+回到开头那个数字,500美元。这个数字之所以让人震撼...
+
+2
+00:00:15,000 --> 00:00:30,000
+然后他——或者说他——用这套工具在这个几乎不可能赚到钱的...
+```
+
+**分镜拆分规则:**
+- 每段约40~45个中文字(约15秒语速)
+- narration 用中文(原始逐字稿文本)
+- prompt 用英文(翻译+扩写为画面描述,适合AI视频生成)
+- prompt 应包含:镜头类型、场景、动作、氛围、画质关键词
+
+### Stage 2: 批量生成视频素材
+
+**方式A: text2video(文生视频,快速)**
+
+对每个分镜段,调用:
+```
+jimeng-video-v3-720p:
+  prompt: segment.prompt
+  method: "1"  (文生视频)
+  frames: 121  (5秒) 或 241 (10秒)
+  config:
+    aspect_ratio: "16:9"
+```
+
+**方式B: img2video(先图后视频,效果更可控)**
+
+Step 1: 对每个分镜段,先生成图片:
+```
+jimeng-img-v4:
+  prompt: segment.prompt
+  sizeDate: { width: 2560, height: 1440 }  (16:9)
+```
+
+Step 2: 图片生成完成后,用图片作为首帧生成视频:
+```
+jimeng-video-v3-720p:
+  prompt: segment.prompt
+  method: "2"  (首帧图生视频)
+  frames: 121
+  config:
+    image_urls: [图片URL]
+```
+
+**并行策略:**
+- 最多 5 个分镜段并行生成
+- 每段生成间隔 1 秒(避免频率限制)
+- 单段超时 5 分钟
+
+### Stage 3: 轮询获取结果
+
+对每个生成任务:
+
+```
+jimeng-task-query:
+  workId: <上一步返回的workId>
+  routerName: "getVideoV3_720p"  (或对应的routerName)
+```
+
+轮询直到 `isFinish: true`,然后:
+
+```
+jimeng-work-result:
+  workId: <workId>
+→ 获取 videos[0] 作为该分镜段的视频URL
+```
+
+### Stage 4: 结果汇总
+
+输出完整的视频素材包:
+```json
+{
+  "storyboard": [...],        // 分镜JSON
+  "srt": "...",               // SRT字幕内容
+  "segments": [
+    {
+      "id": "S-01",
+      "videoUrl": "https://...",  // 视频URL(永久有效)
+      "duration": 5,              // 实际视频时长
+      "prompt": "..."
+    }
+  ],
+  "totalSegments": 71,
+  "successCount": 70,
+  "failedCount": 1,
+  "failedIds": ["S-45"]
+}
+```
+
+### 可选 Stage 5: 一键成片(quickly-video-create)
+
+将生成的视频素材传入 quickly-video-create:
+```
+quickly-video-create:
+  material_list: segments.map(s => ({ type: "video", value: s.videoUrl }))
+  tags: "从逐字稿提取的关键词"
+  proportion: "16:9" 或 "9:16"
+  video_duration: { min: 15, max: 30 }
+  ai_voice: 1
+  ai_bgm: 1
+```
+
+**注意:** quickly-video-create 最长 30 秒,适合将少量片段合成短视频预览。完整长视频需用户在剪映/CapCut中手动拼接。
+
+## 调用的底层 Skill
+
+| Skill | 阶段 | 用途 |
+|-------|------|------|
+| `jimeng-video-v3-720p` | Stage 2 | 文生视频 / 图生视频 |
+| `jimeng-video-v3-1080p` | Stage 2 | 1080p视频(可选) |
+| `jimeng-video-v3-pro` | Stage 2 | Pro质量视频(可选) |
+| `jimeng-img-v4` | Stage 2 | 文生图(img2video模式首帧) |
+| `jimeng-task-query` | Stage 3 | 轮询任务状态 |
+| `jimeng-work-result` | Stage 3 | 获取最终视频URL |
+| `quickly-video-create` | Stage 5 | 可选,素材合成短视频 |
+| `quickly-video-query` | Stage 5 | 可选,轮询成片结果 |
+
+## 费用估算
+
+以71个分镜段为例(按5秒/段计算):
+
+| 项目 | 单价 | 数量 | 费用 |
+|------|------|------|------|
+| jimeng-video-v3-720p | 0.28元/秒 × 5秒 = 1.4元/段 | 71段 | ≈99.4元 |
+| jimeng-img-v4(img2video模式) | 0.22元/张 | 71张 | ≈15.6元 |
+| **text2video 模式总计** | | | **≈99元** |
+| **img2video 模式总计** | | | **≈115元** |
+
+## 当前限制
+
+| 限制 | 说明 | 解决方案 |
+|------|------|---------|
+| 视频时长固定 | jimeng 只支持 5秒(121帧) 或 10秒(241帧),无法精确匹配SRT时间戳 | 用户在剪映中裁剪/变速对齐 |
+| 无TTS配音 | 无法按逐字稿自动生成语音 | 用户在剪映中录音/AI配音 |
+| 无自动拼接 | 无法将N个片段自动拼接成长视频 | 用户在剪映中拼接,或用quickly(≤30秒) |
+| 并行数限制 | 即梦API频率限制,建议≤5并行 | 分批执行,每批5个 |
+
+## 后续扩展(待新增Skill)
+
+1. **TTS配音 Skill** — 按逐字稿生成语音音频,实现自动配音
+2. **视频拼接 Skill** — FFmpeg服务端拼接,按SRT时间轴精确对齐
+3. **seeddance2.0 Skill** — 接入新一代视频生成模型,支持更长时长和更高质量
+
+## 依赖
+
+- 即梦AI视频生成接口(已有,通过 `server.fmode.cn` 代理)
+- 即梦AI Token(通过 APIG 充值获取)
+- Agent AI能力(用于分镜脚本生成)

+ 529 - 0
dist/skills/transcript-to-video/api-config.json

@@ -0,0 +1,529 @@
+{
+  "name": "transcript-to-video",
+  "displayName": "逐字稿 AI 视频生成工作流",
+  "description": "输入逐字稿文本,AI 自动拆分分镜脚本,批量生成视频素材,输出视频片段 URL 列表和 SRT 字幕文件。支持文生视频和先图后视频两种模式。",
+  "category": "video-creation",
+  "version": "1.0.0",
+  "type": "orchestration",
+  "parameters": {
+    "type": "object",
+    "required": [
+      "transcript"
+    ],
+    "properties": {
+      "transcript": {
+        "type": "string",
+        "description": "逐字稿全文(中文),Agent 将自动拆分为分镜段"
+      },
+      "segmentDuration": {
+        "type": "number",
+        "description": "姣忔鐩爣鏃堕暱锛堢锛夛紝褰卞搷鍒嗛暅鎷嗗垎绮掑害",
+        "default": 15
+      },
+      "videoModel": {
+        "type": "string",
+        "enum": [
+          "720p",
+          "1080p",
+          "pro"
+        ],
+        "description": "瑙嗛鐢熸垚妯″瀷璐ㄩ噺绛夌骇",
+        "default": "720p"
+      },
+      "videoMethod": {
+        "type": "string",
+        "enum": [
+          "text2video",
+          "img2video"
+        ],
+        "description": "text2video=纯文生视频(更快),img2video=先生成图片再图生视频(效果更可控)",
+        "default": "text2video"
+      },
+      "aspectRatio": {
+        "type": "string",
+        "enum": [
+          "16:9",
+          "9:16",
+          "1:1",
+          "4:3",
+          "3:4",
+          "21:9"
+        ],
+        "description": "瑙嗛鐢婚潰姣斾緥",
+        "default": "16:9"
+      },
+      "frames": {
+        "type": "integer",
+        "enum": [
+          121,
+          241
+        ],
+        "description": "视频帧数,121=5秒,241=10秒",
+        "default": 121
+      }
+    }
+  },
+  "pipeline": [
+    {
+      "step": 1,
+      "name": "AI鍒嗛暅鑴氭湰鐢熸垚",
+      "type": "ai",
+      "description": "Agent灏嗛€愬瓧绋挎媶鍒嗕负鍒嗛暅JSON鍜孲RT瀛楀箷",
+      "aiConfig": {
+        "systemPrompt": "你是专业的视频分镜脚本编写专家。请将逐字稿拆分为分镜段,每段约 40-45 个中文字(约 15 秒语速)。为每段生成英文视频提示词(prompt),描述画面内容、镜头类型、氛围和画质。",
+        "userPromptTemplate": "请将以下逐字稿拆分为分镜脚本,每段约 ${segmentDuration} 秒。\n\n逐字稿:\n${transcript}\n\n请输出 JSON 数组,每项包含 id、act、narration、type、prompt、duration 字段,并同时输出 SRT 字幕文件内容。",
+        "outputFormat": {
+          "storyboard": "Array<{id, act, narration, type, prompt, duration}>",
+          "srt": "String (SRT format subtitle content)"
+        },
+        "temperature": 0.3
+      },
+      "output": {
+        "storyboard": "鍒嗛暅JSON鏁扮粍",
+        "srt": "SRT瀛楀箷鏂囦欢鍐呭"
+      }
+    },
+    {
+      "step": 2,
+      "name": "鎵归噺鐢熸垚瑙嗛绱犳潗",
+      "type": "api",
+      "description": "瀵规瘡涓垎闀滄骞惰璋冪敤鍗虫ⅵ瑙嗛鐢熸垚API",
+      "forEach": "storyboard",
+      "forEachAs": "segment",
+      "parallel": {
+        "maxConcurrent": 5,
+        "delayMs": 1000
+      },
+      "branches": {
+        "text2video": {
+          "condition": "videoMethod === 'text2video'",
+          "steps": [
+            {
+              "id": "2a",
+              "name": "鏂囩敓瑙嗛",
+              "skill": "jimeng/jimeng-video-v3-720p",
+              "skillVariants": {
+                "720p": "jimeng/jimeng-video-v3-720p",
+                "1080p": "jimeng/jimeng-video-v3-1080p",
+                "pro": "jimeng/jimeng-video-v3-pro"
+              },
+              "input": {
+                "prompt": "${segment.prompt}",
+                "method": "1",
+                "frames": "${frames}",
+                "config": {
+                  "aspect_ratio": "${aspectRatio}"
+                }
+              },
+              "output": "workIds[${segment.id}]"
+            }
+          ]
+        },
+        "img2video": {
+          "condition": "videoMethod === 'img2video'",
+          "steps": [
+            {
+              "id": "2b-1",
+              "name": "文生图(首帧)",
+              "skill": "jimeng/jimeng-img-v4",
+              "input": {
+                "prompt": "${segment.prompt}",
+                "sizeDate": {
+                  "width": "${aspectRatio === '16:9' ? 2560 : aspectRatio === '9:16' ? 1440 : 2048}",
+                  "height": "${aspectRatio === '16:9' ? 1440 : aspectRatio === '9:16' ? 2560 : 2048}"
+                }
+              },
+              "output": "imageWorkIds[${segment.id}]"
+            },
+            {
+              "id": "2b-2",
+              "name": "杞鍥剧墖缁撴灉",
+              "skill": "jimeng/jimeng-task-query",
+              "dependsOn": [
+                "2b-1"
+              ],
+              "input": {
+                "workId": "${imageWorkIds[segment.id]}",
+                "routerName": "getImgV4"
+              },
+              "pollingConfig": {
+                "intervalMs": 3000,
+                "maxAttempts": 30,
+                "completionCondition": "data.isFinish === true"
+              }
+            },
+            {
+              "id": "2b-3",
+              "name": "鑾峰彇鍥剧墖URL",
+              "skill": "jimeng/jimeng-work-result",
+              "dependsOn": [
+                "2b-2"
+              ],
+              "input": {
+                "workId": "${imageWorkIds[segment.id]}"
+              },
+              "output": "imageUrls[${segment.id}]",
+              "responseExtract": "images[0]"
+            },
+            {
+              "id": "2b-4",
+              "name": "鍥剧敓瑙嗛锛堥甯э級",
+              "skill": "jimeng/jimeng-video-v3-720p",
+              "dependsOn": [
+                "2b-3"
+              ],
+              "input": {
+                "prompt": "${segment.prompt}",
+                "method": "2",
+                "frames": "${frames}",
+                "config": {
+                  "image_urls": [
+                    "${imageUrls[segment.id]}"
+                  ]
+                }
+              },
+              "output": "workIds[${segment.id}]"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "step": 3,
+      "name": "杞瑙嗛鐢熸垚缁撴灉",
+      "type": "api",
+      "forEach": "workIds",
+      "forEachAs": "workId",
+      "parallel": {
+        "maxConcurrent": 10,
+        "delayMs": 500
+      },
+      "steps": [
+        {
+          "id": "3a",
+          "name": "轮询任务状态",
+          "skill": "jimeng/jimeng-task-query",
+          "input": {
+            "workId": "${workId}",
+            "routerName": "${videoModel === '720p' ? 'getVideoV3_720p' : videoModel === '1080p' ? 'getVideoV3_1080p' : 'getVideoV3_Pro'}"
+          },
+          "pollingConfig": {
+            "intervalMs": 5000,
+            "maxAttempts": 60,
+            "completionCondition": "data.isFinish === true",
+            "timeoutMs": 300000
+          }
+        },
+        {
+          "id": "3b",
+          "name": "鑾峰彇瑙嗛URL",
+          "skill": "jimeng/jimeng-work-result",
+          "dependsOn": [
+            "3a"
+          ],
+          "input": {
+            "workId": "${workId}"
+          },
+          "output": "videoResults[${segmentId}]",
+          "responseExtract": {
+            "videoUrl": "videos[0]",
+            "images": "images"
+          }
+        }
+      ]
+    },
+    {
+      "step": 4,
+      "name": "结果汇总",
+      "type": "compute",
+      "logic": "aggregateResults(storyboard, srt, videoResults)",
+      "algorithm": {
+        "merge": "灏嗗垎闀淛SON涓庤棰慤RL鍚堝苟",
+        "stats": "缁熻鎴愬姛/澶辫触鏁伴噺",
+        "failedRetry": "澶辫触鐨勫垎闀滄鏍囪涓篺ailedIds锛屽彲閲嶈瘯"
+      },
+      "output": "finalOutput"
+    },
+    {
+      "step": 5,
+      "name": "可选:一键成片",
+      "type": "api",
+      "optional": true,
+      "condition": "user requests quick compilation && successCount <= 50 && totalDuration <= 30",
+      "skill": "video-creation/quickly-video-create",
+      "input": {
+        "material_list": "${videoResults.map(r => ({ type: 'video', value: r.videoUrl }))}",
+        "tags": "${extractKeywords(transcript)}",
+        "proportion": "${aspectRatio === '9:16' ? '9:16' : aspectRatio === '1:1' ? '1:1' : '9:16'}",
+        "video_duration": {
+          "min": 15,
+          "max": 30
+        },
+        "pre_id": "${Date.now().toString()}",
+        "ai_voice": 1,
+        "ai_bgm": 1,
+        "ai_subtitle": 1
+      },
+      "output": "quicklyTaskId",
+      "downstream": "video-creation/quickly-video-query"
+    }
+  ],
+  "response": {
+    "type": "object",
+    "properties": {
+      "storyboard": {
+        "type": "array",
+        "description": "鍒嗛暅鑴氭湰JSON",
+        "items": {
+          "type": "object",
+          "properties": {
+            "id": {
+              "type": "string"
+            },
+            "act": {
+              "type": "string"
+            },
+            "narration": {
+              "type": "string"
+            },
+            "prompt": {
+              "type": "string"
+            },
+            "duration": {
+              "type": "string"
+            },
+            "videoUrl": {
+              "type": "string",
+              "description": "鐢熸垚鐨勮棰慤RL锛堟案涔呮湁鏁堬級"
+            },
+            "imageUrl": {
+              "type": "string",
+              "description": "生成的首帧图片 URL(img2video 模式)"
+            }
+          }
+        }
+      },
+      "srt": {
+        "type": "string",
+        "description": "SRT瀛楀箷鏂囦欢鍐呭"
+      },
+      "segments": {
+        "type": "array",
+        "description": "视频片段汇总",
+        "items": {
+          "type": "object",
+          "properties": {
+            "id": {
+              "type": "string"
+            },
+            "videoUrl": {
+              "type": "string"
+            },
+            "duration": {
+              "type": "number"
+            },
+            "prompt": {
+              "type": "string"
+            }
+          }
+        }
+      },
+      "totalSegments": {
+        "type": "integer"
+      },
+      "successCount": {
+        "type": "integer"
+      },
+      "failedCount": {
+        "type": "integer"
+      },
+      "failedIds": {
+        "type": "array",
+        "items": {
+          "type": "string"
+        }
+      }
+    }
+  },
+  "relatedSkills": [
+    "jimeng/jimeng-video-v3-720p",
+    "jimeng/jimeng-video-v3-1080p",
+    "jimeng/jimeng-video-v3-pro",
+    "jimeng/jimeng-img-v4",
+    "jimeng/jimeng-task-query",
+    "jimeng/jimeng-work-result",
+    "video-creation/quickly-video-create",
+    "video-creation/quickly-video-query"
+  ],
+  "pricing": {
+    "text2video_720p_5s": {
+      "perSegment": 1.4,
+      "unit": "CNY",
+      "formula": "0.28元/秒 × 5秒"
+    },
+    "text2video_720p_10s": {
+      "perSegment": 2.8,
+      "unit": "CNY",
+      "formula": "0.28元/秒 × 10秒"
+    },
+    "img2video_720p_5s": {
+      "perSegment": 1.62,
+      "unit": "CNY",
+      "formula": "0.22鍏?鍥? + 0.28鍏?绉捗?绉?瑙嗛)"
+    },
+    "example_71segments_5s": {
+      "text2video": "约99元",
+      "img2video": "约115元"
+    }
+  },
+  "limitations": {
+    "videoDuration": "仅支持 5 秒(121 帧)或 10 秒(241 帧),无法精确匹配 SRT 时间戳",
+    "noTTS": "鏃燭TS閰嶉煶鑳藉姏锛岄渶鐢ㄦ埛鍦ㄥ壀鏄犱腑閰嶉煶",
+    "noAutoStitch": "暂无自动拼接长视频能力,quickly 最长 30 秒",
+    "parallelLimit": "即梦 API 建议并行数不超过 5,避免触发频率限制"
+  },
+  "futureExtensions": [
+    {
+      "name": "tts-voiceover",
+      "description": "TTS 配音 Skill:按逐字稿生成语音音频",
+      "status": "planned"
+    },
+    {
+      "name": "video-stitch",
+      "description": "视频拼接 Skill:FFmpeg 服务端按 SRT 时间轴精确拼接",
+      "status": "planned"
+    },
+    {
+      "name": "seeddance-video",
+      "description": "seeddance2.0 模型接入:生成更高质量视频",
+      "status": "planned"
+    }
+  ],
+  "tokenConfig": {
+    "type": "bearer",
+    "configFile": "~/.openclaw/voc-credentials.json",
+    "tokenField": "vocToken",
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "Vo3ROWEvDy",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "Vo3ROWEvDy",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
+    "onMissing": {
+      "action": "showPaymentQR",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=Vo3ROWEvDy&fun_id=HOkkX72PMF",
+      "title": "扫码开通 VOC-AI 数据服务",
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
+    },
+    "onBalanceInsufficient": {
+      "action": "resolveUserThenShowPayment",
+      "title": "VOC-AI Token 余额不足,请扫码充值",
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
+    }
+  },
+  "errorHandling": {
+    "balanceInsufficient": {
+      "conditions": [
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
+      ],
+      "matchMode": "any",
+      "trigger": "tokenConfig.onBalanceInsufficient"
+    },
+    "unauthorized": {
+      "conditions": [
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
+      ],
+      "matchMode": "any",
+      "trigger": "tokenConfig.onMissing"
+    }
+  },
+  "timeout": 600000,
+  "retry": {
+    "maxAttempts": 2,
+    "delay": 3000,
+    "backoffMultiplier": 2
+  }
+}

+ 193 - 48
dist/skills/user-persona/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "user-persona",
   "displayName": "用户画像生成",
   "description": "融合电商VOC和社媒VOC,AI生成核心用户画像、使用场景和决策因素",
@@ -67,7 +67,7 @@
       "aiConfig": {
         "systemPrompt": "你是跨境电商用户研究专家。只输出一个合法JSON对象。禁止输出Markdown、代码围栏、解释文字。",
         "userPromptTemplate": "基于以下VOC数据,生成3-5个核心用户画像。每个画像包含: 名称/年龄段/核心场景/决策因素/价格敏感度/社媒平台偏好/购买动机。\n场景数据: ${scenarios}\n决策因素: ${decisionFactors}\n关键词: ${topKeywords}",
-        "outputFormat": "{\"personas\":[{\"name\":\"“品质生活家\u201d\",\"ageRange\":\"28-40\",\"coreScenario\":\"家居装饰\",\"decisionFactors\":[\"品质\",\"香味\"],\"priceSensitivity\":\"medium\",\"socialPreference\":\"Instagram\",\"motivation\":\"提升家居氛围\"}]}",
+        "outputFormat": "{\"personas\":[{\"name\":\"“品质生活家\",\"ageRange\":\"28-40\",\"coreScenario\":\"家居装饰\",\"decisionFactors\":[\"品质\",\"香味\"],\"priceSensitivity\":\"medium\",\"socialPreference\":\"Instagram\",\"motivation\":\"提升家居氛围\"}]}",
         "temperature": 0.3,
         "maxTokens": 3000,
         "promptPattern": "system约束JSON输出 + user提供结构化数据 + outputFormat示例引导格式"
@@ -123,14 +123,39 @@
         "items": {
           "type": "object",
           "properties": {
-            "name": { "type": "string" },
-            "ageRange": { "type": "string" },
-            "coreScenario": { "type": "string" },
-            "decisionFactors": { "type": "array", "items": { "type": "string" } },
-            "priceSensitivity": { "type": "string", "enum": ["high", "medium", "low"] },
-            "socialPreference": { "type": "string" },
-            "motivation": { "type": "string" },
-            "proportion": { "type": "number", "description": "估算占比%" }
+            "name": {
+              "type": "string"
+            },
+            "ageRange": {
+              "type": "string"
+            },
+            "coreScenario": {
+              "type": "string"
+            },
+            "decisionFactors": {
+              "type": "array",
+              "items": {
+                "type": "string"
+              }
+            },
+            "priceSensitivity": {
+              "type": "string",
+              "enum": [
+                "high",
+                "medium",
+                "low"
+              ]
+            },
+            "socialPreference": {
+              "type": "string"
+            },
+            "motivation": {
+              "type": "string"
+            },
+            "proportion": {
+              "type": "number",
+              "description": "估算占比%"
+            }
           }
         }
       },
@@ -140,8 +165,12 @@
         "items": {
           "type": "object",
           "properties": {
-            "scenario": { "type": "string" },
-            "proportion": { "type": "number" }
+            "scenario": {
+              "type": "string"
+            },
+            "proportion": {
+              "type": "number"
+            }
           }
         }
       },
@@ -151,12 +180,19 @@
         "items": {
           "type": "object",
           "properties": {
-            "factor": { "type": "string" },
-            "weight": { "type": "number" }
+            "factor": {
+              "type": "string"
+            },
+            "weight": {
+              "type": "number"
+            }
           }
         }
       },
-      "handbookMarkdown": { "type": "string", "description": "画像手册(Markdown)" },
+      "handbookMarkdown": {
+        "type": "string",
+        "description": "画像手册(Markdown)"
+      },
       "purchaseBehavior": {
         "type": "object",
         "description": "购买行为分析",
@@ -166,10 +202,23 @@
             "items": {
               "type": "object",
               "properties": {
-                "persona": { "type": "string" },
-                "sensitivity": { "type": "string", "enum": ["high", "medium", "low"] },
-                "preferredBand": { "type": "string" },
-                "promotionResponse": { "type": "string" }
+                "persona": {
+                  "type": "string"
+                },
+                "sensitivity": {
+                  "type": "string",
+                  "enum": [
+                    "high",
+                    "medium",
+                    "low"
+                  ]
+                },
+                "preferredBand": {
+                  "type": "string"
+                },
+                "promotionResponse": {
+                  "type": "string"
+                }
               }
             }
           },
@@ -178,10 +227,23 @@
             "items": {
               "type": "object",
               "properties": {
-                "period": { "type": "string" },
-                "peakLevel": { "type": "string", "enum": ["high", "medium", "low"] },
-                "dominantPersona": { "type": "string" },
-                "marketingFocus": { "type": "string" }
+                "period": {
+                  "type": "string"
+                },
+                "peakLevel": {
+                  "type": "string",
+                  "enum": [
+                    "high",
+                    "medium",
+                    "low"
+                  ]
+                },
+                "dominantPersona": {
+                  "type": "string"
+                },
+                "marketingFocus": {
+                  "type": "string"
+                }
               }
             }
           },
@@ -190,10 +252,18 @@
             "items": {
               "type": "object",
               "properties": {
-                "persona": { "type": "string" },
-                "primaryChannel": { "type": "string" },
-                "discoveryPath": { "type": "string" },
-                "conversionDriver": { "type": "string" }
+                "persona": {
+                  "type": "string"
+                },
+                "primaryChannel": {
+                  "type": "string"
+                },
+                "discoveryPath": {
+                  "type": "string"
+                },
+                "conversionDriver": {
+                  "type": "string"
+                }
               }
             }
           }
@@ -211,46 +281,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "7HwdQZk55B",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "7HwdQZk55B",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 232 - 54
dist/skills/voc-proposal/api-config.json

@@ -1,4 +1,4 @@
-{
+{
   "name": "voc-proposal",
   "displayName": "VOC产品优化提案生成",
   "description": "整合所有VOC分析成果,AI生成11章节产品优化提案(含ROI估算+30天行动线)",
@@ -122,16 +122,44 @@
       "logic": "build30DayTimeline(proposal, roiAndRisks, dataIndex)",
       "algorithm": {
         "weeklyBreakdown": {
-          "week1": ["Listing优化(标题/五点/ST植入核心词)", "差评快速响应机制启动", "广告活动搭建(Auto+手动精准)"],
-          "week2": ["A+页面优化", "广告Bid调优基于第一周数据", "社媒内容发布启动"],
-          "week3": ["主图/视频迭代优化", "广告否词清理+新词扩展", "促销活动启动(Coupon/Deal)"],
-          "week4": ["效果复盘+数据分析", "下月计划制定", "库存补货决策"]
+          "week1": [
+            "Listing优化(标题/五点/ST植入核心词)",
+            "差评快速响应机制启动",
+            "广告活动搭建(Auto+手动精准)"
+          ],
+          "week2": [
+            "A+页面优化",
+            "广告Bid调优基于第一周数据",
+            "社媒内容发布启动"
+          ],
+          "week3": [
+            "主图/视频迭代优化",
+            "广告否词清理+新词扩展",
+            "促销活动启动(Coupon/Deal)"
+          ],
+          "week4": [
+            "效果复盘+数据分析",
+            "下月计划制定",
+            "库存补货决策"
+          ]
         },
         "milestones": [
-          { "day": 7, "target": "Listing优化完成,广告开始积累数据" },
-          { "day": 14, "target": "广告ACOS降至目标值,有机流量开始提升" },
-          { "day": 21, "target": "转化率提升可见,社媒引流开始起效" },
-          { "day": 30, "target": "全面复盘,确认下一阶段重点" }
+          {
+            "day": 7,
+            "target": "Listing优化完成,广告开始积累数据"
+          },
+          {
+            "day": 14,
+            "target": "广告ACOS降至目标值,有机流量开始提升"
+          },
+          {
+            "day": 21,
+            "target": "转化率提升可见,社媒引流开始起效"
+          },
+          {
+            "day": 30,
+            "target": "全面复盘,确认下一阶段重点"
+          }
         ]
       },
       "output": "actionTimeline"
@@ -144,31 +172,67 @@
         "type": "object",
         "description": "完整提案结构",
         "properties": {
-          "title": { "type": "string" },
-          "date": { "type": "string" },
-          "executiveSummary": { "type": "string" },
+          "title": {
+            "type": "string"
+          },
+          "date": {
+            "type": "string"
+          },
+          "executiveSummary": {
+            "type": "string"
+          },
           "chapters": {
             "type": "array",
             "items": {
               "type": "object",
               "properties": {
-                "title": { "type": "string" },
-                "sections": { "type": "array" },
-                "keyFindings": { "type": "array", "items": { "type": "string" } },
-                "recommendations": { "type": "array", "items": { "type": "string" } }
+                "title": {
+                  "type": "string"
+                },
+                "sections": {
+                  "type": "array"
+                },
+                "keyFindings": {
+                  "type": "array",
+                  "items": {
+                    "type": "string"
+                  }
+                },
+                "recommendations": {
+                  "type": "array",
+                  "items": {
+                    "type": "string"
+                  }
+                }
               }
             }
           },
-          "fullMarkdown": { "type": "string", "description": "完整Markdown文档" }
+          "fullMarkdown": {
+            "type": "string",
+            "description": "完整Markdown文档"
+          }
         }
       },
       "dataReferences": {
         "type": "object",
         "description": "数据引用和完整度",
         "properties": {
-          "completeness": { "type": "number", "description": "0-100数据完整度" },
-          "availableSources": { "type": "array", "items": { "type": "string" } },
-          "missingSources": { "type": "array", "items": { "type": "string" } }
+          "completeness": {
+            "type": "number",
+            "description": "0-100数据完整度"
+          },
+          "availableSources": {
+            "type": "array",
+            "items": {
+              "type": "string"
+            }
+          },
+          "missingSources": {
+            "type": "array",
+            "items": {
+              "type": "string"
+            }
+          }
         }
       },
       "roiEstimation": {
@@ -177,11 +241,26 @@
         "items": {
           "type": "object",
           "properties": {
-            "recommendation": { "type": "string" },
-            "investmentCost": { "type": "string" },
-            "expectedReturn": { "type": "string" },
-            "paybackPeriod": { "type": "string" },
-            "priority": { "type": "string", "enum": ["high", "medium", "low"] }
+            "recommendation": {
+              "type": "string"
+            },
+            "investmentCost": {
+              "type": "string"
+            },
+            "expectedReturn": {
+              "type": "string"
+            },
+            "paybackPeriod": {
+              "type": "string"
+            },
+            "priority": {
+              "type": "string",
+              "enum": [
+                "high",
+                "medium",
+                "low"
+              ]
+            }
           }
         }
       },
@@ -191,10 +270,23 @@
         "items": {
           "type": "object",
           "properties": {
-            "title": { "type": "string" },
-            "level": { "type": "string", "enum": ["high", "medium", "low"] },
-            "description": { "type": "string" },
-            "mitigation": { "type": "string" }
+            "title": {
+              "type": "string"
+            },
+            "level": {
+              "type": "string",
+              "enum": [
+                "high",
+                "medium",
+                "low"
+              ]
+            },
+            "description": {
+              "type": "string"
+            },
+            "mitigation": {
+              "type": "string"
+            }
           }
         }
       },
@@ -207,8 +299,15 @@
             "items": {
               "type": "object",
               "properties": {
-                "week": { "type": "integer" },
-                "tasks": { "type": "array", "items": { "type": "string" } }
+                "week": {
+                  "type": "integer"
+                },
+                "tasks": {
+                  "type": "array",
+                  "items": {
+                    "type": "string"
+                  }
+                }
               }
             }
           },
@@ -217,8 +316,12 @@
             "items": {
               "type": "object",
               "properties": {
-                "day": { "type": "integer" },
-                "target": { "type": "string" }
+                "day": {
+                  "type": "integer"
+                },
+                "target": {
+                  "type": "string"
+                }
               }
             }
           }
@@ -236,46 +339,121 @@
     "type": "bearer",
     "configFile": "~/.openclaw/voc-credentials.json",
     "tokenField": "vocToken",
-    "currentToken": "r:858b3ee92314d5447d1fc3cdc10462d7",
-    "resolutionOrder": ["configFile", "currentToken"],
+    "resolutionOrder": [
+      "configFile"
+    ],
+    "apigId": "7HwdQZk55B",
+    "paymentUrlResolution": {
+      "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
+      "steps": [
+        "1. 从 voc-credentials.json 获取当前 session token",
+        "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
+        "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
+        "4. 将该URL展示给用户,引导扫码支付"
+      ],
+      "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
+      "userResolveHeaders": {
+        "X-Parse-Application-Id": "ncloudmaster",
+        "X-Parse-Session-Token": "{vocToken}"
+      },
+      "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
+      "paymentParams": {
+        "user": "{resolvedUserId}",
+        "apigid": "7HwdQZk55B",
+        "fun_id": "HOkkX72PMF"
+      },
+      "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
+    },
     "onMissing": {
       "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
       "title": "扫码开通 VOC-AI 数据服务",
-      "message": "请扫描下方二维码完成支付,支付成功后将自动获取 Token 并继续执行。"
+      "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
+      "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
+      "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
     },
     "onBalanceInsufficient": {
-      "action": "showPaymentQR",
-      "qrCodeUrl": "https://pwa.fmode.cn/apig-pay.html?user={{user}}&apigid={{apigid}}&fun_id=HOkkX72PMF",
-      "paymentCheckEndpoint": "https://server.fmode.cn/api/apig/getApig",
-      "pollingIntervalMs": 3000,
-      "pollingTimeoutMs": 300000,
-      "onPaymentSuccess": "retrySkillWithNewToken",
+      "action": "resolveUserThenShowPayment",
       "title": "VOC-AI Token 余额不足,请扫码充值",
-      "message": "当前 Token 余额不足,请扫描二维码充值,支付完成后将自动继续执行。"
+      "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
     }
   },
   "errorHandling": {
     "balanceInsufficient": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [-2, -3, -10, 402, 429] },
-        { "responseField": "msg", "operator": "contains", "value": ["余额不足", "insufficient", "balance", "quota"] },
-        { "responseField": "message", "operator": "contains", "value": ["余额不足", "insufficient", "balance"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            -2,
+            -3,
+            -10,
+            402,
+            429
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "message",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "没有开通",
+            "权限或余额"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onBalanceInsufficient"
     },
     "unauthorized": {
       "conditions": [
-        { "responseField": "code", "operator": "in", "value": [401, 403] },
-        { "responseField": "msg", "operator": "contains", "value": ["unauthorized", "token", "invalid", "auth"] }
+        {
+          "responseField": "code",
+          "operator": "in",
+          "value": [
+            401,
+            403
+          ]
+        },
+        {
+          "responseField": "msg",
+          "operator": "contains",
+          "value": [
+            "unauthorized",
+            "token",
+            "invalid",
+            "auth"
+          ]
+        }
       ],
       "matchMode": "any",
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

BIN
dist/social-media.zip


BIN
dist/voc-core.zip


BIN
dist/workshop.zip


+ 258 - 0
docs/voc-forward-403-决策报告.md

@@ -0,0 +1,258 @@
+# VOC Forward 403 权限拒绝 · 决策报告
+
+**时间**: 2026-04-17
+**发现人**: 刚sir(通过 apig-pay 端到端测试)
+**影响**: 所有通过 apig-pay 充值的用户调用 `/api/voc-ecom/forward` 与 `/api/voc-social/forward` 时被返回 403,**付费后仍无法使用接口**
+**建议决策人**: 陈经理
+
+---
+
+## TL;DR
+
+apig-pay 前端按"用户维度"写 `APIGAuth` 记录(只含 `user` 指针),后端 forward 优先按 "company 维度"查(`APIGAuth.company == user.company`),两侧口径不一致 → 查不到记录 → 返回 **403 "没有开通电商API权限或余额不足"**(尽管实际上余额充足)。
+
+**现有真实数据证据**:
+
+| APIGAuth | user | company (记录上) | user.company (用户当前) | count | 实际调用结果 |
+|---|---|---|---|---|---|
+| `czllJEwkCs` (电商) | 2luFP8J1H1 | **缺失** | aOFIC3HGT4 | 1 | **403** |
+| `Rsx6t50Yf3` (社媒) | 2luFP8J1H1 | 1b54XuxGlR(历史) | aOFIC3HGT4 | 4182 | **403** |
+
+余额 1 次和 4182 次都打不通,证明**与余额无关**,纯粹是绑定字段不匹配。
+
+---
+
+## 一、现象
+
+### 复现命令
+
+```bash
+curl -X POST https://server.fmode.cn/api/voc-ecom/forward \
+  -H "Content-Type: application/json" \
+  -H "Authorization: Bearer r:<sessionToken>" \
+  -d '{"path":"/api/KeywordQuery","method":"POST","query":{"domain":1},"body":{"Keyword":"test"}}'
+```
+
+### 实测响应
+
+```json
+{"code":403,"message":"没有开通电商API权限或余额不足"}
+```
+
+### 对照实验(排除"余额不足"嫌疑)
+
+- 同一 token,调用 `/api/voc-social/forward`(余额 **4182 次**)
+- 返回:`{"code":403,"mess":"没有开通社交平台API权限或余额不足"}`
+- **结论**:余额充足也 403,核心问题不在余额。
+
+### 9 种 auth 变体探测
+
+`Authorization: Bearer <session>` 唯一能通过认证层(否则 401)。通过后一律被权限层拦截 → 403。
+
+---
+
+## 二、根因定位
+
+### 后端代码位置
+
+`modules/voc-ecom-api/src/routes.ts`
+
+```ts
+// 行 107-123
+async function getApiAuth(company: any, user?: any): Promise<any | null> {
+  const query = new AuthParse.Query("APIGAuth");
+  if (company) {
+    query.equalTo('company', company);   // ← 只查 company
+  } else {
+    query.equalTo('user', user);         // ← 只查 user
+  }
+  query.equalTo("api", "7HwdQZk55B");
+  return await query.first({ useMasterKey: true });
+}
+
+// 行 225-227
+const companyId = req.body?.company || authData?.company?.id || authData?.user?.company;
+const userId = !companyId ? (authData?.user?.objectId || authData?.user?.id) : undefined;
+//             ^^^^^^^^^^^^^ 只要用户有 company,就永远不会用 user 回退
+```
+
+`modules/voc-social-api/src/routes.ts` 行 55-74、行 217-218 有**完全相同**的逻辑。
+
+### 后端的隐含契约
+
+> "APIGAuth.company 必须等于当前登录用户 user.company 指针目标"
+
+### apig-pay 的实际写入
+
+`apig-pay/src/app/app.ts:343-354` 创建 APIGAuth 时:
+
+```js
+const body = {
+  api: { __type: 'Pointer', className: 'APIG', objectId: apig },
+  user: { __type: 'Pointer', className: '_User', objectId: user },
+  count: 0,
+  used: 0
+};
+// 注意:没有写 company 字段
+```
+
+→ 所有新建 APIGAuth 缺 company,不满足后端契约。
+
+### 另一类不匹配:历史数据 company 错位
+
+用户 `2luFP8J1H1` 的 `user.company = aOFIC3HGT4`(当前归属),但历史 APIGAuth `Rsx6t50Yf3.company = 1b54XuxGlR`(早期公司)。即使 APIGAuth 有 company,如果不等于用户当前 company,后端一样查不到。
+
+---
+
+## 三、三种修复方案对比
+
+| 维度 | **方案 A**:后端 OR 查询 | **方案 B**:apig-pay 前端补 company | **方案 C**:纯数据迁移 |
+|---|---|---|---|
+| 改动位置 | `voc-ecom-api` + `voc-social-api` 各 2 处 | `apig-pay/src/app/app.ts` 1 处 + 存量自愈逻辑 | 一次性脚本 + 数据库 UPDATE |
+| 改动行数 | ~20 行 TS | ~25 行 TS | ~50 行脚本 |
+| 风险面 | **公司核心后端**,影响所有 VOC 计费流程,回归测试面广 | 仅影响 apig-pay,独立前端工程 | 需 MasterKey,误操作影响全用户 |
+| 长效性 | ✅ 一次修复永久生效,未来任何"user-only"记录都能命中 | ⚠️ 只覆盖新记录 + 自己触达的存量(用户需登录 apig-pay 触发自愈) | ⚠️ 只能修历史一批,未来仍需靠前端补或后端改 |
+| 是否需要数据迁移 | ❌ 不需要 | ⚠️ 需要,但可在用户登录时渐进自愈 | ✅ 一次完成 |
+| 对 `Rsx6t50Yf3`(company 错位)能否救回 | ✅ OR 查询直接命中 `user=2luFP8J1H1` | ❌ 无法,除非强制覆盖 company(风险大) | ⚠️ 需人工确认是否合并老公司余额 |
+| 可回滚性 | 改回单条查询即可 | 前端版本回退 | **最难回滚**(数据一旦覆写) |
+| 工作量(人天) | 0.5(含测试) | 0.5 | 0.5(+人工审核数据) |
+| 部署链路 | fmode-server 重启 | apig-pay 构建 + OBS/CDN 刷新 | 一次性执行,无部署 |
+
+### 方案 A(后端 OR 查询)详细补丁
+
+```ts
+// voc-ecom-api/src/routes.ts  &  voc-social-api/src/routes.ts
+async function getApiAuth(company: any, user?: any): Promise<any | null> {
+  if (!company && !user) return null;
+  const queries: any[] = [];
+  if (company) {
+    const q = new AuthParse.Query("APIGAuth");
+    q.equalTo('company', company);
+    q.equalTo("api", ECOM_APIG_ID);  // 或 SOCIAL_APIG_ID
+    queries.push(q);
+  }
+  if (user) {
+    const q = new AuthParse.Query("APIGAuth");
+    q.equalTo('user', user);
+    q.equalTo("api", ECOM_APIG_ID);
+    queries.push(q);
+  }
+  const combined = queries.length === 1
+    ? queries[0]
+    : AuthParse.Query.or(...queries);
+  return await combined.first({ useMasterKey: true });
+}
+
+// 调用处去掉二选一
+const companyId = req.body?.company || authData?.company?.id || authData?.user?.company;
+const userId   = authData?.user?.objectId || authData?.user?.id;  // 总是传
+```
+
+### 方案 B(apig-pay 前端)详细补丁
+
+```js
+// apig-pay/src/app/app.ts  resolveAuthId
+const body = {
+  api:   { __type: 'Pointer', className: 'APIG',    objectId: apig },
+  user:  { __type: 'Pointer', className: '_User',   objectId: user },
+  count: 0, used: 0
+};
+if (this.companyId) {
+  body.company = { __type: 'Pointer', className: 'Company', objectId: this.companyId };
+}
+
+// 同时:读到已有 APIGAuth 但缺 company 时自愈(PUT 补上)
+if (found && !found.company && this.companyId) {
+  await fetch(API_BASE + '/parse/classes/APIGAuth/' + found.objectId, {
+    method: 'PUT',
+    headers: authHeaders,
+    body: JSON.stringify({
+      company: { __type: 'Pointer', className: 'Company', objectId: this.companyId }
+    })
+  });
+}
+```
+
+---
+
+## 四、推荐
+
+**首选:方案 A(后端 OR 查询)**
+
+理由:
+
+1. **语义最正确**。APIGAuth 本身允许 company 为空(Schema 未强约束),查询方却强制二选一,这是后端自身的逻辑漏洞。修后端让两套绑定方式都能命中才是治本。
+
+2. **一处修复,全链路受益**。任何走这套 forward 的前端(apig-pay、skill-executor、未来集成方)无需重复适配。
+
+3. **不需要数据迁移**。存量 2 类问题记录(user-only、company-错位)自动被 OR 查询覆盖到,零风险。
+
+4. **改动局部**。仅 `getApiAuth` + 调用处共 4 处小改动,语义可读性更高,不改变对外行为(成功路径仍走 company 优先)。
+
+**次选:方案 A + B 并行**
+
+若担心后端改动评审周期长,先上 B 让新用户不再踩坑;A 正常排期跟进。二者不冲突。
+
+**不推荐**:纯方案 C。数据迁移一次只能救一批,未来新问题还会发生,治标不治本。
+
+---
+
+## 五、附录
+
+### E2E 证据(已执行)
+
+```
+━━━ BEFORE ━━━
+  APIGAuth czllJEwkCs  count: 1  used: 0
+
+━━━ CALL voc/keyword-search ━━━
+  HTTP: 403   latency: 101ms
+  body: {"code":403,"message":"没有开通电商API权限或余额不足"}
+
+━━━ AFTER (after 2s settle) ━━━
+  APIGAuth czllJEwkCs  count: 1  used: 0
+
+━━━ DELTA ━━━
+  count: 1 → 1  (Δ=0)  ← 扣费没发生,请求被权限层拦下
+```
+
+### 相关代码文件
+
+| 类别 | 路径 |
+|---|---|
+| 后端 ecom 路由 | `E:\workspace\server\future-server\fmode-server\modules\voc-ecom-api\src\routes.ts`(行 107、225) |
+| 后端 social 路由 | `E:\workspace\server\future-server\fmode-server\modules\voc-social-api\src\routes.ts`(行 55、217) |
+| apig-pay 创建逻辑 | `E:\workspace\apig-pay\src\app\app.ts`(行 343-354 `resolveAuthId`) |
+| apig-pay 订单逻辑 | `E:\workspace\apig-pay\src\app\app.ts`(行 482-483 `createOrder` 的 `fcompany` 传参) |
+
+### 本次 Bug 影响的用户范围估算
+
+需 DBA 执行以下查询评估:
+
+```sql
+-- 1. 缺 company 的 APIGAuth 数量(方案 B 需要自愈的记录数)
+SELECT COUNT(*) FROM "APIGAuth" WHERE "_p_company" IS NULL AND "_p_user" IS NOT NULL;
+
+-- 2. company 与 user 所属 company 不一致的记录数(方案 A 才能救回的记录数)
+SELECT a."objectId", a."_p_company", u."_p_company" AS user_company
+FROM "APIGAuth" a
+JOIN "_User" u ON u."objectId" = SUBSTRING(a."_p_user" FROM 7)
+WHERE a."_p_company" IS NOT NULL
+  AND a."_p_company" <> CONCAT('Company$', u."_p_company");
+```
+
+### 本次工作已完成部分
+
+- ✅ 27 个 skill 的 apigId 映射修复(社媒→电商)
+- ✅ apig-pay 多 APIG 切换器 UI 上线
+- ✅ 用户首次登录自动创建 `count=0` APIGAuth 的机制跑通
+- ✅ 支付→回调→`APIGAuth.count+=N` 链路验证通过
+- 🔴 **E2E 扣费闭环被本 Bug 阻塞**
+
+---
+
+## 请陈经理决策
+
+1. 方案 A 后端修改是否批准?批准后由谁排期?
+2. 若暂不动后端,是否先走方案 B 让新用户不再卡壳?
+3. `Rsx6t50Yf3`(4182 次余额,company 历史错位)如何处理——合并到当前公司、作废重发、或保留待迁移?

+ 20 - 4
douyin/douyin-comment-replies/api-config.json

@@ -8,7 +8,7 @@
     "method": "GET",
     "url": "https://server.fmode.cn/api/voc-social/douyin/app/v3/fetch_video_comment_replies",
     "headers": {
-      "Authorization": "Bearer r:a5a19ea9868043b15d9b10423234ca43",
+      "Authorization": "Bearer ${vocToken}",
       "Accept": "application/json"
     }
   },
@@ -165,7 +165,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -174,7 +188,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],
@@ -206,4 +222,4 @@
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 20 - 4
douyin/douyin-general-search/api-config.json

@@ -8,7 +8,7 @@
     "method": "POST",
     "url": "https://server.fmode.cn/api/voc-social/douyin/search/fetch_general_search_v2",
     "headers": {
-      "Authorization": "Bearer r:a5a19ea9868043b15d9b10423234ca43",
+      "Authorization": "Bearer ${vocToken}",
       "Content-Type": "application/json",
       "Accept": "application/json"
     }
@@ -268,7 +268,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -277,7 +291,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],
@@ -309,4 +325,4 @@
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 20 - 4
douyin/douyin-hashtag-search/api-config.json

@@ -8,7 +8,7 @@
     "method": "POST",
     "url": "https://server.fmode.cn/api/voc-social/douyin/search/fetch_challenge_search_v2",
     "headers": {
-      "Authorization": "Bearer r:a5a19ea9868043b15d9b10423234ca43",
+      "Authorization": "Bearer ${vocToken}",
       "Content-Type": "application/json",
       "Accept": "application/json"
     }
@@ -226,7 +226,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -235,7 +249,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],
@@ -267,4 +283,4 @@
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 20 - 4
douyin/douyin-user-profile/api-config.json

@@ -8,7 +8,7 @@
     "method": "GET",
     "url": "https://server.fmode.cn/api/voc-social/douyin/app/v3/handler_user_profile",
     "headers": {
-      "Authorization": "Bearer r:a5a19ea9868043b15d9b10423234ca43",
+      "Authorization": "Bearer ${vocToken}",
       "Accept": "application/json"
     }
   },
@@ -146,7 +146,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -155,7 +169,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],
@@ -187,4 +203,4 @@
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 20 - 4
douyin/douyin-user-search/api-config.json

@@ -8,7 +8,7 @@
     "method": "POST",
     "url": "https://server.fmode.cn/api/voc-social/douyin/search/fetch_user_search_v2",
     "headers": {
-      "Authorization": "Bearer r:a5a19ea9868043b15d9b10423234ca43",
+      "Authorization": "Bearer ${vocToken}",
       "Content-Type": "application/json",
       "Accept": "application/json"
     }
@@ -169,7 +169,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -178,7 +192,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],
@@ -210,4 +226,4 @@
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 20 - 4
douyin/douyin-video-comments/api-config.json

@@ -8,7 +8,7 @@
     "method": "GET",
     "url": "https://server.fmode.cn/api/voc-social/douyin/app/v3/fetch_video_comments",
     "headers": {
-      "Authorization": "Bearer r:a5a19ea9868043b15d9b10423234ca43",
+      "Authorization": "Bearer ${vocToken}",
       "Accept": "application/json"
     }
   },
@@ -174,7 +174,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -183,7 +197,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],
@@ -215,4 +231,4 @@
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 20 - 4
douyin/douyin-video-detail/api-config.json

@@ -8,7 +8,7 @@
     "method": "GET",
     "url": "https://server.fmode.cn/api/voc-social/douyin/app/v3/fetch_one_video_v3",
     "headers": {
-      "Authorization": "Bearer r:a5a19ea9868043b15d9b10423234ca43",
+      "Authorization": "Bearer ${vocToken}",
       "Accept": "application/json"
     }
   },
@@ -147,7 +147,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -156,7 +170,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],
@@ -188,4 +204,4 @@
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 19 - 3
jimeng/jimeng-actor-v2/api-config.json

@@ -145,7 +145,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -154,7 +168,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],
@@ -186,4 +202,4 @@
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 19 - 3
jimeng/jimeng-actor/api-config.json

@@ -135,7 +135,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -144,7 +158,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],
@@ -176,4 +192,4 @@
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 19 - 3
jimeng/jimeng-clothes-v2/api-config.json

@@ -197,7 +197,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -206,7 +220,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],
@@ -238,4 +254,4 @@
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 19 - 3
jimeng/jimeng-img-v4-goods/api-config.json

@@ -163,7 +163,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -172,7 +186,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],
@@ -204,4 +220,4 @@
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 19 - 3
jimeng/jimeng-img-v4-pod/api-config.json

@@ -167,7 +167,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -176,7 +190,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],
@@ -208,4 +224,4 @@
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 19 - 3
jimeng/jimeng-img-v4/api-config.json

@@ -202,7 +202,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -211,7 +225,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],
@@ -243,4 +259,4 @@
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 19 - 3
jimeng/jimeng-img2img-v3/api-config.json

@@ -155,7 +155,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -164,7 +178,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],
@@ -196,4 +212,4 @@
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 19 - 3
jimeng/jimeng-inpaint/api-config.json

@@ -140,7 +140,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -149,7 +163,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],
@@ -181,4 +197,4 @@
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 19 - 3
jimeng/jimeng-oh-detect/api-config.json

@@ -134,7 +134,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -143,7 +157,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],
@@ -175,4 +191,4 @@
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 19 - 3
jimeng/jimeng-oh-generate/api-config.json

@@ -164,7 +164,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -173,7 +187,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],
@@ -205,4 +221,4 @@
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

+ 19 - 3
jimeng/jimeng-oh-identify/api-config.json

@@ -130,7 +130,21 @@
             "余额不足",
             "insufficient",
             "balance",
-            "quota"
+            "quota",
+            "没有开通",
+            "权限或余额"
+          ]
+        },
+        {
+          "responseField": "mess",
+          "operator": "contains",
+          "value": [
+            "余额不足",
+            "insufficient",
+            "balance",
+            "quota",
+            "没有开通",
+            "权限或余额"
           ]
         },
         {
@@ -139,7 +153,9 @@
           "value": [
             "余额不足",
             "insufficient",
-            "balance"
+            "balance",
+            "没有开通",
+            "权限或余额"
           ]
         }
       ],
@@ -171,4 +187,4 @@
       "trigger": "tokenConfig.onMissing"
     }
   }
-}
+}

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików