← 返回 Skills 市场
nicemaths123

Business Opportunity Radar

作者 nicemaths123 · GitHub ↗ · v1.0.0 · MIT-0
cross-platform ⚠ suspicious
54
总下载
0
收藏
0
当前安装
1
版本数
在 OpenClaw 中安装
/install business-opportunity-radar
功能描述
Automates scraping and analyzing app, Amazon, Reddit, and Product Hunt reviews to identify and rank SaaS market gaps with validated business ideas.
使用说明 (SKILL.md)

Hidden Business Opportunity Detector Skill

Overview

This skill builds an automated business intelligence engine that:

  1. Apify scrapes App Store reviews, Amazon reviews, Reddit, niche forums, and Product Hunt
  2. Claude (OpenClaw) deep-analyzes the raw frustrations, recurring requests, and unmet needs
  3. Produces a structured market gap report with validated SaaS ideas, scored by opportunity size

This is how the best indie hackers and founders find their next product — systematically.

🔗 Apify: https://www.apify.com/?fpr=dx06p


What This Skill Does

  • Scrape App Store & Google Play reviews to find what users hate about existing apps
  • Scrape Amazon reviews (1–2 stars) to extract product frustrations at scale
  • Mine Reddit niche communities for recurring complaints and feature requests
  • Crawl niche forums and communities for unmet needs
  • Scrape Product Hunt for emerging tools and gaps in the market
  • Feed all raw data into Claude for structured opportunity analysis
  • Output a ranked list of business opportunities with validation signals
  • Generate SaaS idea briefs with positioning, features, and GTM angle

Architecture Overview

┌─────────────────────────────────────────────────────────────────┐
│           HIDDEN BUSINESS OPPORTUNITY DETECTOR                  │
│                                                                 │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │  LAYER 1 — DATA MINING (Apify)                          │   │
│  │  App Store │ Google Play │ Amazon │ Reddit │ Forums      │   │
│  │  Product Hunt │ G2 │ Trustpilot │ Indie Hackers          │   │
│  └──────────────────────────┬──────────────────────────────┘   │
│                             │                                   │
│  ┌──────────────────────────▼──────────────────────────────┐   │
│  │  LAYER 2 — OPPORTUNITY ANALYSIS ENGINE (Claude)         │   │
│  │                                                         │   │
│  │  • Frustration Extractor  → what people hate/struggle   │   │
│  │  • Pattern Detector       → recurring complaints        │   │
│  │  • Gap Analyzer           → what nobody is building     │   │
│  │  • Opportunity Scorer     → market size x pain level    │   │
│  │  • SaaS Idea Generator    → concrete product briefs     │   │
│  └──────────────────────────┬──────────────────────────────┘   │
│                             │                                   │
│  ┌──────────────────────────▼──────────────────────────────┐   │
│  │  LAYER 3 — OPPORTUNITY REPORT                           │   │
│  │  Ranked ideas │ Validation signals │ GTM angles          │   │
│  │  JSON export │ Markdown report │ Notion / Slack push     │   │
│  └─────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────┘

Step 1 — Get Your API Keys

Apify

  1. Sign up at https://www.apify.com/?fpr=dx06p
  2. Go to Settings → Integrations
  3. Copy your token:
    export APIFY_TOKEN=apify_api_xxxxxxxxxxxxxxxx
    

Claude / OpenClaw

export CLAUDE_API_KEY=sk-ant-xxxxxxxxxxxxxxxx

Step 2 — Install Dependencies

npm install apify-client axios node-cron dotenv fs-extra

Layer 1 — Multi-Source Data Miner (Apify)

Mine App Store & Google Play Reviews

import ApifyClient from 'apify-client';

const apify = new ApifyClient({ token: process.env.APIFY_TOKEN });

// Define the niche and competitor apps to analyze
const TARGET_NICHE = "project management";
const COMPETITOR_APPS = [
  { name: "Notion",   appStoreId: "1232780281", playStoreId: "notion.id" },
  { name: "Asana",    appStoreId: "489969512",  playStoreId: "com.asana.app" },
  { name: "Trello",   appStoreId: "461504587",  playStoreId: "com.trello" },
  { name: "Monday",   appStoreId: "1298450011", playStoreId: "com.monday.monday" }
];

