ADR-0004: One outbound CRM webhook to Apps Script / Sheets, not a hosted CRM
Validated leads have to land somewhere the owner will actually look. At current volume — a solo agency running early outreach — the options were:
ADR-0004: One outbound CRM webhook to Apps Script / Sheets, not a hosted CRM
- Status: Accepted
- Date: 2026-07-30 (recorded; implemented earlier)
- Deciders: Junaid Siddiqui (owner)
- Related:
../integrations/lead-capture.md,scripts/google-apps-script/SETUP.md, ADR-0003
Context
Validated leads have to land somewhere the owner will actually look. At current volume — a solo agency running early outreach — the options were:
- Hosted CRM (HubSpot, Pipedrive, and similar) — proper pipeline management, but a monthly cost, an API integration, an SDK dependency, and a vendor to migrate off later.
- Own database — full control, but this repo has no database, no ORM, and no reason to add either for a marketing site.
- Single generic outbound webhook to a Google Apps Script Web App that appends rows to a Google Sheet — zero cost, no npm dependency, no Google Cloud project, and a destination that can be swapped by changing one environment variable.
- Email notification — simple, but leads become unsearchable and unsortable.
The playbook's Tier 2 promises "CRM/WhatsApp Lead Integration", which argues for a delivery mechanism that can be pointed anywhere rather than one coupled to a specific vendor.
Decision
Deliver every validated lead as a single JSON POST to whatever CRM_WEBHOOK_URL names. The recommended receiver is a Google Apps Script Web App appending rows to a Google Sheet (scripts/google-apps-script/Code.gs, setup in scripts/google-apps-script/SETUP.md, deployed as Execute as Me / access Anyone, with Asia/Dubai date and time columns).
When CRM_WEBHOOK_URL is unset, leads are validated and logged server-side, so local development needs no webhook at all.
Being vendor-neutral is the point: the same mechanism can target a client's own CRM, an automation platform, or a WhatsApp relay without code changes.
Consequences
- Positive:
- No cost, no dependency, no vendor lock-in; the destination is one env var.
- Google Sheets is immediately usable — sortable, shareable, filterable, no training.
- Local dev works with nothing configured.
- Directly reusable as a client deliverable, since client CRMs vary.
- Trade-offs / costs:
- No retry, queue, or dead-letter path. A webhook outage loses the lead beyond the server log. This is the sharpest edge.
- No pipeline management: no stages, no follow-up reminders, no deduplication.
- The Apps Script Web App URL is effectively a write credential — anyone holding it can append rows. It must stay in
.env.localand host env only. - A Sheet will not scale as lead volume grows, and there is no second copy of the data.
- "WhatsApp integration" is not implemented; the webhook merely could target a relay (
../integrations/lead-capture.md).
- Follow-ups:
- Add retry with backoff, or persist failed payloads for replay.
- Add owner notification on arrival — the success message promises a reply within an hour.
- Revisit a hosted CRM once lead volume justifies pipeline management.
- Stop describing WhatsApp delivery as pre-built until it is.