Requirements
- Target platform
- OpenClaw
- Install method
- Manual import
- Extraction
- Extract archive
- Prerequisites
- OpenClaw
- Primary doc
- SKILL.md
Automatically discover, qualify, and export high-quality business leads by niche and location with AI-generated personalized outreach messages.
Automatically discover, qualify, and export high-quality business leads by niche and location with AI-generated personalized outreach messages.
Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.
I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete.
I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run.
Version: 1.0.0 Author: @g4dr Source: https://github.com/g4dr/openclaw-skills License: MIT
This skill helps Claude discover, qualify, and structure publicly available B2B business contact data and generate personalized outreach messages โ for legitimate sales prospecting, partnership discovery, and market research. All data collection is scoped to publicly listed business information only. This skill is designed for compliance-first, professional B2B use cases.
This section is mandatory reading. Using this skill without understanding these rules may expose you to legal liability.
GDPR (EU/UK): You must have a legitimate interest or consent to contact EU/UK residents. Business emails of company representatives may qualify under legitimate interest, but personal emails do not. Always include an opt-out mechanism. CCPA (California): California residents have the right to opt out of data sale. Do not sell scraped contact lists. Include unsubscribe links in outreach. CAN-SPAM (US): Commercial emails must include sender identity, physical address, and a working unsubscribe link. Honor opt-out requests within 10 business days. CASL (Canada): Requires express or implied consent before sending commercial messages.
Always review the robots.txt of any website before scraping (e.g., https://example.com/robots.txt) LinkedIn prohibits automated scraping in its ToS โ only scrape public company pages and comply with any cease-and-desist or rate-limiting responses Apify's platform requires users to comply with target websites' ToS
Never scrape personal profiles, private accounts, or login-gated content Respect Crawl-delay and Disallow directives in robots.txt Limit request rates to avoid overloading target servers Only collect data that is genuinely publicly listed for business contact purposes Delete data you no longer need โ do not hoard contact databases indefinitely
Always personalize โ mass cold email blasts are ineffective and damage sender reputation Include your real name, company name, and physical address in every email Provide a clear, one-click unsubscribe link Never use misleading subject lines or deceptive sender names Maintain a suppression list of opt-outs and never contact them again Disclaimer: This skill provides technical guidance only. It is not legal advice. Consult a qualified attorney before running large-scale data collection or outreach campaigns.
Discover publicly listed business contacts from Yellow Pages, Google Maps, and LinkedIn company pages Qualify leads by industry, location, company size, and job title Deduplicate and normalize contacts into a CRM-ready schema Generate personalized outreach messages using Claude AI Export clean CSV or JSON files ready for your CRM or email tool
Apify is a cloud web scraping platform. Sign up at https://apify.com to get started. Create a free account at https://apify.com Navigate to Settings โ Integrations Direct link: https://console.apify.com/account/integrations Copy your Personal API Token: apify_api_xxxxxxxxxxxxxxxx Store it securely โ never paste it into a chat or commit it to a public repo: export APIFY_TOKEN=apify_api_xxxxxxxxxxxxxxxx โ ๏ธ Keep your API token private. Do not share it in conversations with Claude or anyone else. Free tier includes $5/month of compute โ sufficient for targeted, small-scale prospecting.
npm install apify-client
Only use actors that target publicly listed business directories: Actor IDSourceData Availableapify/yellowpages-scraperYellow PagesBusiness name, phone, address, categoryapify/google-maps-scraperGoogle MapsBusiness name, phone, website, categoryapify/yelp-scraperYelpBusiness listings, contact infoapify/linkedin-companies-scraperLinkedIn (public pages only)Company info, website, industry
import ApifyClient from 'apify-client'; const client = new ApifyClient({ token: process.env.APIFY_TOKEN }); // Before running โ check robots.txt: // https://www.yellowpages.com/robots.txt const run = await client.actor("apify/yellowpages-scraper").call({ searchTerms: ["digital marketing agency"], locations: ["New York, NY"], maxResultsPerPage: 25 // keep batches small and targeted }); const { items } = await run.dataset().getData(); // Filter out any results missing key business contact info const qualified = items.filter(b => b.businessName && (b.phone || b.website)); console.log(`${qualified.length} qualified leads found`);
// Before running โ check: // https://www.google.com/robots.txt // Google Maps ToS: https://cloud.google.com/maps-platform/terms const run = await client.actor("apify/google-maps-scraper").call({ searchStringsArray: ["accountants Austin TX"], maxCrawledPlacesPerSearch: 25, language: "en" }); const { items } = await run.dataset().getData(); // Each item contains: // { title, address, phone, website, rating, category, email }
import { writeFileSync } from 'fs'; async function runLeadPipeline(searchTerm, location, maxLeads = 25) { // STEP 1 โ Discover const run = await client.actor("apify/yellowpages-scraper").call({ searchTerms: [searchTerm], locations: [location], maxResultsPerPage: maxLeads }); const { items } = await run.dataset().getData(); // STEP 2 โ Qualify and normalize const leads = items .filter(b => b.businessName && (b.phone || b.website)) .map(b => ({ companyName: b.businessName, industry: b.category || searchTerm, phone: b.phone || "", website: b.website || "", address: `${b.street || ""}, ${b.city || ""}, ${b.state || ""}`.trim(), source: "yellowpages", collectedAt: new Date().toISOString(), outreachSent: false })); // STEP 3 โ Deduplicate by website domain const seen = new Set(); const unique = leads.filter(l => { const domain = l.website?.replace(/https?:\/\/(www\.)?/, '').split('/')[0]; if (!domain || seen.has(domain)) return false; seen.add(domain); return true; }); // STEP 4 โ Generate outreach for top 5 (keep batches human-reviewable) for (const lead of unique.slice(0, 5)) { lead.suggestedEmail = await generateOutreach(lead); await new Promise(r => setTimeout(r, 500)); // rate limit Claude calls } // STEP 5 โ Export to CSV const headers = ["companyName","industry","phone","website","address","source","suggestedEmail"]; const csv = [ headers.join(","), ...unique.map(l => headers.map(h => `"${(l[h] || "").replace(/"/g, '""')}"`).join(",")) ].join("\n"); const filename = `leads-${searchTerm.replace(/\s+/g, '_')}-${Date.now()}.csv`; writeFileSync(filename, csv); console.log(`โ ${unique.length} leads exported to ${filename}`); return unique; } // Example usage await runLeadPipeline("IT consulting firms", "Chicago, IL", 25);
{ "companyName": "Bright Digital Agency", "industry": "Marketing & Advertising", "phone": "+1 (415) 555-0192", "website": "https://brightdigital.com", "address": "123 Market St, San Francisco, CA 94105", "source": "yellowpages", "collectedAt": "2025-02-25T10:00:00Z", "outreachSent": false, "gdprBasis": "legitimate_interest", "optedOut": false }
Before executing any lead scraping or outreach campaign, verify: Reviewed robots.txt of every target website Confirmed the target data is publicly listed business information Identified your legal basis for processing (legitimate interest / consent) Outreach emails include sender identity and physical address Outreach emails include a working unsubscribe link Suppression list is in place for previous opt-outs Data will be deleted when no longer needed For EU/UK contacts: legitimate interest assessment completed
Small, targeted batches (25โ50 leads) outperform mass scraping every time Always validate emails before sending (use Hunter.io or NeverBounce) Review outreach drafts before sending โ never auto-send without human review Log every contact in your CRM and mark outreach dates Warm up new email domains before sending at scale (use tools like Instantly or Lemlist) Target decision makers by title โ not just any email at a company
try { const run = await client.actor("apify/yellowpages-scraper").call(input); const dataset = await run.dataset().getData(); return dataset.items; } catch (error) { if (error.statusCode === 401) throw new Error("Invalid Apify token โ check credentials"); if (error.statusCode === 429) throw new Error("Rate limit โ reduce batch size"); if (error.statusCode === 404) throw new Error("Actor not found โ verify actor ID"); throw error; }
Apify account at https://apify.com Claude / OpenClaw API key for outreach generation Node.js 18+ with apify-client and axios A CRM or spreadsheet tool to manage your lead list (HubSpot, Airtable, CSV) An outreach tool with built-in unsubscribe management (Instantly, Lemlist, Apollo)
Code helpers, APIs, CLIs, browser automation, testing, and developer operations.
Largest current source with strong distribution and engagement signals.