async function scrapeAppReviews() {
  console.log("📱 Scraping App Store & Play Store reviews...");

  const jobs = COMPETITOR_APPS.map(app =>
    Promise.all([

      // App Store — focus on 1-3 star reviews (the gold mine)
      apify.actor("apify/apple-app-store-scraper").call({
        appIds: [app.appStoreId],
        maxReviews: 100,
        filterStars: [1, 2, 3]
      }).then(run => run.dataset().getData())
        .then(d => d.items.map(r => ({
          source: "app_store",
          appName: app.name,
          rating: r.rating,
          review: r.review,
          title: r.title,
          date: r.date,
          country: r.country
        }))),

      // Google Play Store
      apify.actor("apify/google-play-scraper").call({
        appId: app.playStoreId,
        maxReviews: 100,
        filterScore: [1, 2, 3]
      }).then(run => run.dataset().getData())
        .then(d => d.items.map(r => ({
          source: "google_play",
          appName: app.name,
          rating: r.score,
          review: r.text,
          title: r.title || "",
          date: r.date,
          thumbsUp: r.thumbsUp
        })))

    ]).then(results => results.flat())
  );

  const allReviews = await Promise.all(jobs);
  return allReviews.flat();
}

Mine Amazon Reviews (1-3 Stars)

async function scrapeAmazonReviews() {
  console.log("📦 Scraping Amazon negative reviews...");

  // Target products in your niche
  const TARGET_PRODUCTS = [
    "https://www.amazon.com/dp/B08N5WRWNW", // productivity tool example
    "https://www.amazon.com/dp/B09G9HD6PD"
  ];

  const jobs = TARGET_PRODUCTS.map(url =>
    apify.actor("apify/amazon-reviews-scraper").call({
      startUrls: [{ url }],
      maxReviews: 100,
      filterByStar: ["one_star", "two_star", "three_star"]
    }).then(run => run.dataset().getData())
      .then(d => d.items.map(r => ({
        source: "amazon",
        productTitle: r.productTitle,
        rating: r.ratingScore,
        review: r.reviewText,
        title: r.reviewTitle,
        date: r.date,
        helpfulVotes: r.helpfulVotes,
        verifiedPurchase: r.verifiedPurchase
      })))
  );

  const results = await Promise.all(jobs);
  return results.flat();
}

Mine Reddit Niche Communities

async function scrapeRedditFrustrations() {
  console.log("💬 Scraping Reddit communities...");

  const SUBREDDITS = [
    "r/Entrepreneur",
    "r/SaaS",
    "r/smallbusiness",
    "r/productivity",
    "r/projectmanagement",
    "r/startups",
    "r/indiehackers"
  ];

  const [posts, searchResults] = await Promise.all([

    // Hot/top posts in subreddits
    apify.actor("apify/reddit-scraper").call({
      startUrls: SUBREDDITS.map(s => ({ url: `https://www.reddit.com/${s}/` })),
      maxPostCount: 30,
      maxComments: 15,
      sort: "top"
    }).then(run => run.dataset().getData()),

    // Search for frustration signals
    apify.actor("apify/reddit-search-scraper").call({
      queries: [
        `${TARGET_NICHE} frustrated wish`,
        `${TARGET_NICHE} hate problem broken`,
        `${TARGET_NICHE} alternative looking for better`,
        `${TARGET_NICHE} feature request need`,
        `${TARGET_NICHE} why is there no tool`
      ],
      maxItems: 50
    }).then(run => run.dataset().getData())

  ]);

  return [
    ...posts.items.map(p => ({
      source: "reddit_post",
      subreddit: p.subreddit,
      title: p.title,
      text: p.selftext,
      score: p.score,
      comments: p.numComments,
      url: p.url
    })),
    ...searchResults.items.map(p => ({
      source: "reddit_search",
      subreddit: p.subreddit,
      title: p.title,
      text: p.selftext,
      score: p.score,
      url: p.url
    }))
  ];
}

Mine Product Hunt & G2 Reviews

