This workflow corresponds to n8n.io template #17558 — we link there as the canonical source.
This workflow follows the Chainllm → Google Sheets 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 →
{
"name": "Qualify leads from Google Sheets with AI and send them to Slack",
"nodes": [
{
"id": "sticky-10",
"name": "Sticky Note10",
"type": "n8n-nodes-base.stickyNote",
"position": [
-660,
-80
],
"parameters": {
"color": 1,
"width": 540,
"height": 980,
"content": "## Qualify leads from Google Sheets with AI and send them to Slack\n\n### Who's it for\nAnyone collecting leads from places that cannot be automated - Facebook groups,\nLinkedIn, WhatsApp, in-person referrals, or forums with a closed API. You do the\ncollecting, this does the qualifying.\n\n### How it works\nYou paste a post, message, or enquiry into a Google Sheet. Each new row triggers\nthe workflow, which sends the text to a language model together with a\ndescription of your business. The model returns a buying-intent score from 0 to\n10, a category, and a one-line reason. All three are written straight back to\nthe same row, so the sheet doubles as a lead tracker with full history. Only\nrows at or above your score threshold raise a Slack alert, which keeps the\nchannel signal-only.\n\n### How to set up\n1. Create a sheet with these headers: post_text, link, source, relevant, score,\n category, reason, status.\n2. Select that sheet in both Google Sheets nodes.\n3. Describe your business in \"Configure here\" and set minScore.\n4. Add language model and Slack credentials.\n\n### Requirements\nA Google account, an OpenAI (or compatible) API key, and Slack.\n\n### How to customize\nReplace the Sheets trigger with a webhook or form submission. Adjust the scoring\nbands in the prompt, or add categories that match your services."
},
"typeVersion": 1
},
{
"id": "sticky-11",
"name": "Sticky Note11",
"type": "n8n-nodes-base.stickyNote",
"position": [
-60,
-300
],
"parameters": {
"color": 7,
"width": 460,
"height": 200,
"content": "### 1. New row and configuration\nDescribe your business in the Set node - the model uses it to score."
},
"typeVersion": 1
},
{
"id": "sticky-12",
"name": "Sticky Note12",
"type": "n8n-nodes-base.stickyNote",
"position": [
420,
-300
],
"parameters": {
"color": 7,
"width": 440,
"height": 200,
"content": "### 2. AI qualification\nReturns score, category, and a one-line reason."
},
"typeVersion": 1
},
{
"id": "sticky-13",
"name": "Sticky Note13",
"type": "n8n-nodes-base.stickyNote",
"position": [
880,
-300
],
"parameters": {
"color": 7,
"width": 540,
"height": 200,
"content": "### 3. Write back and alert\nEvery row is scored. Only strong ones reach Slack."
},
"typeVersion": 1
},
{
"id": "sheettrigger",
"name": "New row in Google Sheets",
"type": "n8n-nodes-base.googleSheetsTrigger",
"position": [
0,
0
],
"parameters": {
"event": "rowAdded",
"options": {},
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "",
"cachedResultName": ""
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "",
"cachedResultName": ""
}
},
"typeVersion": 1
},
{
"id": "config",
"name": "Configure here",
"type": "n8n-nodes-base.set",
"position": [
220,
0
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "f0",
"name": "businessContext",
"type": "string",
"value": "We build and automate marketing websites (Webflow and WordPress) for small B2B and SaaS companies. Not e-commerce, not complex custom applications."
},
{
"id": "f1",
"name": "minScore",
"type": "number",
"value": "7"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "guard",
"name": "Skip empty rows",
"type": "n8n-nodes-base.filter",
"position": [
440,
0
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "hastext",
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{ $json.post_text }}",
"rightValue": ""
}
]
},
"looseTypeValidation": true
},
"typeVersion": 2.2
},
{
"id": "llm",
"name": "Qualify the lead",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
660,
0
],
"parameters": {
"text": "=You qualify inbound leads for this business:\n{{ $json.businessContext }}\n\nPost:\n\"\"\"\n{{ $json.post_text }}\n\"\"\"\nSource: {{ $json.source }}\n\nScore buying intent from 0 to 10:\n- 9 to 10: explicitly looking to hire someone now\n- 6 to 8: has a real project or problem and is weighing options\n- 3 to 5: general research, no project yet\n- 0 to 2: irrelevant, self-promotion, or a competitor selling\n\nCategorise as one of: new_website, redesign, platform_help, automation, seo, other.\n\nSet relevant to true only if this is a real person with a real need the business above could serve. Give one short sentence of reasoning, no hedging.",
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 1.5
},
{
"id": "model",
"name": "Language model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
620,
220
],
"parameters": {
"options": {}
},
"typeVersion": 1.2
},
{
"id": "parser",
"name": "Structured output",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
760,
220
],
"parameters": {
"jsonSchemaExample": "{\n \"relevant\": true,\n \"score\": 8,\n \"category\": \"new_website\",\n \"reason\": \"Pre-launch founder with copy ready, asking who to hire.\"\n}"
},
"typeVersion": 1.2
},
{
"id": "writeback",
"name": "Write score back to the row",
"type": "n8n-nodes-base.googleSheets",
"position": [
900,
0
],
"parameters": {
"columns": {
"value": {
"score": "={{ $json.output.score }}",
"reason": "={{ $json.output.reason }}",
"status": "qualified",
"category": "={{ $json.output.category }}",
"relevant": "={{ $json.output.relevant }}",
"row_number": "={{ $('New row in Google Sheets').item.json.row_number }}"
},
"schema": [],
"mappingMode": "defineBelow",
"matchingColumns": [
"row_number"
]
},
"options": {},
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "",
"cachedResultName": ""
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "",
"cachedResultName": ""
}
},
"typeVersion": 4.5
},
{
"id": "worth",
"name": "Above the score threshold",
"type": "n8n-nodes-base.if",
"position": [
1120,
0
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "rel",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $('Qualify the lead').item.json.output.relevant }}",
"rightValue": "true"
},
{
"id": "score",
"operator": {
"type": "number",
"operation": "gte"
},
"leftValue": "={{ $('Qualify the lead').item.json.output.score }}",
"rightValue": "={{ $('Configure here').first().json.minScore }}"
}
]
},
"looseTypeValidation": true
},
"typeVersion": 2.2
},
{
"id": "slack",
"name": "Alert the team in Slack",
"type": "n8n-nodes-base.slack",
"position": [
1340,
0
],
"parameters": {
"text": "=*New lead - score {{ $('Qualify the lead').item.json.output.score }}/10* ({{ $('Qualify the lead').item.json.output.category }})\n_{{ $('Qualify the lead').item.json.output.reason }}_\n\n{{ $('New row in Google Sheets').item.json.post_text.slice(0, 500) }}\n\n<{{ $('New row in Google Sheets').item.json.link }}|Open the original>",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": "",
"cachedResultName": ""
},
"otherOptions": {
"mrkdwn": true
}
},
"typeVersion": 2.3
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"connections": {
"Configure here": {
"main": [
[
{
"node": "Skip empty rows",
"type": "main",
"index": 0
}
]
]
},
"Language model": {
"ai_languageModel": [
[
{
"node": "Qualify the lead",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Skip empty rows": {
"main": [
[
{
"node": "Qualify the lead",
"type": "main",
"index": 0
}
]
]
},
"Qualify the lead": {
"main": [
[
{
"node": "Write score back to the row",
"type": "main",
"index": 0
}
]
]
},
"Structured output": {
"ai_outputParser": [
[
{
"node": "Qualify the lead",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"New row in Google Sheets": {
"main": [
[
{
"node": "Configure here",
"type": "main",
"index": 0
}
]
]
},
"Above the score threshold": {
"main": [
[
{
"node": "Alert the team in Slack",
"type": "main",
"index": 0
}
],
[]
]
},
"Write score back to the row": {
"main": [
[
{
"node": "Above the score threshold",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow watches for new rows in Google Sheets, uses an OpenAI chat model to score and categorize lead intent with structured output, writes the results back to the same sheet, and posts only high-scoring relevant leads to a Slack channel. Triggers every minute when a new…
Source: https://n8n.io/workflows/17558/ — 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 end-to-end AI-powered recruitment automation workflow helps HR and talent acquisition teams automate the complete hiring pipeline—from resume intake and parsing to GPT-4-based evaluation, TA appr
[](https://www.youtube.com/watch?v=MD1krFvVKdU) Automatically extract, evaluate, and shortlist multiple resumes against a selected job description using GPT-4. This smart, scalable n8n workflow helps
A smart and reliable resume screening pipeline for modern HR teams. This workflow combines Google Drive (JD & CV storage), OpenAI (GPT-4-based evaluation), Google Sheets (position mapping + result log
Consultants, agencies, freelancers, and project managers who want to ensure proposals, emails, and tasks are followed up on time.
> by Thomas Vie Thomas@pollup.net