This workflow corresponds to n8n.io template #10325 — we link there as the canonical source.
This workflow follows the Google Sheets → Slack 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 →
{
"id": "FpblHtpWHqFmqzwu",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Automate Inactive Deal Cleanup from GoHighLevel to Slack and Sheets",
"tags": [],
"nodes": [
{
"id": "a30f842e-09db-4524-bb2a-f6fb696cd818",
"name": "Workflow Description",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1408,
-96
],
"parameters": {
"color": 4,
"width": 386,
"height": 400,
"content": "## \ud83c\udfaf Workflow Overview\n\nThis workflow automatically identifies and archives inactive deals in HighLevel CRM pipelines.\n\n**What it does:**\n- Runs daily to check all opportunities\n- Filters deals with no activity for 10+ days\n- Archives inactive deals automatically\n- Logs all actions to Google Sheets\n- Sends summary report to Slack\n\n**Business Value:**\n- Keeps pipelines clean and focused\n- Prevents lost opportunities from cluttering views\n- Maintains audit trail in Google Sheets\n- Team visibility via Slack notifications"
},
"typeVersion": 1
},
{
"id": "0558197c-899a-470f-93b0-131da334b0f7",
"name": "Schedule Setup",
"type": "n8n-nodes-base.stickyNote",
"position": [
-992,
-400
],
"parameters": {
"width": 282,
"height": 311,
"content": "## \u23f0 Schedule Configuration\n\n**Current:** Runs daily at 9 AM\n\n**To modify:**\n1. Click this node\n2. Adjust cron expression\n3. Common patterns:\n - Every 6 hours: `0 */6 * * *`\n - Twice daily: `0 9,17 * * *`\n - Weekdays only: `0 9 * * 1-5`"
},
"typeVersion": 1
},
{
"id": "86b8ca02-40c9-4f1d-8192-8c076eb62bc6",
"name": "Daily at 9 AM",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-800,
-64
],
"parameters": {
"rule": {
"interval": [
{}
]
}
},
"typeVersion": 1.2
},
{
"id": "860e1aca-04f7-4001-a58b-d2fa695da3e1",
"name": "HighLevel Configuration",
"type": "n8n-nodes-base.stickyNote",
"position": [
-688,
112
],
"parameters": {
"width": 264,
"height": 274,
"content": "## \ud83d\udcca HighLevel Setup\n\n**Required:**\n- OAuth2 credentials configured\n- Location ID in credential settings\n\n**This fetches:**\n- All opportunities from your account\n- Includes contact data\n- No pagination limit issues"
},
"typeVersion": 1
},
{
"id": "9d54a579-e7b9-4d02-a1cd-58f76ebf4c73",
"name": "Fetch All Opportunities",
"type": "n8n-nodes-base.highLevel",
"position": [
-576,
-64
],
"parameters": {
"filters": {},
"resource": "opportunity",
"operation": "getAll",
"requestOptions": {}
},
"credentials": {
"highLevelOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "6f31695d-a18d-46c1-aa00-3ce68013db10",
"name": "Filter Logic",
"type": "n8n-nodes-base.stickyNote",
"position": [
-496,
-384
],
"parameters": {
"width": 262,
"height": 296,
"content": "## \ud83d\udd0d Inactivity Filter\n\n**Logic:**\n- Calculates days since last activity\n- Uses `last_activity_at` or `updatedAt`\n- Threshold: **10 days**\n\n**To adjust threshold:**\nChange `10` in the rightValue field\n- 7 days = more aggressive\n- 14 days = more lenient"
},
"typeVersion": 1
},
{
"id": "09134267-b553-4979-9be3-d3e74e263b74",
"name": "Filter Deals Inactive 10+ Days",
"type": "n8n-nodes-base.filter",
"position": [
-352,
-64
],
"parameters": {
"options": {},
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"operator": {
"type": "number",
"operation": "gt"
},
"leftValue": "={{ Math.floor((new Date() - new Date($json.lastActionDate || $json.updatedAt)) / (1000 * 60 * 60 * 24)) }}",
"rightValue": 10
}
]
}
},
"typeVersion": 2
},
{
"id": "b9dd983f-bbba-4956-85fd-d3813997f27b",
"name": "Archive Configuration",
"type": "n8n-nodes-base.stickyNote",
"position": [
-192,
112
],
"parameters": {
"width": 254,
"height": 264,
"content": "## \ud83d\udce6 Archive Action\n\n**What happens:**\n- Updates opportunity status\n- Marks as archived/closed\n- Preserves all deal data\n\n**Note:** Configure the `status` field in updateFields to match your HighLevel setup (e.g., \"archived\", \"lost\", \"closed\")"
},
"typeVersion": 1
},
{
"id": "dc7991c7-79ad-48a3-b79d-d8359afa4d8c",
"name": "Archive Inactive Deal",
"type": "n8n-nodes-base.highLevel",
"position": [
-128,
-64
],
"parameters": {
"resource": "opportunity",
"operation": "update",
"updateFields": {
"status": "archived"
},
"opportunityId": "={{ $json.id }}",
"requestOptions": {}
},
"credentials": {
"highLevelOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "7f905180-3a1a-4b6f-b049-438b49d50929",
"name": "Processing Logic",
"type": "n8n-nodes-base.stickyNote",
"position": [
48,
-288
],
"parameters": {
"width": 256,
"height": 296,
"content": "## \ud83e\uddee Data Processing\n\n**Transforms deal data:**\n- Calculates days inactive\n- Extracts contact info\n- Formats for Google Sheets\n- Adds metadata fields\n\n**Output fields:**\nid, name, contactName, daysSinceActivity, monetaryValue, source, tags"
},
"typeVersion": 1
},
{
"id": "7fe4471f-287d-4319-8ab0-02f245d9c8f2",
"name": "Format Deal Data",
"type": "n8n-nodes-base.code",
"position": [
112,
32
],
"parameters": {
"jsCode": "// Process and format inactive deal data for logging\nconst formattedData = $input.all().map(item => {\n const opp = item.json;\n const lastActivity = new Date(opp.lastActionDate || opp.updatedAt);\n const daysSinceActivity = Math.floor((Date.now() - lastActivity) / (1000 * 60 * 60 * 24));\n \n return {\n json: {\n id: opp.id,\n name: opp.name,\n pipelineId: opp.pipelineId,\n pipelineStageId: opp.pipelineStageId,\n contactId: opp.contactId,\n contactName: opp.contact?.name || 'N/A',\n lastActionDate: opp.lastActionDate,\n updatedAt: opp.updatedAt,\n daysSinceActivity: daysSinceActivity,\n isInactive: daysSinceActivity > 10,\n monetaryValue: opp.monetaryValue || 0,\n source: opp.source || 'Unknown',\n tags: Array.isArray(opp.contact?.tags) ? opp.contact.tags.join(', ') : '',\n archivedAt: new Date().toISOString()\n }\n };\n});\n\nreturn formattedData;"
},
"typeVersion": 2
},
{
"id": "909dfef7-0703-4893-9465-e806445e492e",
"name": "Sheets Configuration",
"type": "n8n-nodes-base.stickyNote",
"position": [
368,
224
],
"parameters": {
"width": 278,
"height": 346,
"content": "## \ud83d\udccb Google Sheets Setup\n\n**Required:**\n1. Create Google Sheet\n2. Add sheet named \"Inactive Pipeliner\"\n3. Connect OAuth2 credential\n4. Replace documentId below\n\n**Columns auto-created:**\nid, name, contactName, daysSinceActivity, monetaryValue, source, tags, archivedAt"
},
"typeVersion": 1
},
{
"id": "046731cb-c515-4430-ba58-f75b46797401",
"name": "Log to Google Sheets",
"type": "n8n-nodes-base.googleSheets",
"position": [
400,
64
],
"parameters": {
"columns": {
"value": {},
"schema": [
{
"id": "id",
"type": "string",
"display": true,
"required": false,
"displayName": "id",
"defaultMatch": true,
"canBeUsedToMatch": true
},
{
"id": "name",
"type": "string",
"display": true,
"required": false,
"displayName": "name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "contactName",
"type": "string",
"display": true,
"required": false,
"displayName": "contactName",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "daysSinceActivity",
"type": "string",
"display": true,
"required": false,
"displayName": "daysSinceActivity",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "monetaryValue",
"type": "string",
"display": true,
"required": false,
"displayName": "monetaryValue",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "source",
"type": "string",
"display": true,
"required": false,
"displayName": "source",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "tags",
"type": "string",
"display": true,
"required": false,
"displayName": "tags",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "archivedAt",
"type": "string",
"display": true,
"required": false,
"displayName": "archivedAt",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "autoMapInputData",
"matchingColumns": [
"id"
]
},
"options": {},
"operation": "appendOrUpdate",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "Inactive Pipeliner"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Workflow Description').item.json.sheetId }}"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "3a9b90d5-901f-4dd8-a118-cf76b3da61f5",
"name": "Slack Setup",
"type": "n8n-nodes-base.stickyNote",
"position": [
576,
-304
],
"parameters": {
"width": 246,
"height": 328,
"content": "## \ud83d\udcac Slack Notification\n\n**Setup:**\n1. Connect Slack OAuth2\n2. Select your channel\n3. Remove hardcoded channel ID\n\n**Message includes:**\n- Total archived count\n- Sum of monetary values\n- List of deal names"
},
"typeVersion": 1
},
{
"id": "e1acc249-b80a-4d7d-aa63-b6265b641170",
"name": "Send Slack Report",
"type": "n8n-nodes-base.slack",
"position": [
432,
-128
],
"parameters": {
"text": "=:bookmark_tabs: *Inactive Pipeline Cleaner Report*\n\n*Date:* {{ $now.format('MMMM dd, yyyy') }}\n*Total Deals Archived:* {{ $json.count }}\n*Total Monetary Value:* ${{ $json.totalValue.toLocaleString() }}\n\n*Archived Deals:*\n{{ $json.dealsList.split(',').map((deal, idx) => `${idx + 1}. ${deal.trim()}`).join('\\n') }}",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Workflow Description').item.json.slackChannel }}"
},
"otherOptions": {}
},
"credentials": {
"slackApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "5d204940-94de-4c34-8521-884e2f4345f8",
"connections": {
"Daily at 9 AM": {
"main": [
[
{
"node": "Fetch All Opportunities",
"type": "main",
"index": 0
}
]
]
},
"Format Deal Data": {
"main": [
[
{
"node": "Log to Google Sheets",
"type": "main",
"index": 0
},
{
"node": "Send Slack Report",
"type": "main",
"index": 0
}
]
]
},
"Archive Inactive Deal": {
"main": [
[
{
"node": "Format Deal Data",
"type": "main",
"index": 0
}
]
]
},
"Fetch All Opportunities": {
"main": [
[
{
"node": "Filter Deals Inactive 10+ Days",
"type": "main",
"index": 0
}
]
]
},
"Filter Deals Inactive 10+ Days": {
"main": [
[
{
"node": "Archive Inactive Deal",
"type": "main",
"index": 0
}
]
]
}
}
}
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.
googleSheetsOAuth2ApihighLevelOAuth2ApislackApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Keep your CRM pipeline clean and actionable by automatically archiving inactive deals, logging results to Google Sheets, and sending Slack summary reports. This workflow ensures your sales team focuses on active opportunities while maintaining full audit visibility. 🚀📈 Triggers…
Source: https://n8n.io/workflows/10325/ — 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 workflow continuously monitors the TikTok Ads Library for new creatives from specific advertisers or keyword searches, scrapes them via Apify, logs them into Google Sheets, and sends concise noti
This workflow contains community nodes that are only compatible with the self-hosted version of n8n.
Simplify financial oversight with this automated n8n workflow. Triggered daily, it fetches cash flow and expense data from a Google Sheet, analyzes inflows and outflows, validates records, and generat
This workflow is essential for e-commerce store owners, product strategists, and marketing teams who need real-time insight into what their competitors are selling.
This weekly workflow automatically discovers new high-volume, ranked keywords for your domain on Google without manual SERP monitoring. On each run, the workflow fetches the latest ranking and search