async function scrapeProductIntelligence() {
  console.log("🚀 Scraping Product Hunt & review platforms...");

  const [productHunt, g2] = await Promise.all([

    // Product Hunt — see what's launching and what comments say
    apify.actor("apify/product-hunt-scraper").call({
      mode: "search",
      searchQuery: TARGET_NICHE,
      maxItems: 30
    }).then(run => run.dataset().getData())
      .then(d => d.items.map(p => ({
        source: "product_hunt",
        name: p.name,
        tagline: p.tagline,
        description: p.description,
        upvotes: p.votesCount,
        comments: p.commentsCount,
        topics: p.topics,
        url: p.url
      }))),

    // G2 reviews for competitor software
    apify.actor("apify/website-content-crawler").call({
      startUrls: [
        { url: `https://www.g2.com/categories/${TARGET_NICHE.replace(/\s+/g, '-')}-software` }
      ],
      maxCrawlingDepth: 1,
      maxRequestsPerCrawl: 10
    }).then(run => run.dataset().getData())
      .then(d => d.items.map(p => ({
        source: "g2",
        text: p.text?.slice(0, 2000),
        url: p.url
      })))

  ]);

  return [...productHunt, ...g2];
}

Layer 2 — Opportunity Analysis Engine (Claude)

Frustration Extractor

import axios from 'axios';

const claude = axios.create({
  baseURL: 'https://api.anthropic.com/v1',
  headers: {
    'x-api-key': process.env.CLAUDE_API_KEY,
    'anthropic-version': '2023-06-01',
    'Content-Type': 'application/json'
  }
});

async function extractFrustrations(allData) {
  const prompt = `
You are a world-class product researcher and market analyst.

Analyze this raw data from app reviews, Amazon reviews, Reddit posts, and product listings.
Extract every customer frustration, unmet need, and recurring complaint.

NICHE: ${TARGET_NICHE}

RAW DATA (sample):
${JSON.stringify(allData.slice(0, 30), null, 2)}

Respond ONLY in this JSON format:
{
  "frustrations": [
    {
      "theme": "short label",
      "description": "what users are frustrated about",
      "frequency": "how often this comes up (high/medium/low)",
      "emotionalIntensity": "how angry/upset users are (1-10)",
      "affectedSegment": "who experiences this most",
      "evidenceQuotes": ["direct quote 1", "direct quote 2"],
      "sources": ["app_store", "reddit"]
    }
  ],
  "featureRequests": [
    {
      "request": "what users are explicitly asking for",
      "frequency": "high | medium | low",
      "currentWorkaround": "what users do today instead",
      "evidenceQuotes": ["quote"]
    }
  ],
  "recurringPatterns": [
    "pattern 1 observed across multiple sources",
    "pattern 2"
  ],
  "underservedSegments": [
    {
      "segment": "who is being ignored",
      "unmetNeed": "what they need",
      "currentSolution": "what they use today despite it being bad"
    }
  ]
}
`;

  const { data } = await claude.post('/messages', {
    model: "claude-opus-4-5",
    max_tokens: 3000,
    messages: [{ role: "user", content: prompt }]
  });

  return JSON.parse(data.content[0].text.replace(/```json|```/g, '').trim());
}

Market Gap Analyzer & SaaS Idea Generator

async function analyzeMarketGaps(frustrations, productIntel) {
  const prompt = `
You are a serial entrepreneur and SaaS product strategist.

Based on these validated customer frustrations and market intelligence, identify
the highest-potential business opportunities and generate concrete SaaS ideas.

FRUSTRATIONS & PATTERNS:
${JSON.stringify(frustrations, null, 2)}

MARKET INTELLIGENCE (existing products):
${JSON.stringify(productIntel.slice(0, 10), null, 2)}

Respond ONLY in this JSON format:
{
  "marketGaps": [
    {
      "gap": "what is clearly missing from the market",
      "evidenceStrength": "strong | moderate | weak",
      "estimatedMarketSize": "niche | small | medium | large",
      "competitionLevel": "none | low | medium | high",
      "urgency": "nice-to-have | important | critical"
    }
  ],
  "saasIdeas": [
    {
      "rank": 1,
      "name": "working product name",
      "oneLiner": "X for Y — one sentence pitch",
      "problem": "exact problem it solves",
      "targetCustomer": "specific ICP (ideal customer profile)",
      "coreFeatures": ["feature 1", "feature 2", "feature 3"],
      "differentiator": "why this beats existing solutions",
      "monetization": "pricing model (per seat | usage | freemium | etc)",
      "estimatedMRR": "rough MRR potential at 100 customers",
      "validationSignals": ["signal from data that confirms the need"],
      "gtmAngle": "how to acquire first 100 customers",
      "buildComplexity": "low | medium | high",
      "opportunityScore": 8,
      "risksAndChallenges": ["risk 1", "risk 2"]
    }
  ],
  "quickWins": [
    {
      "idea": "simplest possible version of a solution",
      "timeToMVP": "estimated days/weeks to build",
      "validationMethod": "how to validate before building"
    }
  ],
  "topRecommendation": "single best opportunity with 1-paragraph reasoning"
}
`;

  const { data } = await claude.post('/messages', {
    model: "claude-opus-4-5",
    max_tokens: 4000,
    messages: [{ role: "user", content: prompt }]
  });

  return JSON.parse(data.content[0].text.replace(/```json|```/g, '').trim());
}

