api-config.json 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. {
  2. "name": "competitor-discovery",
  3. "displayName": "竞品发现与筛选",
  4. "description": "根据品类关键词和自身品牌信息,自动发现并筛选直接竞品",
  5. "category": "competitor-analysis",
  6. "version": "1.3.0",
  7. "type": "orchestration",
  8. "parameters": {
  9. "categoryKeyword": {
  10. "type": "string",
  11. "required": true,
  12. "description": "品类核心关键词"
  13. },
  14. "ownBrand": {
  15. "type": "string",
  16. "required": true,
  17. "description": "自身品牌名称"
  18. },
  19. "ownAsins": {
  20. "type": "array",
  21. "items": {
  22. "type": "string"
  23. },
  24. "required": false,
  25. "description": "自身品牌核心ASIN列表"
  26. },
  27. "competitorCount": {
  28. "type": "integer",
  29. "required": false,
  30. "default": 5,
  31. "description": "需要筛选的竞品数量"
  32. },
  33. "domain": {
  34. "type": "integer",
  35. "required": false,
  36. "default": 1,
  37. "description": "Amazon站点(1=美国)"
  38. },
  39. "priceRange": {
  40. "type": "object",
  41. "required": false,
  42. "properties": {
  43. "min": {
  44. "type": "number"
  45. },
  46. "max": {
  47. "type": "number"
  48. }
  49. },
  50. "description": "价格带过滤范围,不传则自动按自身价格±30%"
  51. }
  52. },
  53. "pipeline": [
  54. {
  55. "step": 1,
  56. "name": "搜索品类产品",
  57. "api": {
  58. "service": "EcomDataService.searchProductsByQuery",
  59. "endpoint": "/api/ProductQuery",
  60. "method": "POST",
  61. "forwardUrl": "https://server.fmode.cn/api/voc-ecom/forward",
  62. "headers": {
  63. "Authorization": "Bearer {{vocToken}}"
  64. },
  65. "requestBody": {
  66. "Page": 1,
  67. "Query": "1",
  68. "QueryType": "7",
  69. "Pattern": "${categoryKeyword}"
  70. },
  71. "queryParams": {
  72. "domain": "${domain}"
  73. }
  74. },
  75. "output": "searchResults",
  76. "responseExtract": "extractProductList(resp) → Array<{ Asin, Title, Price, Rating, RatingsCount, MonthlySales, Brand, BSR, Photo }>"
  77. },
  78. {
  79. "step": 2,
  80. "name": "查找相似产品",
  81. "condition": "ownAsins.length > 0",
  82. "api": {
  83. "service": "EcomDataService.getSimilarProducts",
  84. "endpoint": "/api/SimilarProductRealtimeRequest",
  85. "method": "POST",
  86. "requestBody": {
  87. "ASIN": "${ownAsins[0]}"
  88. },
  89. "queryParams": {
  90. "domain": "${domain}"
  91. },
  92. "note": "异步任务:需后续调用 /api/SimilarProductRealtimeRequestStatusQuery 和 /api/SimilarProductRealtimeRequestCollection"
  93. },
  94. "output": "similarResults"
  95. },
  96. {
  97. "step": 3,
  98. "name": "关键词排名产品",
  99. "api": {
  100. "service": "EcomDataService.getKeywordProductRanking",
  101. "endpoint": "/api/KeywordProductRanking",
  102. "method": "POST",
  103. "requestBody": {
  104. "keyword": "${categoryKeyword}"
  105. },
  106. "queryParams": {
  107. "domain": "${domain}"
  108. }
  109. },
  110. "output": "rankingResults",
  111. "responseExtract": "Array<{ Asin, Title, Rank, Price, Rating, RatingsCount, IsSponsored }>"
  112. },
  113. {
  114. "step": 4,
  115. "name": "合并去重+竞品评分筛选",
  116. "type": "compute",
  117. "logic": "mergeAndScore(searchResults, similarResults, rankingResults, { ownBrand, priceRange, competitorCount })",
  118. "algorithm": {
  119. "merge": "按ASIN去重合并三个来源的产品",
  120. "exclude": "排除ownBrand的产品",
  121. "filter": "价格在ownPrice±30%范围内 && 评分>=3.5 && 同品类",
  122. "score": "matchScore = priceProximity*0.3 + ratingProximity*0.2 + salesProximity*0.2 + rankInKeyword*0.15 + isSimilar*0.15",
  123. "sort": "按matchScore降序,取top competitorCount个",
  124. "brandGrouping": "按Brand字段分组,统计每个品牌的SKU数和总销量,用于排除自有品牌和识别竞品品牌"
  125. },
  126. "output": "filteredCompetitors"
  127. },
  128. {
  129. "step": 5,
  130. "name": "批量获取竞品详情",
  131. "forEach": "filteredCompetitors",
  132. "api": {
  133. "service": "EcomDataService.getProductDetail",
  134. "endpoint": "/api/ProductRequest",
  135. "method": "POST",
  136. "requestBody": {
  137. "ASIN": "${competitor.asin}",
  138. "Trend": 1,
  139. "QueryTrendStartDt": "",
  140. "QueryTrendEndDt": ""
  141. },
  142. "queryParams": {
  143. "domain": "${domain}"
  144. }
  145. },
  146. "output": "competitorDetails",
  147. "responseExtract": "{ Title, Brand, SalesPrice, Ratings, RatingsCount, BSR, Category, Photo, Feature, Description, VariationASIN, MonthlySales }"
  148. },
  149. {
  150. "step": 6,
  151. "name": "竞争格局分析",
  152. "type": "compute",
  153. "logic": "analyzeCompetitiveLandscape(filteredCompetitors, competitorDetails)",
  154. "algorithm": {
  155. "cr5": {
  156. "method": "按品牌汇总销量 → top5品牌销量占比 = top5Sales/totalSales*100",
  157. "fallback": "品牌数据不足时默认CR5=30(中等)"
  158. },
  159. "monopolyLevel": {
  160. "low": "CR5<30 → '垄断度低,新卖家突围机会充足'",
  161. "medium": "CR5 30-60 → '中等垄断,需差异化策略'",
  162. "high": "CR5>60 → '垄断严重,不建议正面硬刚'"
  163. },
  164. "brandComparison": {
  165. "method": "按Brand分组 → 统计skus/totalSales/totalPrice/totalRating → 取top5品牌",
  166. "output": "Array<{ brand, skus, avgSales, avgPrice, avgRating }>"
  167. },
  168. "differentiationAdvice": {
  169. "highMonopoly": "切入细分人群赛道,避开头部正面竞争",
  170. "lowMonopoly": "新品有充足突围空间",
  171. "always": "打造独家设计款,注册外观专利,构建长期溢价能力"
  172. },
  173. "attackStrategy": "针对TOP竞品的核心差评痛点打造本店独家卖点; 在Listing/主图中做直接对标,抢夺竞品精准用户"
  174. },
  175. "output": "competitiveLandscape"
  176. }
  177. ],
  178. "response": {
  179. "type": "object",
  180. "properties": {
  181. "competitors": {
  182. "type": "array",
  183. "description": "筛选出的直接竞品列表",
  184. "items": {
  185. "type": "object",
  186. "properties": {
  187. "asin": {
  188. "type": "string"
  189. },
  190. "title": {
  191. "type": "string"
  192. },
  193. "brand": {
  194. "type": "string"
  195. },
  196. "price": {
  197. "type": "number"
  198. },
  199. "rating": {
  200. "type": "number"
  201. },
  202. "ratingsCount": {
  203. "type": "integer"
  204. },
  205. "monthlySales": {
  206. "type": "integer"
  207. },
  208. "bsr": {
  209. "type": "integer"
  210. },
  211. "category": {
  212. "type": "string"
  213. },
  214. "matchScore": {
  215. "type": "number"
  216. },
  217. "matchReasons": {
  218. "type": "array",
  219. "items": {
  220. "type": "string"
  221. }
  222. }
  223. }
  224. }
  225. },
  226. "searchMeta": {
  227. "type": "object",
  228. "properties": {
  229. "totalCandidates": {
  230. "type": "integer"
  231. },
  232. "filteredCount": {
  233. "type": "integer"
  234. },
  235. "filterCriteria": {
  236. "type": "object"
  237. }
  238. }
  239. },
  240. "competitiveLandscape": {
  241. "type": "object",
  242. "description": "竞争格局分析(来自computeCompetition算法)",
  243. "properties": {
  244. "cr5": {
  245. "type": "number",
  246. "description": "Top5品牌销量集中度(0-100)"
  247. },
  248. "monopolyLevel": {
  249. "type": "string",
  250. "enum": [
  251. "low",
  252. "medium",
  253. "high"
  254. ]
  255. },
  256. "monopolyLabel": {
  257. "type": "string"
  258. },
  259. "brandComparison": {
  260. "type": "array",
  261. "items": {
  262. "type": "object",
  263. "properties": {
  264. "brand": {
  265. "type": "string"
  266. },
  267. "skus": {
  268. "type": "integer"
  269. },
  270. "avgSales": {
  271. "type": "integer"
  272. },
  273. "avgPrice": {
  274. "type": "number"
  275. },
  276. "avgRating": {
  277. "type": "number"
  278. }
  279. }
  280. }
  281. },
  282. "differentiationAdvice": {
  283. "type": "array",
  284. "items": {
  285. "type": "string"
  286. }
  287. },
  288. "attackStrategy": {
  289. "type": "array",
  290. "items": {
  291. "type": "string"
  292. }
  293. }
  294. }
  295. }
  296. }
  297. },
  298. "timeout": 120000,
  299. "retry": {
  300. "maxAttempts": 2,
  301. "delay": 2000,
  302. "backoffMultiplier": 2
  303. },
  304. "tokenConfig": {
  305. "type": "bearer",
  306. "configFile": "~/.openclaw/voc-credentials.json",
  307. "tokenField": "vocToken",
  308. "resolutionOrder": [
  309. "configFile"
  310. ],
  311. "apigId": "7HwdQZk55B",
  312. "paymentUrlResolution": {
  313. "description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
  314. "steps": [
  315. "1. 从 voc-credentials.json 获取当前 session token",
  316. "2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
  317. "3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
  318. "4. 将该URL展示给用户,引导扫码支付"
  319. ],
  320. "userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
  321. "userResolveHeaders": {
  322. "X-Parse-Application-Id": "ncloudmaster",
  323. "X-Parse-Session-Token": "{vocToken}"
  324. },
  325. "paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
  326. "paymentParams": {
  327. "user": "{resolvedUserId}",
  328. "apigid": "7HwdQZk55B",
  329. "fun_id": "HOkkX72PMF"
  330. },
  331. "balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
  332. },
  333. "onMissing": {
  334. "action": "showPaymentQR",
  335. "qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
  336. "title": "扫码开通 VOC-AI 数据服务",
  337. "message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
  338. "tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
  339. "tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js <session-token> 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
  340. },
  341. "onBalanceInsufficient": {
  342. "action": "resolveUserThenShowPayment",
  343. "title": "VOC-AI Token 余额不足,请扫码充值",
  344. "message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
  345. }
  346. },
  347. "errorHandling": {
  348. "balanceInsufficient": {
  349. "conditions": [
  350. {
  351. "responseField": "code",
  352. "operator": "in",
  353. "value": [
  354. -2,
  355. -3,
  356. -10,
  357. 402,
  358. 429
  359. ]
  360. },
  361. {
  362. "responseField": "msg",
  363. "operator": "contains",
  364. "value": [
  365. "余额不足",
  366. "insufficient",
  367. "balance",
  368. "quota",
  369. "没有开通",
  370. "权限或余额"
  371. ]
  372. },
  373. {
  374. "responseField": "mess",
  375. "operator": "contains",
  376. "value": [
  377. "余额不足",
  378. "insufficient",
  379. "balance",
  380. "quota",
  381. "没有开通",
  382. "权限或余额"
  383. ]
  384. },
  385. {
  386. "responseField": "message",
  387. "operator": "contains",
  388. "value": [
  389. "余额不足",
  390. "insufficient",
  391. "balance",
  392. "没有开通",
  393. "权限或余额"
  394. ]
  395. }
  396. ],
  397. "matchMode": "any",
  398. "trigger": "tokenConfig.onBalanceInsufficient"
  399. },
  400. "unauthorized": {
  401. "conditions": [
  402. {
  403. "responseField": "code",
  404. "operator": "in",
  405. "value": [
  406. 401,
  407. 403
  408. ]
  409. },
  410. {
  411. "responseField": "msg",
  412. "operator": "contains",
  413. "value": [
  414. "unauthorized",
  415. "token",
  416. "invalid",
  417. "auth"
  418. ]
  419. }
  420. ],
  421. "matchMode": "any",
  422. "trigger": "tokenConfig.onMissing"
  423. }
  424. }
  425. }