Quick overview
This workflow runs on two schedules to read new leads from Google Sheets, validate and normalize email addresses, and queue each lead to a rate-limited CRM via Jitterflow, then writes queue status, job IDs, and CRM rejection errors back to the sheet.
How it works
- Runs every hour and reads all rows from the Google Sheets “Leads” sheet.
- Keeps only rows with an empty Status, then trims fields and normalizes the email to lowercase.
- Validates the email format and marks the row as “Invalid email” in Google Sheets when it fails validation.
- Sends valid leads to Jitterflow as webhook jobs (using the email as an idempotency key) so Jitterflow can deliver them to the CRM at the configured rate limit.
- Updates the originating Google Sheets row as “Queued”, stores the Jitterflow job ID, and notes if the email was already queued.
- Runs every morning at 8:00, lists unresolved jobs from the Jitterflow dead-letter queue, and filters to only entries created by this sheet import.
- Marks matching rows in Google Sheets as “Rejected by CRM” and writes the HTTP status/error reason into the Note column.
Setup
- Install and configure the community node n8n-nodes-jitterflow (required for the Jitterflow nodes).
- Create a Jitterflow API credential in n8n, create a Jitterflow endpoint that targets your CRM’s create-contact API (with auth and pacing), and paste the endpoint key into the workflow.
- Create a Google Sheet with a “Leads” tab and columns Email, First name, Last name, Company, Status, Jitterflow job, and Note.
- Add your Google Sheets OAuth credential in n8n and update the Google Sheet document ID on the Google Sheets nodes.
Requirements
- A Jitterflow account (the free Developer plan works; replaying CRM-rejected leads needs Pro), the verified n8n-nodes-jitterflow community node, and a Google Sheets account.
Customization
- Reshape the Payload on Queue lead for the CRM to match your CRM's field names, or run the intake every 15 minutes instead of hourly.