Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

visitor-signal-engine

A consent-first website visitor identification pipeline in the shape of RB2B: a pixel spots your visitors, the collector resolves what it legitimately can, and a profile card lands in Slack (or your CRM) seconds later so your team can follow up on a warm timing signal.

It implements the full RB2B-style architecture (how it works) with one deliberate line: the person-level de-anonymization graph and social scraping are not built here. Those are vacant provider slots you connect to a licensed vendor with your own key and legal basis. Everything else — pixel, collector, company-level reverse-IP, first-party known-contact resolution, Slack/CRM delivery, consent + opt-out — is real, tested, and runnable.

 pixel ─▶ /collect ─▶ [consent gate] ─▶ [company-level] ─▶ [identity] ─▶ [enrich] ─▶ Slack / CRM
                          drop if no      reverse-IP        known-contact   (vacant)
                          consent/opt-out  (org, real)      or vendor (vacant)

Quick look (no dependencies, no network)

python3 -m app.main --demo
{ "case": "known person (US, consent, matches mock)",   "out": "Jane Sample (VP of Marketing) from Example Co visited /pricing", "resolution": "person" }
{ "case": "company only (US, consent, no person match)", "out": "Someone at Acme Corp visited /pricing",                          "resolution": "company" }
{ "case": "dropped (no consent)",                        "out": "dropped — no consent / opted out",                              "resolution": "-" }

The person shown is synthetic (MockPersonLevelResolver) — the demo touches no real data.

What's real vs. vacant

Capability Status Where
Pixel (consent-gated, first-party) ✅ real pixel/pixel.js
Collector API (/collect, /opt-out, /healthz) ✅ real app/main.py
Company-level (reverse-IP firmographics, org-only) ✅ real app/providers/company_ipinfo.py
Known-contact (first-party signed-token → your CRM) ✅ real app/providers/known_contact.py
Slack card + CRM/webhook delivery ✅ real app/delivery/
Consent + opt-out store, US+consent person gate ✅ real app/consent.py
Person-level de-anonymization vacant (interface + fake mock) app/providers/person_level.py
Social / LinkedIn enrichment vacant (no scraper) app/enrichment/social.py

Why the vacant slots, and the obligations that come with filling them: docs/privacy-and-legal.md.

Run the collector

pip install -r requirements.txt        # fastapi + uvicorn (core/demo need neither)
cp .env.example .env                    # set only what you use
uvicorn app.main:app --reload           # POST /collect, /opt-out; GET /healthz, /pixel.js

Install the pixel on your site (after your CMP records consent, set window.VSE_CONSENT = true):

<script>window.VSE_CONSENT = true;</script>
<script src="https://your-collector.example.com/pixel.js"
        data-endpoint="https://your-collector.example.com/collect"></script>

Every capability is opt-in via env (.env.example). With nothing configured, the engine runs anonymous/company-level only and never attempts person-level identification.

How resolution works

  1. Consent gate — opted-out or consent=false → the event is dropped; nothing is stored.
  2. Company-level — reverse-IP → the organization (hosting/ISP ranges are discarded). Names no individual; the accepted B2B practice, available globally.
  3. Identity — a first-party known-contact match (someone who arrived via a signed link from your own email/CRM, i.e. gave you their info) is tried first and always wins. Only then, and only with consent + US traffic, is the person-level vendor slot consulted — which is vacant until you connect one.
  4. Enrichment — optional licensed professional-data API (vacant; no scraping).
  5. Delivery — a Slack Block Kit card and/or a JSON webhook to your CRM, each carrying the identity's basis for auditability.

Tests

python3 -m pytest tests -q      # 24 tests, fully offline (HTTP + providers injected)

Layout

pixel/pixel.js              the consent-gated browser snippet
app/
  main.py                   FastAPI collector (+ dependency-free offline demo)
  pipeline.py               the 4-step orchestration; all guards live here
  consent.py                opt-out store + the US/consent person-level gate
  models.py                 VisitorEvent · Company · IdentityMatch · VisitorProfile
  config.py                 env → wired pipeline
  providers/                company (reverse-IP) · known-contact · person-level (vacant+mock)
  enrichment/social.py      social/professional enrichment (vacant)
  delivery/                 slack.py (card) · crm.py (webhook)
tests/                      24 offline tests
docs/                       how-rb2b-works · architecture · privacy-and-legal

Scope, stated plainly

This is a portfolio-grade implementation of the architecture and the legitimate capabilities of a person-level visitor tool, plus a clean integration surface for the licensed person-level layer. It intentionally does not ship covert de-anonymization or social scraping. See docs/privacy-and-legal.md.

About

Consent-first website visitor identification (RB2B-style): pixel to collector, company-level reverse-IP and first-party known-contact resolution, Slack/CRM delivery. Person-level de-anon and social enrichment are vacant licensed-vendor slots, not scrapers.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages