Score new building permits from Apify for contractor outreach with OpenAI, Slack and Google Sheets
Pulls recently issued building permits from city open-data portals through Apify, keeps only new ones, and scores them by project value, trade keywords, named contractor and freshness. Built for roofers, solar installers, HVAC and electrical trades, suppliers, architects and equipment rental firms that want to reach projects while materials and subcontractors are still being chosen.
How it works Daily schedule / manual run reads every setting from Config. A weekly schedule uses the same Config to send a report instead of running the actor. Starts the Apify actor asynchronously, then waits and polls the run; FAILED, ABORTED, TIMED-OUT or too many polls stop with an error. Downloads the dataset, validates rows and dedupes within the run and across runs (workflow static data, dedupeMemoryDays). A transparent rule score runs first, then an LLM chain with a structured output parser reads each record against your plain-English aiCriteria and returns a fit score, verdict, summary, outreach angle and red flags. Calls are batched with a delay for rate limits, retried, and fall back to the rule score if the model fails. Upserts every row to Google Sheets. Hot rows go to Slack as one approve / dismiss message (send-and-wait, 24 h limit) and the decision is written back to the sheet; warm rows go to an HTML email digest; cold rows stay in the sheet. Weekly report: reads the sheet, summarises the last 7 days (tiers, approvals, top 10) and emails it. A separate Error Trigger branch posts any failure to Slack.
Setup (about 15 minutes) Create an HTTP Header Auth credential: name Authorization, value Bearer (Apify Console > Settings > API & Integrations). Select it on the 3 Apify HTTP nodes. Create a Google Sheet with a tab named in sheetTab and a header row matching the sheet columns (see Upsert to Google Sheets, plus status and reviewedAt). Paste its ID into googleSheetId. Connect OpenAI (or swap the chat model sub-node for Anthropic, Gemini, Ollama...), Slack and Gmail; set slackChannelId and digestEmail in Config (also the channel on Slack: error alert). In Config set actorInput.cities (city codes the actor lists), sinceDays, minValuation, then permitKeywords (permit types you serve) and descriptionKeywords (words in the work description). Write your ideal-lead description in aiCriteria; set aiWeight (0 = rules only, 1 = AI only). Run once manually, check the sheet, then activate.
Customize Edit weights in Score permit leads (valuation up to 35, permit type 20, description 20, contractor 10, freshness 15). Use keywords, permitTypes or maxValuation in actorInput to filter at the source. Permits are public records; contractor names are business names, not private contact data. Swap Gmail/Slack for Teams, Discord, HubSpot, Airtable, etc. Each delivery node only reads $json.
Disclosure: I maintain these Apify actors (account transparent_meteorite). The actor is a paid pay-per-event Apify tool; check its Store page for current pricing before scheduling.
Related Templates
Transform Gmail Newsletters into Insightful LinkedIn Posts Using OpenAI
Who Is This For? This workflow is perfect for content creators, marketers, and business professionals who receive regu...
AI Email Classifier & Auto-Delete for Gmail (SPAM/OFFER Cleaner)
This workflow is designed for freelancers, solopreneurs, and business owners who receive a high volume of irrelevant mes...
Subscribe to new releases of a Github repository via Gmail
This is a very simple workflow that lets you subscribe to any github repository for the latest release (using n8n as ex...
🔒 Please log in to import templates to n8n and favorite templates
Workflow Visualization
Loading...
Preparing workflow renderer
Comments (0)
Login to post comments