Validation Signal Scorer

async function scoreOpportunities(ideas, rawData) {
  const prompt = `
Score each SaaS idea based on the evidence in the raw data.
Apply the Rob Walling (TinySeed) and Paul Graham opportunity frameworks.

IDEAS TO SCORE:
${JSON.stringify(ideas.saasIdeas, null, 2)}

RAW DATA SIGNALS:
- Total reviews analyzed: ${rawData.length}
- Sources: ${[...new Set(rawData.map(r => r.source))].join(', ')}
- Top frustration themes: ${JSON.stringify(ideas.marketGaps?.slice(0, 5))}

Respond ONLY in this JSON format:
{
  "scoredIdeas": [
    {
      "rank": 1,
      "name": "product name",
      "scores": {
        "painLevel":       { "score": 9, "reasoning": "why" },
        "marketSize":      { "score": 7, "reasoning": "why" },
        "competition":     { "score": 8, "reasoning": "why" },
        "buildability":    { "score": 6, "reasoning": "why" },
        "monetization":    { "score": 8, "reasoning": "why" },
        "founderFit":      { "score": 7, "reasoning": "why" }
      },
      "overallScore": 7.5,
      "verdict": "🔥 Build this | ✅ Worth exploring | ⚠️ Risky | ❌ Skip",
      "nextStep": "concrete first action to validate this idea"
    }
  ],
  "winnerIdea": "name of the single best opportunity",
  "executiveSummary": "2-3 sentence summary of the full analysis"
}
`;

  const { data } = await claude.post('/messages', {
    model: "claude-opus-4-5",
    max_tokens: 2500,
    messages: [{ role: "user", content: prompt }]
  });

  return JSON.parse(data.content[0].text.replace(/```json|```/g, '').trim());
}

Layer 3 — Opportunity Report Generator

import { writeFileSync } from 'fs';

function generateMarkdownReport(frustrations, gaps, scored, rawDataCount) {
  const top = scored.scoredIdeas.slice(0, 3);
  const date = new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' });

  return `# 🎯 Business Opportunity Report
**Niche:** ${TARGET_NICHE} | **Date:** ${date} | **Data Points Analyzed:** ${rawDataCount}

---

## Executive Summary
${scored.executiveSummary}

**🏆 Winner Idea: ${scored.winnerIdea}**

---

## Top Market Gaps Identified

${gaps.marketGaps?.slice(0, 5).map((g, i) =>
  `### ${i + 1}. ${g.gap}
- **Evidence:** ${g.evidenceStrength} | **Market:** ${g.estimatedMarketSize} | **Competition:** ${g.competitionLevel}
- **Urgency:** ${g.urgency}`
).join('\
\
')}

---

## Top 3 SaaS Opportunities

${top.map(idea => `### ${idea.rank}. ${idea.name} — Score: ${idea.overallScore}/10 ${idea.verdict}

${gaps.saasIdeas?.find(i => i.name === idea.name)?.oneLiner || ""}

| Dimension | Score | Notes |
|---|---|---|
| Pain Level | ${idea.scores.painLevel.score}/10 | ${idea.scores.painLevel.reasoning} |
| Market Size | ${idea.scores.marketSize.score}/10 | ${idea.scores.marketSize.reasoning} |
| Competition | ${idea.scores.competition.score}/10 | ${idea.scores.competition.reasoning} |
| Buildability | ${idea.scores.buildability.score}/10 | ${idea.scores.buildability.reasoning} |
| Monetization | ${idea.scores.monetization.score}/10 | ${idea.scores.monetization.reasoning} |

**Next Step:** ${idea.nextStep}`
).join('\
\
---\
\
')}

---

## Top Customer Frustrations

${frustrations.frustrations?.slice(0, 8).map((f, i) =>
  `**${i + 1}. ${f.theme}** (Intensity: ${f.emotionalIntensity}/10 | Frequency: ${f.frequency})
> "${f.evidenceQuotes?.[0] || 'No quote available'}"
${f.description}`
).join('\
\
')}

---

## Quick Wins (Ship in Days)

${gaps.quickWins?.map(q =>
  `- **${q.idea}** | Time to MVP: ${q.timeToMVP} | Validate by: ${q.validationMethod}`
).join('\
')}

---
*Generated by Hidden Business Opportunity Detector • Powered by Apify + Claude*
`;
}

