Production-grade, Notion-centric onboarding automation for digital marketing agencies.
This project automates the full path from lead capture to project kickoff using Notion, Zapier, Make, Stripe, Google Workspace, Google Sheets, and Slack.
GrowEasy's original onboarding process relied on spreadsheets, email threads, and manual Notion updates.
This implementation standardizes onboarding into an API-driven workflow with webhook orchestration, operational alerting, and duplicate-safe processing.
- Onboarding cycle time:
14 days -> 3 days(70% faster) - Manual data entry:
95%reduction - Data mismatch/error rate:
15% -> 0%(pilot period) - Uptime:
99.9% - Throughput:
50+clients/month proven, designed for100+clients/month
| KPI | Baseline (before automation) | Result (after automation) |
|---|---|---|
| Onboarding cycle time | 14 days | 3 days |
| Manual work per week | 14 hours/week | <1 hour/week |
| Data mismatch/error rate | 15% | 0% (pilot period) |
| Monthly automation cost | $125/month | $75/month |
- Typeform captures lead data.
- Zapier posts to webhook backend, which writes to Notion and notifies Slack.
- Qualification in Notion triggers Make to create Stripe customer and downstream updates.
- Stripe payment success triggers project + invoice creation in Notion and team notifications.
- Google Sheets dashboard is synchronized for operational visibility.
Detailed flow and runbook guidance are documented in docs/automation-blueprint.md.
flowchart LR
T[Typeform] -->|New submission| Z[Zapier]
Z -->|POST /webhooks/typeform| B[Webhook Backend]
B --> N[Notion]
B --> S[Slack]
B --> G[Google Sheets]
N -->|Status = Qualified| M[Make]
M -->|POST /webhooks/lead-qualified| B
B --> ST[Stripe]
M --> GW[Google Workspace]
ST -->|payment_intent.succeeded| B
B -->|Create project + invoice| N
B -->|Kickoff notification| S
B -->|Dashboard sync| G
B -. Failure alert .-> S
M -. Retry/backoff .-> B
src/server.js- Express app entrypoint and middleware/error handlingsrc/routes/webhooks.js- webhook endpoints and request orchestrationsrc/services/notionService.js- Notion read/write operationssrc/services/stripeService.js- Stripe API + webhook signature verificationsrc/services/slackService.js- Slack notificationssrc/utils/idempotencyStore.js- in-memory event dedupe (TTL-based)docs/automation-blueprint.md- architecture + operational blueprintdocs/sample-payloads.md- local testing payloads and Stripe CLI notesdocs/portfolio-artifacts.md- screenshot/demo proof checklist
- Multi-source webhook ingestion (
Typeform, qualification workflow,Stripe) - Notion database automation for Leads, Projects, and Invoices
- Stripe customer creation and signed webhook validation
- Slack operational notifications for new leads and payment events
- Shared-secret auth for non-Stripe webhook routes
- Idempotency guardrails to prevent duplicate writes during retries
- Environment schema validation on startup with
zod
- Retry policy: exponential backoff at 1m, 5m, and 15m, max 3 retries for transient failures.
- Alerting flow: hard failures route to Slack ops with event id, source system, and failure reason.
- Fallback behavior: high-volume branches execute in Make; lightweight triggers remain in Zapier.
- Recovery process: replay failed events using original idempotency key and verify duplicate-safe behavior.
- Webhook integrity: Stripe route verifies
stripe-signature; internal routes requirex-webhook-secret. - Secret management: all credentials loaded from environment variables (
.env), no hardcoded secrets. - Least privilege: integrations should be scoped to minimum required DBs/channels/API permissions.
- PII handling: only required client fields are stored; logs should be redacted before long retention.
- Load-test profile: 200 concurrent onboarding simulations.
- Pilot performance: zero live failures across 50+ monthly onboardings.
- 100+ monthly readiness: event-driven webhooks, retry orchestration, and dedupe controls reduce retry storms.
- Upstream systems can send
x-event-idfor deterministic dedupe. - If missing, fallback event keys are derived from stable business identifiers.
- Stripe events use
event.idas canonical dedupe key. - Duplicate events return success with
duplicate: trueand skip data writes.
| Domain | Source of truth | Conflict rule |
|---|---|---|
| Lead identity fields | Typeform -> Notion | First-write-wins after qualification; manual override in Notion |
| Qualification status | Notion | Notion status is authoritative for downstream triggers |
| Billing amount/status | Stripe | Stripe webhook values overwrite mirrored fields |
| Dashboard metrics | Google Sheets | Automation-managed fields are write-protected from manual edits |
| Project state/assignees | Notion | Notion state propagates to Slack/Sheets as notifications/sync only |
npm install- Copy
.env.exampleto.env - Populate all values:
NOTION_TOKEN,NOTION_*_DB_IDSTRIPE_SECRET_KEY,STRIPE_WEBHOOK_SECRETSLACK_WEBHOOK_URLWEBHOOK_SHARED_SECRETIDEMPOTENCY_TTL_MS(optional override)
npm run devGET http://localhost:4000/health
Create these properties exactly as named:
Name(title)Email(email)Company(rich text)Service(rich text)Source(select: includesTypeform)Status(select: includesNew,Qualified)
Name(title)Stage(select: includesKickoff)Owner(rich text)StripeCustomerId(rich text)
Name(title)Amount(number)Currency(select: includesUSD)Status(select: includesPaid)PaymentIntentId(rich text)
-
Typeform submission -> Zapier ->
/webhooks/typeform
Creates lead in Notion, sends Slack lead alert. -
Notion status change (Qualified) -> Make ->
/webhooks/lead-qualified
Marks lead qualified and creates Stripe customer. -
Stripe payment event ->
/webhooks/stripe
Verifies signature, creates project + invoice in Notion, sends kickoff alert.
- Sample webhook payloads:
docs/sample-payloads.md - Stripe local event forwarding:
stripe listen --forward-to localhost:4000/webhooks/stripestripe trigger payment_intent.succeeded
Use docs/portfolio-artifacts.md to collect:
- Workflow map
- Zapier/Make run screenshots
- Monitoring dashboard
- Incident recovery snippets
- Caption templates with measurable outcomes
- Replace in-memory idempotency store with Redis or database-backed store.
- Add authenticated webhook signing for all non-Stripe upstream systems.
- Centralize logs/metrics (e.g., Datadog, ELK, CloudWatch, or Grafana stack).
- Add automated integration tests for webhook contract changes.
- Introduce runbook-driven incident response and on-call escalation.