sisu · project 07/11
Sisu.
Finds local businesses with broken websites and drafts the pitch.
Illustrative leads — the shape of what Sisu finds.
Quick fix for brightsmile-dental.com
Draft · to hello@brightsmile… · from you
Hi Dr. Rao,
Chrome shows a “Not secure” warning on brightsmile-dental.com — patients see it before they see your clinic. It’s a quick fix, and I can also add online booking while I’m in there.
Worth a 10-minute call this week?
— reply STOP to opt out · [postal address]
How a lead lands in your inbox
Finding small businesses that genuinely need web work — and writing outreach specific enough to get a reply — is slow manual work.
Google Places plus OpenStreetMap with mirror failover; chains are skipped and known businesses excluded up front.
A shared Chromium visits four sites at a time and extracts emails, phone and socials — including Cloudflare-obfuscated emails.
Weighted site issues add up to a lead score; dead, healthy or unreachable businesses are disqualified.
MX records are checked so drafts never go to dead domains.
The email opens with the one issue the owner can verify in ten seconds, with opt-out and address built in.
Audit rules
from extractor.py- Page shows PHP / WordPress error messages redesign+45
- No mobile viewport redesign+35
- Plain http:// (no SSL) redesign+30
- Copyright footer 3+ years old redesign+25
- No way to book online booking+20
- Contact form but no booking booking+15
- Slow load (> 5 s) +10
- Missing meta description / thin text +5
- No OpenGraph tags +2
Below 20 a site is disqualified and never shown — so is anything dead or unreachable.
Nine weighted checks — from PHP errors and missing SSL to a stale © footer.
Targeted city + niche, random, or a rotation that remembers its position.
Random pacing, rate-limited geocoding and a daily lead cap.
Start, watch and stop pipeline runs from the dashboard with a live log.
Opt-out line and postal address in every email.
Decodes Cloudflare email protection and filters placeholder and asset junk.
📎 extractor.pyKnown businesses are excluded before the per-run limit, so each run digs deeper into a city.
📎 discovery.pyThe dashboard spawns the pipeline without a shell and kills the whole process tree on stop.
📎 dashboard/src/lib/pipelineRunner.tsNext.js 16, React 19, Tailwind 4
Python, Playwright, asyncpg, BeautifulSoup, dnspython
PostgreSQL
Google Places API, OpenStreetMap, Nominatim, Ollama (optional)