Master Orchestrator — Full Pipeline

async function runOpportunityDetector(niche = TARGET_NICHE) {
  console.log(`\
🎯 Opportunity Detector started — ${niche}`);
  console.log(`Timestamp: ${new Date().toISOString()}\
`);

  try {
    // STEP 1 — Mine all data sources in parallel
    console.log("[1/5] Mining data sources...");
    const [appReviews, amazonReviews, redditData, productIntel] = await Promise.all([
      scrapeAppReviews(),
      scrapeAmazonReviews(),
      scrapeRedditFrustrations(),
      scrapeProductIntelligence()
    ]);

    const allData = [...appReviews, ...amazonReviews, ...redditData, ...productIntel];
    console.log(`  ✅ ${allData.length} data points collected`);
    console.log(`     App reviews: ${appReviews.length} | Amazon: ${amazonReviews.length}`);
    console.log(`     Reddit: ${redditData.length} | Product intel: ${productIntel.length}`);

    // STEP 2 — Extract frustrations
    console.log("\
[2/5] Extracting frustrations with Claude...");
    const frustrations = await extractFrustrations(allData);
    console.log(`  ✅ ${frustrations.frustrations?.length} frustration themes identified`);
    console.log(`  ✅ ${frustrations.featureRequests?.length} feature requests found`);

    // STEP 3 — Analyze market gaps and generate SaaS ideas
    console.log("\
[3/5] Analyzing market gaps...");
    const gaps = await analyzeMarketGaps(frustrations, productIntel);
    console.log(`  ✅ ${gaps.marketGaps?.length} gaps identified`);
    console.log(`  ✅ ${gaps.saasIdeas?.length} SaaS ideas generated`);

    // STEP 4 — Score all opportunities
    console.log("\
[4/5] Scoring opportunities...");
    const scored = await scoreOpportunities(gaps, allData);
    console.log(`  ✅ Ideas scored | Winner: ${scored.winnerIdea}`);

    // STEP 5 — Generate report
    console.log("\
[5/5] Generating report...");
    const report = generateMarkdownReport(frustrations, gaps, scored, allData.length);
    writeFileSync(`./opportunity-report-${Date.now()}.md`, report);

    const outputJSON = {
      niche,
      analyzedAt: new Date().toISOString(),
      dataPoints: allData.length,
      frustrationThemes: frustrations.frustrations?.length,
      marketGaps: gaps.marketGaps,
      saasIdeas: scored.scoredIdeas,
      winnerIdea: scored.winnerIdea,
      quickWins: gaps.quickWins,
      executiveSummary: scored.executiveSummary
    };

    writeFileSync(`./opportunity-data-${Date.now()}.json`, JSON.stringify(outputJSON, null, 2));
    console.log("\
✅ Reports saved to disk");

    // Optional: push to Slack
    if (process.env.SLACK_WEBHOOK_URL) {
      await axios.post(process.env.SLACK_WEBHOOK_URL, {
        text: `🎯 *Opportunity Report Ready — ${niche}*\
` +
              `📊 ${allData.length} data points analyzed\
` +
              `🏆 Top idea: *${scored.winnerIdea}*\
` +
              `💬 ${scored.executiveSummary}`
      });
    }

    return outputJSON;

  } catch (err) {
    console.error("Pipeline error:", err.message);
    throw err;
  }
}

// Run immediately
runOpportunityDetector("project management tools");

Environment Variables

