{ "name": "review-batch-collection", "displayName": "评论批量采集", "description": "对多个ASIN批量采集Amazon评论,支持翻页和星级过滤,输出结构化评论语料库", "category": "review-analysis", "version": "1.3.0", "type": "orchestration", "parameters": { "asins": { "type": "array", "items": { "type": "string" }, "required": true, "description": "ASIN列表" }, "maxPagesPerAsin": { "type": "integer", "required": false, "default": 5, "description": "每个ASIN最大翻页数" }, "starFilter": { "type": "array", "items": { "type": "integer", "enum": [ 1, 2, 3, 4, 5 ] }, "required": false, "description": "星级过滤,不传则全部" }, "onlyVerifiedPurchase": { "type": "boolean", "required": false, "default": false, "description": "只采集已验证购买" }, "domain": { "type": "integer", "required": false, "default": 1, "description": "Amazon站点" } }, "pipeline": [ { "step": 1, "name": "批量ASIN×多页评论采集", "forEach": "asins × [1..maxPagesPerAsin] × (starFilter || [null])", "api": { "service": "SorftimeApiService.getProductReviews", "endpoint": "/api/ProductReviewsQuery", "method": "POST", "forwardUrl": "https://server.fmode.cn/api/voc-ecom/forward", "headers": { "Authorization": "Bearer {{vocToken}}" }, "requestBody": { "ASIN": "${asin}", "Star": "${star || ''}", "PageIndex": "${pageIndex}", "OnlyPurchase": "${onlyVerifiedPurchase ? 1 : 0}", "QueryStartDt": "" }, "queryParams": { "domain": "${domain}" }, "rateLimit": "400ms between requests per ASIN" }, "output": "rawReviews", "responseFields": { "note": "Sorftime返回的评论字段为PascalCase", "Star": "integer, 1-5", "Title": "string, 评论标题", "Content": "string, 评论正文", "ConsumerName": "string", "ConsumerURL": "string, 用户主页链接", "ReviewsDate": "string, 格式'20260204'", "ReviewedCountry": "string, 如'United States'", "IsVP": "boolean, 已验证购买", "Helpful": "integer", "ReviewsLink": "string, 评论链接", "Asin": "string", "AsinProperty": "string, 变体属性", "Resource": "array, 图片", "Videos": "array" }, "pagination": "多页采集时每页请求间隔400ms避免限流,PageIndex从1开始递增直到无更多数据" }, { "step": 2, "name": "去重+清洗", "type": "compute", "logic": "deduplicateAndClean(rawReviews)", "algorithm": { "deduplicate": "按ReviewsLink去重", "clean": "过滤Content长度<10的无效短评论", "normalize": "统一字段名为cabmelCase: Star→star, Content→content, ReviewsDate→reviewDate" }, "output": "cleanedReviews" }, { "step": 3, "name": "统计汇总", "type": "compute", "logic": "computeStats(cleanedReviews)", "algorithm": { "perAsin": "{ total, avgRating, positiveRate(4-5★%), negativeRate(1-2★%), neutralRate(3★%) }", "overall": "{ totalReviews, asinsCollected, avgStarDistribution }", "starDistribution": "统计各星级评论数: groupBy(star) → {1:n,2:n,3:n,4:n,5:n}" }, "output": "stats" }, { "step": 4, "name": "竞品VOC对比汇总", "type": "compute", "logic": "computeCompetitorVocComparison(cleanedReviews, asins, { ownAsins })", "algorithm": { "grouping": "将ASIN分为本店(ownAsins)和竞品两组", "perGroup": { "count": "产品数", "avgRating": "加权平均评分 = sum(rating*ratingsCount)/sum(ratingsCount)", "totalReviews": "总评论数", "negativeRate": "差评率 = avg(1★%+2★%) per product", "topProducts": "按ratingsCount降序取top5产品: { asin, title(40字), rating, ratingsCount, negativeRate }" }, "starPctFields": "星级百分比字段: oneStartRatings/twoStartRatings/threeStartRatings/fourStartRatings/fiveStartRatings", "ratingCalc": "rawRating>0用rawRating; 否则starSum>0时(1*one+2*two+3*three+4*four+5*five)/starSum" }, "output": "vocComparison" } ], "response": { "type": "object", "properties": { "reviews": { "type": "array", "description": "清洗后的评论列表", "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" } } } }, "stats": { "type": "object", "description": "采集统计概况", "properties": { "totalReviews": { "type": "integer" }, "asinsCollected": { "type": "integer" }, "avgRating": { "type": "number" }, "positiveRate": { "type": "number" }, "negativeRate": { "type": "number" }, "perAsinStats": { "type": "object" } } }, "vocComparison": { "type": "object", "description": "本店vs竞品VOC对比", "properties": { "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" } } } } } }, "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" } } } } } } } } } }, "timeout": 300000, "retry": { "maxAttempts": 3, "delay": 2000, "backoffMultiplier": 2 }, "tokenConfig": { "type": "bearer", "configFile": "~/.openclaw/voc-credentials.json", "tokenField": "vocToken", "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://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 写入 ~/.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 写入 ~/.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" } } }