This workflow follows the Emailsend → HTTP Request recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"updatedAt": "2026-03-15T20:46:15.113Z",
"createdAt": "2026-03-08T19:25:51.109Z",
"id": "ElZJaflNkUL51zbk",
"name": "VenueDesk \u2014 AI Lead Generator (Daily)",
"description": null,
"active": true,
"isArchived": false,
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "hours",
"hoursInterval": 24
}
]
}
},
"id": "sch",
"name": "Daily at 9am",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1,
"position": [
624,
288
]
},
{
"parameters": {
"operation": "executeQuery",
"query": "SELECT * FROM leads WHERE status='new' AND website_url IS NOT NULL AND website_url <> '' AND website_url NOT LIKE '%example.com%' AND website_url NOT LIKE '%duckduckgo.com%' ORDER BY created_at ASC LIMIT 20",
"options": {}
},
"id": "pg_f",
"name": "Fetch New Leads",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2,
"position": [
848,
48
],
"credentials": {
"postgres": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"version": 2
},
"conditions": [
{
"id": "c1",
"leftValue": "={{ $json.id }}",
"operator": {
"type": "string",
"operation": "exists"
}
}
]
},
"options": {}
},
"id": "if1",
"name": "Any new leads?",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
1008,
48
]
},
{
"parameters": {
"url": "={{ $json.website_url || 'https://example.com' }}",
"options": {
"response": {
"response": {
"neverError": true
}
},
"timeout": 8000
}
},
"id": "http",
"name": "Fetch Website",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
1232,
32
],
"continueOnFail": true
},
{
"parameters": {
"modelId": "gpt-4o-mini",
"messages": {
"values": [
{
"content": "={{ $json.analysis_prompt }}"
}
]
},
"options": {
"temperature": 0.3
}
},
"id": "ai1",
"name": "AI Venue Analysis",
"type": "@n8n/n8n-nodes-langchain.openAi",
"typeVersion": 1,
"position": [
1584,
32
],
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "executeQuery",
"query": "SELECT * FROM leads WHERE status='contacted' AND reply_received=FALSE AND last_email_sent_at<NOW()-INTERVAL '4 days' AND follow_up_count<2 AND email IS NOT NULL ORDER BY last_email_sent_at ASC LIMIT 10",
"options": {}
},
"id": "pg_fu",
"name": "Fetch Follow-up Leads",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2,
"position": [
864,
448
],
"credentials": {
"postgres": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"modelId": "gpt-4o-mini",
"messages": {
"values": [
{
"content": "={{ $json.followup_prompt }}\nInclude this website link in the email: https://in2netdigital.online/venuedesk/"
}
]
},
"options": {
"temperature": 0.7
}
},
"id": "ai3",
"name": "AI Follow-up",
"type": "@n8n/n8n-nodes-langchain.openAi",
"typeVersion": 1,
"position": [
1568,
448
],
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"fromEmail": "bookings@venuedesk.co.uk",
"toEmail": "={{ $('Fetch Follow-up Leads').item.json.email }}",
"subject": "={{ JSON.parse($('AI Follow-up').item.json.message.content).subject }}",
"text": "={{ JSON.parse($('AI Follow-up').item.json.message.content).body }}",
"options": {}
},
"id": "se2",
"name": "Send Follow-up",
"type": "n8n-nodes-base.emailSend",
"typeVersion": 1,
"position": [
1856,
448
],
"credentials": {
"smtp": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "executeQuery",
"query": "UPDATE leads SET follow_up_count=follow_up_count+1,last_email_sent_at=NOW(),status=CASE WHEN follow_up_count>=1 THEN 'follow_up' ELSE status END WHERE id='{{ $('Fetch Follow-up Leads').item.json.id }}'",
"options": {}
},
"id": "pg_fuu",
"name": "Update Follow-up",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2,
"position": [
2016,
448
],
"credentials": {
"postgres": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "executeQuery",
"query": "INSERT INTO lead_activity (lead_id,type,message) VALUES ('{{ $('Fetch Follow-up Leads').item.json.id }}','email_sent','Follow-up sent to {{ $('Fetch Follow-up Leads').item.json.venue_name }}')",
"options": {}
},
"id": "lg2",
"name": "Log Follow-up",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2,
"position": [
2304,
448
],
"credentials": {
"postgres": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"version": 2
},
"conditions": [
{
"id": "cf1",
"leftValue": "={{ $json.id }}",
"operator": {
"type": "string",
"operation": "exists"
}
}
]
},
"options": {}
},
"id": "if_fu",
"name": "Any follow-up leads?",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
1104,
448
]
},
{
"parameters": {
"jsCode": "const lead = $('Fetch New Leads').item.json;\nconst fullHtml = $input.item.json.data ? String($input.item.json.data) : '';\n\n// Extract first email address found in the raw HTML\n// Skip noreply/privacy/legal addresses and the known test email\nconst TEST_EMAIL = 'andyralston.johnson@yahoo.com';\nconst SKIP = /noreply|no-reply|privacy|legal|info@example|webmaster|support@|admin@/i;\nconst emailRe = /[a-zA-Z0-9._%+\\-]+@[a-zA-Z0-9.\\-]+\\.[a-zA-Z]{2,}/g;\nlet scrapedEmail = '';\nlet match;\nwhile ((match = emailRe.exec(fullHtml)) !== null) {\n const candidate = match[0].toLowerCase();\n if (!SKIP.test(candidate) && candidate !== TEST_EMAIL.toLowerCase()) {\n scrapedEmail = candidate;\n break;\n }\n}\n\nconst website = fullHtml.length > 0 ? fullHtml.substring(0, 2000) : 'No website available';\nconst contactName = lead.contact_name || 'there';\nconst venueName = lead.venue_name || 'the venue';\nconst analysisPrompt = [\n 'Analyse this venue for VenueDesk CRM outreach.',\n 'Respond ONLY with valid JSON: {\"score\":<1-10>,\"venue_type\":\"<type>\",\"key_feature\":\"<one sentence>\",\"pain_point\":\"<one sentence>\",\"tone\":\"<formal|friendly>\"}',\n 'Venue: ' + venueName,\n 'Website content (first 2000 chars): ' + website\n].join('\\n');\nreturn [{ json: {\n ...lead,\n contact_name_resolved: contactName,\n venue_name_resolved: venueName,\n website_data: website,\n scraped_email: scrapedEmail,\n analysis_prompt: analysisPrompt\n} }];"
},
"id": "prep_analysis",
"name": "Prepare Analysis Prompt",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1424,
32
]
},
{
"parameters": {
"jsCode": "const lead = $input.item.json;\nconst contactName = lead.contact_name || 'there';\nconst venueName = lead.venue_name || 'the venue';\nconst followupPrompt = [\n 'Write a brief, friendly follow-up email for VenueDesk. Maximum 2 paragraphs, not pushy.',\n 'The email MUST:',\n '- Open with: Hi ' + contactName + ',',\n '- Reference ' + venueName + ' by name',\n '- Acknowledge the previous email was sent and you just wanted to check in',\n '- Close with: The VenueDesk Team',\n '- Be plain text, no placeholders or template variables',\n '',\n 'Respond ONLY with valid JSON: {\"subject\":\"<subject line>\",\"body\":\"<complete plain text email body>\"}',\n '',\n 'Venue name: ' + venueName,\n 'Contact name: ' + contactName\n].join('\\n');\nreturn [{ json: {\n ...lead,\n contact_name_resolved: contactName,\n venue_name_resolved: venueName,\n followup_prompt: followupPrompt\n} }];"
},
"id": "prep_followup",
"name": "Prepare Follow-up Prompt",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1328,
448
]
},
{
"parameters": {
"jsCode": "const lead = $('Fetch New Leads').item.json;\nif (!lead.id) return [];\nconst anRaw = $input.item.json.message.content;\nlet a = {score: 5};\ntry { a = JSON.parse(anRaw.replace(/^```json\\n?|```$/g, '')); } catch(x) {}\nconst esc = s => (s || '').replace(/'/g, \"''\");\nreturn [{ json: { ...lead, ai_score: a.score || 5, ai_analysis: esc(anRaw) } }];"
},
"id": "parse_score",
"name": "Parse Score",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1712,
-32
]
},
{
"parameters": {
"operation": "executeQuery",
"query": "UPDATE leads SET ai_score={{ $('Parse Score').item.json.ai_score }},ai_analysis='{{ $('Parse Score').item.json.ai_analysis }}',status='scored',email=CASE WHEN (email IS NULL OR email='' OR email='andyralston.johnson@yahoo.com') AND '{{ $('Prepare Analysis Prompt').item.json.scraped_email }}' != '' THEN '{{ $('Prepare Analysis Prompt').item.json.scraped_email }}' ELSE email END WHERE id='{{ $('Parse Score').item.json.id }}'",
"options": {}
},
"id": "save_score",
"name": "Save Score",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.5,
"position": [
1824,
32
],
"credentials": {
"postgres": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "executeQuery",
"query": "INSERT INTO lead_activity (lead_id,type,message) VALUES ('{{ $('Parse Score').item.json.id }}','lead_scored','AI scored lead: score={{ $('Parse Score').item.json.ai_score }}')",
"options": {}
},
"id": "log_score",
"name": "Log Score Saved",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.5,
"position": [
2064,
32
],
"credentials": {
"postgres": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"path": "run-leadgen-now",
"responseMode": "onReceived",
"options": {},
"httpMethod": "POST",
"authentication": "none"
},
"id": "wh_manual_run",
"name": "Manual Run Trigger",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
200,
160
],
"credentials": {}
}
],
"connections": {
"Daily at 9am": {
"main": [
[
{
"node": "Fetch New Leads",
"type": "main",
"index": 0
},
{
"node": "Fetch Follow-up Leads",
"type": "main",
"index": 0
}
]
]
},
"Fetch New Leads": {
"main": [
[
{
"node": "Any new leads?",
"type": "main",
"index": 0
}
]
]
},
"Any new leads?": {
"main": [
[
{
"node": "Fetch Website",
"type": "main",
"index": 0
}
],
[]
]
},
"Fetch Website": {
"main": [
[
{
"node": "Prepare Analysis Prompt",
"type": "main",
"index": 0
}
]
]
},
"Fetch Follow-up Leads": {
"main": [
[
{
"node": "Any follow-up leads?",
"type": "main",
"index": 0
}
]
]
},
"AI Follow-up": {
"main": [
[
{
"node": "Send Follow-up",
"type": "main",
"index": 0
}
]
]
},
"Send Follow-up": {
"main": [
[
{
"node": "Update Follow-up",
"type": "main",
"index": 0
}
]
]
},
"Update Follow-up": {
"main": [
[
{
"node": "Log Follow-up",
"type": "main",
"index": 0
}
]
]
},
"Any follow-up leads?": {
"main": [
[
{
"node": "Prepare Follow-up Prompt",
"type": "main",
"index": 0
}
],
[]
]
},
"Prepare Analysis Prompt": {
"main": [
[
{
"node": "AI Venue Analysis",
"type": "main",
"index": 0
}
]
]
},
"Prepare Follow-up Prompt": {
"main": [
[
{
"node": "AI Follow-up",
"type": "main",
"index": 0
}
]
]
},
"AI Venue Analysis": {
"main": [
[
{
"node": "Parse Score",
"type": "main",
"index": 0
}
]
]
},
"Parse Score": {
"main": [
[
{
"node": "Save Score",
"type": "main",
"index": 0
}
]
]
},
"Save Score": {
"main": [
[
{
"node": "Log Score Saved",
"type": "main",
"index": 0
}
]
]
},
"Manual Run Trigger": {
"main": [
[
{
"node": "Fetch New Leads",
"type": "main",
"index": 0
},
{
"node": "Fetch Follow-up Leads",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1",
"callerPolicy": "workflowsFromSameOwner",
"availableInMCP": true
},
"staticData": {
"node:Daily at 9am": {
"recurrenceRules": [
0
]
}
},
"meta": null,
"versionId": "33935db5-c6c7-4a32-a441-9c726ad21da6",
"activeVersionId": "33935db5-c6c7-4a32-a441-9c726ad21da6",
"versionCounter": 126,
"triggerCount": 2,
"shared": [
{
"updatedAt": "2026-03-08T19:25:51.109Z",
"createdAt": "2026-03-08T19:25:51.109Z",
"role": "workflow:owner",
"workflowId": "ElZJaflNkUL51zbk",
"projectId": "xsdyFVsct988qLUy",
"project": {
"updatedAt": "2025-12-04T20:24:17.537Z",
"createdAt": "2025-12-04T19:47:48.685Z",
"id": "xsdyFVsct988qLUy",
"name": "andrew johnson <andrew.ralston.johnson@gmail.com>",
"type": "personal",
"icon": null,
"description": null,
"creatorId": "e2485274-7097-4eb5-8502-e39b2308096c"
}
}
],
"tags": [],
"activeVersion": {
"updatedAt": "2026-03-10T20:51:48.304Z",
"createdAt": "2026-03-10T20:51:48.304Z",
"versionId": "33935db5-c6c7-4a32-a441-9c726ad21da6",
"workflowId": "ElZJaflNkUL51zbk",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "hours",
"hoursInterval": 24
}
]
}
},
"id": "sch",
"name": "Daily at 9am",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1,
"position": [
624,
288
]
},
{
"parameters": {
"operation": "executeQuery",
"query": "SELECT * FROM leads WHERE status='new' AND website_url IS NOT NULL AND website_url <> '' AND website_url NOT LIKE '%example.com%' AND website_url NOT LIKE '%duckduckgo.com%' ORDER BY created_at ASC LIMIT 20",
"options": {}
},
"id": "pg_f",
"name": "Fetch New Leads",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2,
"position": [
848,
48
],
"credentials": {
"postgres": {
"id": "iEsRYyB7vjr5G7i8",
"name": "Postgres account 3"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"version": 2
},
"conditions": [
{
"id": "c1",
"leftValue": "={{ $json.id }}",
"operator": {
"type": "string",
"operation": "exists"
}
}
]
},
"options": {}
},
"id": "if1",
"name": "Any new leads?",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
1008,
48
]
},
{
"parameters": {
"url": "={{ $json.website_url || 'https://example.com' }}",
"options": {
"response": {
"response": {
"neverError": true
}
},
"timeout": 8000
}
},
"id": "http",
"name": "Fetch Website",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
1232,
32
],
"continueOnFail": true
},
{
"parameters": {
"modelId": "gpt-4o-mini",
"messages": {
"values": [
{
"content": "={{ $json.analysis_prompt }}"
}
]
},
"options": {
"temperature": 0.3
}
},
"id": "ai1",
"name": "AI Venue Analysis",
"type": "@n8n/n8n-nodes-langchain.openAi",
"typeVersion": 1,
"position": [
1584,
32
],
"credentials": {
"openAiApi": {
"id": "sAiUxZnK5nm6DZfX",
"name": "OpenAi account 2"
}
}
},
{
"parameters": {
"operation": "executeQuery",
"query": "SELECT * FROM leads WHERE status='contacted' AND reply_received=FALSE AND last_email_sent_at<NOW()-INTERVAL '4 days' AND follow_up_count<2 AND email IS NOT NULL ORDER BY last_email_sent_at ASC LIMIT 10",
"options": {}
},
"id": "pg_fu",
"name": "Fetch Follow-up Leads",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2,
"position": [
864,
448
],
"credentials": {
"postgres": {
"id": "iEsRYyB7vjr5G7i8",
"name": "Postgres account 3"
}
}
},
{
"parameters": {
"modelId": "gpt-4o-mini",
"messages": {
"values": [
{
"content": "={{ $json.followup_prompt }}\nInclude this website link in the email: https://in2netdigital.online/venuedesk/"
}
]
},
"options": {
"temperature": 0.7
}
},
"id": "ai3",
"name": "AI Follow-up",
"type": "@n8n/n8n-nodes-langchain.openAi",
"typeVersion": 1,
"position": [
1568,
448
],
"credentials": {
"openAiApi": {
"id": "sAiUxZnK5nm6DZfX",
"name": "OpenAi account 2"
}
}
},
{
"parameters": {
"fromEmail": "bookings@venuedesk.co.uk",
"toEmail": "={{ $('Fetch Follow-up Leads').item.json.email }}",
"subject": "={{ JSON.parse($('AI Follow-up').item.json.message.content).subject }}",
"text": "={{ JSON.parse($('AI Follow-up').item.json.message.content).body }}",
"options": {}
},
"id": "se2",
"name": "Send Follow-up",
"type": "n8n-nodes-base.emailSend",
"typeVersion": 1,
"position": [
1856,
448
],
"webhookId": "3cd27384-6e91-4ca4-95ec-21fb6a647a2d",
"credentials": {
"smtp": {
"id": "oWx6QKxXljDdeSDP",
"name": "SMTP account"
}
}
},
{
"parameters": {
"operation": "executeQuery",
"query": "UPDATE leads SET follow_up_count=follow_up_count+1,last_email_sent_at=NOW(),status=CASE WHEN follow_up_count>=1 THEN 'follow_up' ELSE status END WHERE id='{{ $('Fetch Follow-up Leads').item.json.id }}'",
"options": {}
},
"id": "pg_fuu",
"name": "Update Follow-up",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2,
"position": [
2016,
448
],
"credentials": {
"postgres": {
"id": "iEsRYyB7vjr5G7i8",
"name": "Postgres account 3"
}
}
},
{
"parameters": {
"operation": "executeQuery",
"query": "INSERT INTO lead_activity (lead_id,type,message) VALUES ('{{ $('Fetch Follow-up Leads').item.json.id }}','email_sent','Follow-up sent to {{ $('Fetch Follow-up Leads').item.json.venue_name }}')",
"options": {}
},
"id": "lg2",
"name": "Log Follow-up",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2,
"position": [
2304,
448
],
"credentials": {
"postgres": {
"id": "iEsRYyB7vjr5G7i8",
"name": "Postgres account 3"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"version": 2
},
"conditions": [
{
"id": "cf1",
"leftValue": "={{ $json.id }}",
"operator": {
"type": "string",
"operation": "exists"
}
}
]
},
"options": {}
},
"id": "if_fu",
"name": "Any follow-up leads?",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
1104,
448
]
},
{
"parameters": {
"jsCode": "const lead = $('Fetch New Leads').item.json;\nconst fullHtml = $input.item.json.data ? String($input.item.json.data) : '';\n\n// Extract first email address found in the raw HTML\n// Skip noreply/privacy/legal addresses and the known test email\nconst TEST_EMAIL = 'andyralston.johnson@yahoo.com';\nconst SKIP = /noreply|no-reply|privacy|legal|info@example|webmaster|support@|admin@/i;\nconst emailRe = /[a-zA-Z0-9._%+\\-]+@[a-zA-Z0-9.\\-]+\\.[a-zA-Z]{2,}/g;\nlet scrapedEmail = '';\nlet match;\nwhile ((match = emailRe.exec(fullHtml)) !== null) {\n const candidate = match[0].toLowerCase();\n if (!SKIP.test(candidate) && candidate !== TEST_EMAIL.toLowerCase()) {\n scrapedEmail = candidate;\n break;\n }\n}\n\nconst website = fullHtml.length > 0 ? fullHtml.substring(0, 2000) : 'No website available';\nconst contactName = lead.contact_name || 'there';\nconst venueName = lead.venue_name || 'the venue';\nconst analysisPrompt = [\n 'Analyse this venue for VenueDesk CRM outreach.',\n 'Respond ONLY with valid JSON: {\"score\":<1-10>,\"venue_type\":\"<type>\",\"key_feature\":\"<one sentence>\",\"pain_point\":\"<one sentence>\",\"tone\":\"<formal|friendly>\"}',\n 'Venue: ' + venueName,\n 'Website content (first 2000 chars): ' + website\n].join('\\n');\nreturn [{ json: {\n ...lead,\n contact_name_resolved: contactName,\n venue_name_resolved: venueName,\n website_data: website,\n scraped_email: scrapedEmail,\n analysis_prompt: analysisPrompt\n} }];"
},
"id": "prep_analysis",
"name": "Prepare Analysis Prompt",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1424,
32
]
},
{
"parameters": {
"jsCode": "const lead = $input.item.json;\nconst contactName = lead.contact_name || 'there';\nconst venueName = lead.venue_name || 'the venue';\nconst followupPrompt = [\n 'Write a brief, friendly follow-up email for VenueDesk. Maximum 2 paragraphs, not pushy.',\n 'The email MUST:',\n '- Open with: Hi ' + contactName + ',',\n '- Reference ' + venueName + ' by name',\n '- Acknowledge the previous email was sent and you just wanted to check in',\n '- Close with: The VenueDesk Team',\n '- Be plain text, no placeholders or template variables',\n '',\n 'Respond ONLY with valid JSON: {\"subject\":\"<subject line>\",\"body\":\"<complete plain text email body>\"}',\n '',\n 'Venue name: ' + venueName,\n 'Contact name: ' + contactName\n].join('\\n');\nreturn [{ json: {\n ...lead,\n contact_name_resolved: contactName,\n venue_name_resolved: venueName,\n followup_prompt: followupPrompt\n} }];"
},
"id": "prep_followup",
"name": "Prepare Follow-up Prompt",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1328,
448
]
},
{
"parameters": {
"jsCode": "const lead = $('Fetch New Leads').item.json;\nif (!lead.id) return [];\nconst anRaw = $input.item.json.message.content;\nlet a = {score: 5};\ntry { a = JSON.parse(anRaw.replace(/^```json\\n?|```$/g, '')); } catch(x) {}\nconst esc = s => (s || '').replace(/'/g, \"''\");\nreturn [{ json: { ...lead, ai_score: a.score || 5, ai_analysis: esc(anRaw) } }];"
},
"id": "parse_score",
"name": "Parse Score",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1712,
-32
]
},
{
"parameters": {
"operation": "executeQuery",
"query": "UPDATE leads SET ai_score={{ $('Parse Score').item.json.ai_score }},ai_analysis='{{ $('Parse Score').item.json.ai_analysis }}',status='scored',email=CASE WHEN (email IS NULL OR email='' OR email='andyralston.johnson@yahoo.com') AND '{{ $('Prepare Analysis Prompt').item.json.scraped_email }}' != '' THEN '{{ $('Prepare Analysis Prompt').item.json.scraped_email }}' ELSE email END WHERE id='{{ $('Parse Score').item.json.id }}'",
"options": {}
},
"id": "save_score",
"name": "Save Score",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.5,
"position": [
1824,
32
],
"credentials": {
"postgres": {
"id": "iEsRYyB7vjr5G7i8",
"name": "Postgres account 3"
}
}
},
{
"parameters": {
"operation": "executeQuery",
"query": "INSERT INTO lead_activity (lead_id,type,message) VALUES ('{{ $('Parse Score').item.json.id }}','lead_scored','AI scored lead: score={{ $('Parse Score').item.json.ai_score }}')",
"options": {}
},
"id": "log_score",
"name": "Log Score Saved",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.5,
"position": [
2064,
32
],
"credentials": {
"postgres": {
"id": "iEsRYyB7vjr5G7i8",
"name": "Postgres account 3"
}
}
},
{
"parameters": {
"path": "run-leadgen-now",
"responseMode": "onReceived",
"options": {},
"httpMethod": "POST",
"authentication": "none"
},
"id": "wh_manual_run",
"name": "Manual Run Trigger",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
200,
160
],
"webhookId": "run-leadgen-now",
"credentials": {}
}
],
"connections": {
"Daily at 9am": {
"main": [
[
{
"node": "Fetch New Leads",
"type": "main",
"index": 0
},
{
"node": "Fetch Follow-up Leads",
"type": "main",
"index": 0
}
]
]
},
"Fetch New Leads": {
"main": [
[
{
"node": "Any new leads?",
"type": "main",
"index": 0
}
]
]
},
"Any new leads?": {
"main": [
[
{
"node": "Fetch Website",
"type": "main",
"index": 0
}
],
[]
]
},
"Fetch Website": {
"main": [
[
{
"node": "Prepare Analysis Prompt",
"type": "main",
"index": 0
}
]
]
},
"Fetch Follow-up Leads": {
"main": [
[
{
"node": "Any follow-up leads?",
"type": "main",
"index": 0
}
]
]
},
"AI Follow-up": {
"main": [
[
{
"node": "Send Follow-up",
"type": "main",
"index": 0
}
]
]
},
"Send Follow-up": {
"main": [
[
{
"node": "Update Follow-up",
"type": "main",
"index": 0
}
]
]
},
"Update Follow-up": {
"main": [
[
{
"node": "Log Follow-up",
"type": "main",
"index": 0
}
]
]
},
"Any follow-up leads?": {
"main": [
[
{
"node": "Prepare Follow-up Prompt",
"type": "main",
"index": 0
}
],
[]
]
},
"Prepare Analysis Prompt": {
"main": [
[
{
"node": "AI Venue Analysis",
"type": "main",
"index": 0
}
]
]
},
"Prepare Follow-up Prompt": {
"main": [
[
{
"node": "AI Follow-up",
"type": "main",
"index": 0
}
]
]
},
"AI Venue Analysis": {
"main": [
[
{
"node": "Parse Score",
"type": "main",
"index": 0
}
]
]
},
"Parse Score": {
"main": [
[
{
"node": "Save Score",
"type": "main",
"index": 0
}
]
]
},
"Save Score": {
"main": [
[
{
"node": "Log Score Saved",
"type": "main",
"index": 0
}
]
]
},
"Manual Run Trigger": {
"main": [
[
{
"node": "Fetch New Leads",
"type": "main",
"index": 0
},
{
"node": "Fetch Follow-up Leads",
"type": "main",
"index": 0
}
]
]
}
},
"authors": "andrew johnson",
"name": null,
"description": null,
"autosaved": false,
"workflowPublishHistory": [
{
"createdAt": "2026-03-10T20:51:48.335Z",
"id": 925,
"workflowId": "ElZJaflNkUL51zbk",
"versionId": "33935db5-c6c7-4a32-a441-9c726ad21da6",
"event": "deactivated",
"userId": "e2485274-7097-4eb5-8502-e39b2308096c"
},
{
"createdAt": "2026-03-10T20:51:48.352Z",
"id": 926,
"workflowId": "ElZJaflNkUL51zbk",
"versionId": "33935db5-c6c7-4a32-a441-9c726ad21da6",
"event": "activated",
"userId": "e2485274-7097-4eb5-8502-e39b2308096c"
},
{
"createdAt": "2026-03-15T20:46:15.146Z",
"id": 1411,
"workflowId": "ElZJaflNkUL51zbk",
"versionId": "33935db5-c6c7-4a32-a441-9c726ad21da6",
"event": "deactivated",
"userId": "e2485274-7097-4eb5-8502-e39b2308096c"
},
{
"createdAt": "2026-03-15T20:46:15.163Z",
"id": 1412,
"workflowId": "ElZJaflNkUL51zbk",
"versionId": "33935db5-c6c7-4a32-a441-9c726ad21da6",
"event": "activated",
"userId": "e2485274-7097-4eb5-8502-e39b2308096c"
}
]
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
openAiApipostgressmtp
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
VenueDesk — AI Lead Generator (Daily). Uses postgres, httpRequest, openAi, emailSend. Scheduled trigger; 17 nodes.
Source: https://github.com/AndyJay72/VenueDesk/blob/main/n8n-workflows/ElZJaflNkUL51zbk.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This n8n workflow automates the monitoring of warehouse inventory and sales velocity to predict demand, generate purchase orders automatically, send them to suppliers, and record all transactions in E
A scheduled process aggregates content from eight distinct data sources and standardizes all inputs into a unified format. AI models perform sentiment scoring, detect conspiracy or misinformation sign
Relatorio de custos AWS FinOps. Uses awsS3, googleSheets, emailSend, openAi. Scheduled trigger; 29 nodes.
Daily Economic News Brief for Israel (Hebrew, RTL, GPT-4o)
Runs every morning at 8:00 using the Schedule Trigger. Sets a value and queries Salesforce for Opportunities where equals that value and the stage is not Closed Won / Closed Lost. For each “stale” Opp