# .env
APIFY_TOKEN=apify_api_xxxxxxxxxxxxxxxx
CLAUDE_API_KEY=sk-ant-xxxxxxxxxxxxxxxx

# Optional notifications
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/xxx/xxx/xxx
NOTION_API_KEY=secret_xxxxxxxxxxxxxxxx

Normalized Opportunity Output Schema

{
  "niche": "project management",
  "analyzedAt": "2025-02-25T10:00:00Z",
  "dataPoints": 380,
  "winnerIdea": "AutoStandup",
  "saasIdeas": [
    {
      "rank": 1,
      "name": "AutoStandup",
      "oneLiner": "Async standups that actually get filled out",
      "overallScore": 8.5,
      "verdict": "🔥 Build this",
      "targetCustomer": "Remote engineering teams 5-50 people",
      "estimatedMRR": "$12,000 at 100 customers ($120/mo per team)",
      "timeToMVP": "3 weeks",
      "nextStep": "Post in r/remotework and r/SaaS — ask if this is a real problem",
      "validationSignals": [
        "47 Reddit posts complaining about standups being ignored",
        "3-star Slack reviews: 'nobody fills them out'"
      ]
    }
  ],
  "quickWins": [
    {
      "idea": "Notion template for async standups",
      "timeToMVP": "2 days",
      "validationMethod": "Post on Gumroad, see if anyone pays $9"
    }
  ]
}

Best Practices

  • Focus on 1–3 star reviews — that's where the real pain lives
  • Scrape at least 200+ reviews per competitor for statistically significant patterns
  • Always include a "why is there no tool for X" Reddit search — goldmine for gaps
  • Cross-validate: an idea is strong only if the same frustration appears in 3+ sources
  • The Quick Wins section is perfect for validation before building — ship a landing page first
  • Re-run the pipeline on a new niche weekly to build a pipeline of ideas
  • Track which ideas get the most Slack/Notion engagement from your team

Error Handling

try {
  const data = await scrapeAppReviews();
  return data;
} catch (error) {
  if (error.statusCode === 401) throw new Error("Invalid Apify token");
  if (error.statusCode === 429) throw new Error("Rate limit — reduce concurrent scrapers");
  if (error.message.includes("actor")) throw new Error("Actor not found — verify actor ID");
  throw error;
}

Requirements

  • Apify account → https://www.apify.com/?fpr=dx06p
  • Claude / OpenClaw API key
  • Node.js 18+ with apify-client, axios, node-cron, fs-extra
  • Optional: Slack, Notion, or Airtable for team collaboration on the output
安全使用建议
Before installing or running this skill, consider the following: - The SKILL.md requires APIFY_TOKEN and CLAUDE_API_KEY but the registry metadata does not declare them—ask the publisher to declare required env vars in the registry so you know what you'll be exposing. - This skill scrapes many sites and sends collected text to a third‑party LLM (Claude). Do not feed PII, credentials, or private customer data into it. Verify what data will be sent to the LLM and where results are stored. - The README references pushing results to Notion/Slack but gives no instructions for supplying those credentials; confirm what integrations are used and whether additional tokens are required. If so, prefer to create least-privilege tokens for those destinations. - Confirm the exact Apify actors and owners the skill will call (the SKILL.md uses apify actors like 'apify/apple-app-store-scraper'). Review those actors' owners and privacy policies before running them under your APIFY_TOKEN. - Check legal/ToS implications of scraping each target (Amazon, App Stores, Reddit, Product Hunt, forums). Consider rate limits and blocking risks; run initial tests in an isolated environment. - Because the skill's source/homepage is unknown, prefer only running it in a sandbox or with non-sensitive test data until the author and code provenance are verified. - If you plan to install npm packages as instructed, review the packages and consider installing them in a controlled environment (container or VM). If you need help vetting the publisher, listing the exact Apify actors used, or rewriting the skill to require credentials explicitly in the registry manifest, I can help with next steps.
功能分析
Type: OpenClaw Skill Name: business-opportunity-radar Version: 1.0.0 The 'business-opportunity-radar' skill is a legitimate market research tool designed to scrape public reviews (App Store, Amazon, Reddit) via Apify and analyze them using the Claude API. The code in SKILL.md implements a standard data processing pipeline (collection, LLM analysis, and reporting) and uses well-known libraries like axios and apify-client. No indicators of data exfiltration, malicious execution, or harmful prompt injection were found; the inclusion of an Apify affiliate link is a common promotional practice and does not pose a security risk.
能力标签
requires-sensitive-credentials
能力评估
Purpose & Capability
The skill's stated purpose (scrape reviews and analyze them with an LLM) matches the SKILL.md code and architecture. However, the registry metadata declares no required environment variables or credentials while the SKILL.md explicitly instructs users to set APIFY_TOKEN and CLAUDE_API_KEY. The README also lists Notion/Slack outputs but does not declare credentials for those destinations. The skill's source/homepage is 'unknown', which reduces provenance and trust.
Instruction Scope
The instructions explicitly direct broad web scraping (App Store, Play Store, Amazon, Reddit, forums, Product Hunt, G2, Trustpilot, Indie Hackers) and then send aggregated content to a third‑party LLM (Claude/OpenClaw). They mention outputs pushed to Notion/Slack but do not show how credentials or endpoints are supplied. Scraping and forwarding user content to external LLMs and unknown destinations increases data-exposure risk and may violate site terms—this scope is wider than what the registry metadata declares.
Install Mechanism
This is an instruction-only skill (no install spec), which is lower platform risk, but SKILL.md tells users to run 'npm install apify-client axios node-cron dotenv fs-extra'. The mismatch (no install spec in registry) means the agent/operator must execute installs themselves; packages requested are reasonable for the task and no arbitrary binary downloads are referenced.
Credentials
Registry metadata lists no required env vars, but SKILL.md requires APIFY_TOKEN and CLAUDE_API_KEY. It also references pushing results to Notion/Slack without declaring or documenting required Notion/Slack tokens. Requesting API keys for Apify and a Claude/OpenClaw key is proportional to the described functionality, but the metadata omission and undisclosed additional outputs (Notion/Slack) are inconsistent and risky.
Persistence & Privilege
The skill is not marked 'always: true' and defaults allow model invocation (normal). Autonomous invocation combined with the need for third‑party credentials (Apify, Claude) increases the potential blast radius if the skill is later invoked without oversight, but the skill does not request system-level persistence or access to other skills' configurations in the provided content.
如何使用
  1. 确保已安装 OpenClaw(本地或 Docker 部署)
  2. 在对话框中输入安装命令:/install business-opportunity-radar
  3. 安装完成后,直接呼叫该 Skill 的名称或使用 /business-opportunity-radar 触发
  4. 根据 Skill 的参数说明提供必要输入,即可获得结构化输出
版本历史
v1.0.0
Business Opportunity Radar Skill 1.0.0 - Automates discovery of hidden SaaS opportunities by mining user frustrations and unmet needs across the App Store, Google Play, Amazon, Reddit, Product Hunt, and niche forums. - Integrates Apify for large-scale data scraping and Claude for deep analysis and opportunity scoring. - Produces structured, ranked market gap reports including validation signals and actionable SaaS idea briefs with suggested positioning and go-to-market angles. - Output options include JSON exports, Markdown reports, and Notion/Slack integration for easy sharing. - Designed for indie hackers and founders to systematize the search for their next product idea.
元数据
Slug business-opportunity-radar
版本 1.0.0
许可证 MIT-0
累计安装 0
当前安装数 0
历史版本数 1
常见问题

Business Opportunity Radar 是什么?

Automates scraping and analyzing app, Amazon, Reddit, and Product Hunt reviews to identify and rank SaaS market gaps with validated business ideas. 它是一个面向 Claude Code / OpenClaw 的 AI Agent Skill 插件,目前累计下载 54 次。

如何安装 Business Opportunity Radar?

在 OpenClaw 或 Claude Code 对话框中运行命令「/install business-opportunity-radar」即可一键安装,无需额外配置。

Business Opportunity Radar 是免费的吗?

是的,Business Opportunity Radar 完全免费,采用 MIT-0 许可证,可自由下载、安装和使用。

Business Opportunity Radar 支持哪些平台?

Business Opportunity Radar 跨平台运行,可在任意部署了 OpenClaw / Claude Code 的环境中使用(cross-platform)。

谁开发了 Business Opportunity Radar?

由 nicemaths123(@nicemaths123)开发并维护,当前版本 v1.0.0。

💬 留言讨论