AutomationFlowsEmail & Gmail › Weekly Client Re-engagement System with Gohighlevel, Gmail, Sheets, and Slack

Weekly Client Re-engagement System with Gohighlevel, Gmail, Sheets, and Slack

ByRahul Joshi @rahul08 on n8n.io

Automatically identify clients who haven’t been contacted in 14+ days and re-engage them with personalized Gmail follow-up emails, Google Sheets tracking, and Slack notifications for account managers. Prevents churn by ensuring no client goes unnoticed. 💌📊💬 Triggers every Monday…

Cron / scheduled trigger★★★★☆ complexity23 nodesHigh LevelGmailGoogle SheetsSlackError Trigger
Email & Gmail Trigger: Cron / scheduled Nodes: 23 Complexity: ★★★★☆ Added:

This workflow corresponds to n8n.io template #9237 — we link there as the canonical source.

This workflow follows the Error Trigger → Gmail 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 →

Download .json
{
  "id": "W1BO1coWaTTtuCrC",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Weekly Client Engagement Automation with GoHighLevel, Gmail, Slack, and Sheets",
  "tags": [],
  "nodes": [
    {
      "id": "5152120f-eb1c-4741-a0c4-c6073fb3403c",
      "name": "Workflow Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -784,
        -256
      ],
      "parameters": {
        "color": 4,
        "width": 387,
        "height": 609,
        "content": "## \ud83d\udccb Weekly Client Engagement Pulse\n\nThis workflow automatically identifies clients who haven't been contacted in 14+ days and sends:\n- \u2709\ufe0f Automated follow-up email to inactive clients\n- \ud83d\udcca Google Sheets log for tracking\n- \ud83d\udcac Slack notification to account managers\n\n**Runs:** Every Monday at 9:00 AM\n\n**What it does:**\n1. Fetches all contacts from HighLevel CRM\n2. Filters contacts inactive for 14+ days\n3. Sends personalized re-engagement email\n4. Logs to Google Sheets\n5. Notifies team via Slack\n6. Handles errors gracefully\n\n**Setup Time:** ~10 minutes\n\n---\n\n### \ud83c\udfaf Use Case\nPerfect for agencies, consultants, and service businesses who need to maintain regular client touchpoints and prevent churn."
      },
      "typeVersion": 1
    },
    {
      "id": "adf66a9e-7cb9-4fef-b345-4c13abcbaa9e",
      "name": "Note: Schedule Trigger",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -336,
        -400
      ],
      "parameters": {
        "color": 5,
        "width": 340,
        "height": 380,
        "content": "## \u23f0 Schedule Trigger Node\n\n**What it does:**\nAutomatically runs this workflow every Monday at 9:00 AM.\n\n**Cron Expression:** `0 9 * * 1`\n- `0` = Minute (0)\n- `9` = Hour (9 AM)\n- `*` = Any day of month\n- `*` = Any month\n- `1` = Monday (0=Sunday, 1=Monday)\n\n**Customization Examples:**\n- Daily at 9 AM: `0 9 * * *`\n- Every 4 hours: `0 */4 * * *`\n- Weekdays at 2 PM: `0 14 * * 1-5`\n\n**Testing:**\nClick \"Test workflow\" button to run manually before enabling schedule."
      },
      "typeVersion": 1
    },
    {
      "id": "7c5340fa-e80a-4db7-953e-8b3b31b2536f",
      "name": "Note: HighLevel Fetch",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        32,
        -384
      ],
      "parameters": {
        "color": 5,
        "width": 340,
        "height": 380,
        "content": "## \ud83d\udd17 HighLevel CRM Node\n\n**What it does:**\nFetches ALL contacts from your HighLevel CRM.\n\n**Setup Steps:**\n1. Click \"Create New Credential\"\n2. Select \"HighLevel OAuth2 API\"\n3. Authorize access to your CRM\n4. Select location if needed\n\n**Operation:** Get Many Contacts\n**Sorting:** By `date_updated` (most recent first)\n\n**Output:**\nReturns all contact data including:\n- Contact names, emails, phones\n- Company information\n- Tags and custom fields\n- Date added/updated timestamps\n\n**Note:** No filters applied here - filtering happens in next node."
      },
      "typeVersion": 1
    },
    {
      "id": "6037ea36-f052-483b-b6e9-ec4e8399c64c",
      "name": "Note: Filter Logic",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        416,
        -416
      ],
      "parameters": {
        "color": 5,
        "width": 340,
        "height": 380,
        "content": "## \ud83d\udd0d Filter Inactive Contacts\n\n**What it does:**\nIdentifies contacts with NO activity in the last 14 days.\n\n**Logic:**\n```javascript\n// Calculate 14 days ago\nconst fourteenDaysAgo = new Date();\nfourteenDaysAgo.setDate(fourteenDaysAgo.getDate() - 14);\n\n// Check if last activity is older\nif (lastActivityDate < fourteenDaysAgo) {\n  // Flag as needs attention\n}\n```\n\n**Uses These Fields:**\n- `dateUpdated` (preferred) or\n- `dateAdded` (fallback)\n\n**Adds:**\n- `daysSinceContact` = calculated days\n- `needsAttention` = true flag\n- `lastContactDate` = timestamp\n\n**Customize:** Change `14` to any number of days."
      },
      "typeVersion": 1
    },
    {
      "id": "94f2604f-359d-4b62-9d12-3c11cfe3dfe6",
      "name": "Note: Split Array",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        304,
        320
      ],
      "parameters": {
        "color": 5,
        "width": 340,
        "height": 572,
        "content": "## \ud83d\udce4 Split Out Node\n\n**What it does:**\nConverts array of contacts into individual items (one per contact).\n\n**Why needed:**\nThe filter node returns an array. We need to process each contact separately for:\n- Individual emails\n- Google Sheets row insertion\n- Per-contact logic\n\n**Fields Split:**\nAll contact fields including:\n- contactName, firstName, lastName\n- email, phone, address\n- tags, dates, IDs\n- needsAttention flag\n\n**Output:**\nEach contact becomes a separate execution item.\n\n**Example:**\nArray of 5 contacts \u2192 5 separate items flowing through workflow."
      },
      "typeVersion": 1
    },
    {
      "id": "f09969ea-72a8-4651-bcf9-4a57a1ca404a",
      "name": "Note: Condition Check",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        656,
        384
      ],
      "parameters": {
        "color": 5,
        "width": 340,
        "height": 572,
        "content": "## \u2753 IF Condition Node\n\n**What it does:**\nDouble-checks that contact truly needs attention.\n\n**Condition:**\n```\nneedsAttention === true\n```\n\n**Why needed:**\nSafety check to ensure only flagged contacts proceed to:\n- Email sending\n- Google Sheets logging\n- Slack notifications\n\n**True Branch:**\nContact gets email + logged\n\n**False Branch:**\nContact is skipped (no action)\n\n**Best Practice:**\nAlways validate critical flags before taking action like sending emails."
      },
      "typeVersion": 1
    },
    {
      "id": "661b394d-2dc8-4ff9-8d4d-eff137b18c4f",
      "name": "Note: Email Sender",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        784,
        -464
      ],
      "parameters": {
        "color": 5,
        "width": 340,
        "height": 412,
        "content": "## \ud83d\udce7 Gmail Send Email Node\n\n**What it does:**\nSends personalized re-engagement email to inactive client.\n\n**Setup:**\n1. Connect Gmail OAuth2 credential\n2. Replace `YOUR_RECIPIENT_EMAIL@example.com` with:\n   - `{{ $json.email }}` for dynamic recipient\n3. Customize subject and HTML template\n\n**Dynamic Fields Available:**\n- `{{ $json.firstName }}` - First name\n- `{{ $json.lastName }}` - Last name\n- `{{ $json.companyName }}` - Company\n- `{{ $json.daysSinceContact }}` - Days\n\n**Email Template:**\nProfessional HTML with:\n- Gradient header\n- Personalized greeting\n- Call-to-action button\n- Responsive design\n\n**Customize:**\n- Change colors/branding\n- Edit copy\n- Add your logo"
      },
      "typeVersion": 1
    },
    {
      "id": "2e2f7125-ae70-49a3-815e-cf332e9cc468",
      "name": "Note: Google Sheets Logger",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1216,
        -176
      ],
      "parameters": {
        "color": 5,
        "width": 340,
        "height": 420,
        "content": "## \ud83d\udcca Google Sheets Log Node\n\n**What it does:**\nAppends each inactive contact to tracking spreadsheet.\n\n**Setup Required:**\n1. Create Google Sheet with columns:\n   - id, contactName, firstName, lastName\n   - email, phone, companyName, address1\n   - dateAdded, dateUpdated, lastContactDate\n   - needsAttention, tags\n\n2. Connect Google Sheets OAuth2\n3. Select your spreadsheet\n4. Select sheet name (e.g., \"Client Engagement\")\n5. Enable \"Auto-map input data\"\n\n**Operation:** Append\n**Matching Column:** `id` (prevents duplicates)\n\n**Purpose:**\n- Audit trail of all re-engagement attempts\n- Historical tracking\n- Reporting and analytics\n\n**Pro Tip:** Add a timestamp column for when logged."
      },
      "typeVersion": 1
    },
    {
      "id": "187ea926-1dc1-4a44-b200-59242193544d",
      "name": "Note: Message Formatter",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1088,
        432
      ],
      "parameters": {
        "color": 5,
        "width": 340,
        "height": 676,
        "content": "## \ud83d\udd04 Format Slack Message\n\n**What it does:**\nAggregates all inactive contacts and formats a summary message.\n\n**Processing:**\n1. Loops through all contacts\n2. Handles null lastName values\n3. Extracts key info (name, email, days)\n4. Creates bulleted list\n\n**Output Format:**\n```\n\ud83d\udea8 Weekly Client Engagement Pulse\n\n5 clients need attention:\n\n\u2022 John Doe (john@example.com) - 18 days\n\u2022 Jane Smith (jane@example.com) - 22 days\n...\n```\n\n**Variables Created:**\n- `count` = number of clients\n- `clientList` = formatted bullet list\n- `clients` = array of client objects\n\n**Customization:**\nEdit JavaScript to change format or add fields."
      },
      "typeVersion": 1
    },
    {
      "id": "67e28ac0-5c86-4f24-8cba-e7dca6b353a8",
      "name": "Note: Slack Notifier",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1440,
        336
      ],
      "parameters": {
        "color": 5,
        "width": 340,
        "height": 676,
        "content": "## \ud83d\udcac Slack Notification Node\n\n**What it does:**\nSends summary report to account managers via Slack.\n\n**Setup:**\n1. Create Slack app or use OAuth2\n2. Install to workspace\n3. Select channel (e.g., #client-engagement)\n4. Authorize permissions:\n   - `chat:write`\n   - `channels:read`\n\n**Message Includes:**\n- \ud83d\udea8 Alert emoji for visibility\n- Total count of inactive clients\n- Formatted list with:\n  - Client names\n  - Email addresses\n  - Days since last contact\n- Call to action\n\n**Markdown Enabled:** Yes\n\n**Best Practice:**\nCreate dedicated channel like:\n- `#client-engagement`\n- `#account-management`\n- `#crm-alerts`"
      },
      "typeVersion": 1
    },
    {
      "id": "10d80719-f5c3-46e0-adff-f932f9a7eb98",
      "name": "Note: Error Trigger",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -560,
        560
      ],
      "parameters": {
        "color": 5,
        "width": 340,
        "height": 420,
        "content": "## \ud83d\udea8 Error Trigger Node\n\n**What it does:**\nAutomatically catches ANY error in this workflow.\n\n**Triggers When:**\n- API connection fails\n- Authentication expires\n- Rate limits hit\n- Invalid data format\n- Network timeouts\n- Any node throws error\n\n**Captures:**\n- `node.name` = which node failed\n- `error.message` = error description\n- `timestamp` = when it happened\n- Full error stack trace\n\n**Why Critical:**\nWithout this, workflow fails silently and you don't know:\n- Emails weren't sent\n- Clients weren't tracked\n- System is broken\n\n**Best Practice:**\nALWAYS include error handling in production workflows."
      },
      "typeVersion": 1
    },
    {
      "id": "0f7d2301-2dd7-4f24-8580-38b7e5c19ccc",
      "name": "Note: Error Alerting",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -80,
        608
      ],
      "parameters": {
        "color": 5,
        "width": 340,
        "height": 420,
        "content": "## \ud83d\udce2 Error Alert to Slack\n\n**What it does:**\nImmediately notifies team when workflow breaks.\n\n**Message Format:**\n```\n\u274c Workflow Error: Weekly Client Engagement Pulse\n\nNode: [Node Name]\nError: [Error Message]\nTime: 2025-01-15 09:23:45\n\nPlease investigate immediately.\n```\n\n**Setup:**\n1. Use same Slack credential\n2. Select channel for errors:\n   - `#errors`\n   - `#n8n-monitoring`\n   - `#devops-alerts`\n\n**Dynamic Values:**\n- `{{ $json.node.name }}` = failed node\n- `{{ $json.error.message }}` = error text\n- `{{ $now.format() }}` = timestamp\n\n**Pro Tip:**\nSet up Slack notifications to phone for critical errors."
      },
      "typeVersion": 1
    },
    {
      "id": "5b9c5442-0ba8-4501-9adb-701b4166863d",
      "name": "Trigger: Weekly Scheduler",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -240,
        144
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 9 * * 1"
            }
          ]
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "8dd6f18c-dff9-409b-b83d-336722d28b2d",
      "name": "Fetch HighLevel Contacts",
      "type": "n8n-nodes-base.highLevel",
      "position": [
        -16,
        144
      ],
      "parameters": {
        "filters": {},
        "options": {
          "sortBy": "date_updated"
        },
        "operation": "getAll",
        "requestOptions": {}
      },
      "credentials": {
        "highLevelOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "1bd6795e-3915-420a-9f72-c05b0c788e89",
      "name": "Filter Inactive Contacts (14+ days)",
      "type": "n8n-nodes-base.code",
      "position": [
        208,
        144
      ],
      "parameters": {
        "jsCode": "const fourteenDaysAgo = new Date();\nfourteenDaysAgo.setDate(fourteenDaysAgo.getDate() - 14);\n\nconst inactiveContacts = [];\n\nfor (const item of $input.all()) {\n  const contact = item.json;\n  const lastActivity = contact.dateUpdated || contact.dateAdded;\n  const lastActivityDate = new Date(lastActivity);\n  \n  if (lastActivityDate < fourteenDaysAgo) {\n    inactiveContacts.push({\n      json: {\n        ...contact,\n        daysSinceContact: Math.floor((new Date() - lastActivityDate) / (1000 * 60 * 60 * 24)),\n        lastContactDate: lastActivity,\n        needsAttention: true\n      }\n    });\n  }\n}\n\nreturn inactiveContacts;"
      },
      "typeVersion": 2
    },
    {
      "id": "bc7bab6f-c83f-4bfa-878c-0beea381686e",
      "name": "Split Clients Array",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        432,
        144
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "contactName, firstName, lastName, companyName, email, phone, address1, dateUpdated, dateAdded, id, tags, lastContactDate, needsAttention"
      },
      "typeVersion": 1
    },
    {
      "id": "24b870ce-2065-4719-bc24-8c37be738046",
      "name": "IF: Needs Attention",
      "type": "n8n-nodes-base.if",
      "position": [
        656,
        144
      ],
      "parameters": {
        "conditions": {
          "boolean": [
            {
              "value1": "={{ $json.needsAttention }}",
              "value2": true
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "65a984e9-6140-4c5e-8411-4081e3207684",
      "name": "Send Re-engagement Email",
      "type": "n8n-nodes-base.gmail",
      "position": [
        880,
        48
      ],
      "parameters": {
        "sendTo": "={{ $json.email }}",
        "message": "=<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>Check-in Email</title>\n</head>\n<body style=\"margin: 0; padding: 0; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background-color: #f4f4f4;\">\n    <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"background-color: #f4f4f4; padding: 40px 0;\">\n        <tr>\n            <td align=\"center\">\n                <table width=\"600\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); overflow: hidden;\">\n                    <tr>\n                        <td style=\"background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 30px; text-align: center;\">\n                            <h1 style=\"margin: 0; color: #ffffff; font-size: 24px; font-weight: 600;\">We're Thinking of You! \ud83d\udcad</h1>\n                        </td>\n                    </tr>\n                    <tr>\n                        <td style=\"padding: 40px 30px;\">\n                            <p style=\"margin: 0 0 20px 0; font-size: 16px; color: #333333; line-height: 1.6;\">\n                                Hi <strong>{{ $json.firstName || 'there' }}</strong>,\n                            </p>\n                            <p style=\"margin: 0 0 20px 0; font-size: 16px; color: #555555; line-height: 1.6;\">\n                                Hope everything's going well! We noticed it's been a while since we last connected.\n                            </p>\n                            <p style=\"margin: 0 0 20px 0; font-size: 16px; color: #555555; line-height: 1.6;\">\n                                Is there anything we can help you with? We're always here to support you.\n                            </p>\n                            <table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"margin: 30px 0;\">\n                                <tr>\n                                    <td align=\"center\" style=\"border-radius: 4px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\">\n                                        <a href=\"mailto:support@yourcompany.com\" style=\"display: inline-block; padding: 14px 32px; color: #ffffff; text-decoration: none; font-size: 16px; font-weight: 600;\">Get in Touch</a>\n                                    </td>\n                                </tr>\n                            </table>\n                            <p style=\"margin: 0; font-size: 16px; color: #555555; line-height: 1.6;\">\n                                Looking forward to hearing from you!\n                            </p>\n                            <p style=\"margin: 20px 0 0 0; font-size: 16px; color: #555555; line-height: 1.6;\">\n                                Best regards,<br>\n                                <strong>Your Team</strong>\n                            </p>\n                        </td>\n                    </tr>\n                    <tr>\n                        <td style=\"background-color: #f8f9fa; padding: 20px 30px; text-align: center; border-top: 1px solid #e9ecef;\">\n                            <p style=\"margin: 0; font-size: 14px; color: #6c757d;\">\n                                \u00a9 2025 Your Company. All rights reserved.\n                            </p>\n                        </td>\n                    </tr>\n                </table>\n            </td>\n        </tr>\n    </table>\n</body>\n</html>",
        "options": {},
        "subject": "Just Checking In!"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "22c49b1c-b43a-4a34-99c0-0e93e2f3df7a",
      "name": "Log Inactive Client in Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        880,
        240
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [
            {
              "id": "contactName",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "contactName",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "firstName",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "firstName",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "lastName",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "lastName",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "companyName",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "companyName",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "email",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "phone",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "phone",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "address1",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "address1",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "dateUpdated",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "dateUpdated",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "dateAdded",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "dateAdded",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "id",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "id",
              "defaultMatch": true,
              "canBeUsedToMatch": true
            },
            {
              "id": "lastContactDate",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "lastContactDate",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "needsAttention",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "needsAttention",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "tags",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "tags",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [
            "id"
          ]
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "Sheet1",
          "cachedResultName": "Client Engagement"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_GOOGLE_SHEET_ID",
          "cachedResultName": "Client Engagement Tracking"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4
    },
    {
      "id": "a1ba79ab-323f-4710-bfce-22ec818e568f",
      "name": "Format Slack Message",
      "type": "n8n-nodes-base.code",
      "position": [
        1104,
        240
      ],
      "parameters": {
        "jsCode": "const clients = $input.all().map(item => {\n  const data = item.json;\n  const fullName = data.lastName ? `${data.firstName} ${data.lastName}` : data.firstName || data.contactName;\n  const lastContact = new Date(data.lastContactDate);\n  const today = new Date();\n  const daysSinceContact = Math.floor((today - lastContact) / (1000 * 60 * 60 * 24));\n  return {\n    name: fullName,\n    email: data.email || 'No email',\n    company: data.companyName || 'No company',\n    phone: data.phone || 'No phone',\n    daysSinceContact: daysSinceContact\n  };\n});\n\nconst clientList = clients.map(c => `\u2022 ${c.name} (${c.email}) - ${c.daysSinceContact} days since last contact`).join('\\n');\n\nreturn {\n  json: {\n    count: clients.length,\n    clientList: clientList,\n    clients: clients\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "7d64a0f4-6c39-4ce1-bd23-ca1d4706effe",
      "name": "Send Slack Notification to Account Manager",
      "type": "n8n-nodes-base.slack",
      "position": [
        1328,
        240
      ],
      "parameters": {
        "text": "=\ud83d\udea8 *Weekly Client Engagement Pulse*\n\n*{{ $json.count }}* clients need attention (no contact in 14+ days):\n\n{{ $json.clientList }}\n\nPlease review and follow up accordingly.",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_SLACK_CHANNEL_ID",
          "cachedResultName": "client-engagement"
        },
        "otherOptions": {
          "mrkdwn": true
        }
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "13d74e9a-9687-4d20-bbf4-e6df8d3f2744",
      "name": "Error Trigger",
      "type": "n8n-nodes-base.errorTrigger",
      "position": [
        -240,
        464
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "26fe07d2-e839-406c-b2b7-cf85dde3a998",
      "name": "Send Error Alert to Slack",
      "type": "n8n-nodes-base.slack",
      "position": [
        -16,
        464
      ],
      "parameters": {
        "text": "=\u274c *Workflow Error: Weekly Client Engagement Pulse*\n\n*Node:* {{ $json.node.name }}\n*Error:* {{ $json.error.message }}\n*Time:* {{ $now.format('yyyy-MM-dd HH:mm:ss') }}\n\nPlease investigate immediately.",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_SLACK_CHANNEL_ID",
          "cachedResultName": "errors"
        },
        "otherOptions": {}
      },
      "typeVersion": 2.1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "53e0ed29-a751-4a7e-a92a-5414ebac3321",
  "connections": {
    "Error Trigger": {
      "main": [
        [
          {
            "node": "Send Error Alert to Slack",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF: Needs Attention": {
      "main": [
        [
          {
            "node": "Send Re-engagement Email",
            "type": "main",
            "index": 0
          },
          {
            "node": "Log Inactive Client in Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Clients Array": {
      "main": [
        [
          {
            "node": "IF: Needs Attention",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Slack Message": {
      "main": [
        [
          {
            "node": "Send Slack Notification to Account Manager",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch HighLevel Contacts": {
      "main": [
        [
          {
            "node": "Filter Inactive Contacts (14+ days)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Trigger: Weekly Scheduler": {
      "main": [
        [
          {
            "node": "Fetch HighLevel Contacts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter Inactive Contacts (14+ days)": {
      "main": [
        [
          {
            "node": "Split Clients Array",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log Inactive Client in Google Sheets": {
      "main": [
        [
          {
            "node": "Format Slack Message",
            "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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Automatically identify clients who haven’t been contacted in 14+ days and re-engage them with personalized Gmail follow-up emails, Google Sheets tracking, and Slack notifications for account managers. Prevents churn by ensuring no client goes unnoticed. 💌📊💬 Triggers every Monday…

Source: https://n8n.io/workflows/9237/ — original creator credit. Request a take-down →

More Email & Gmail workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Email & Gmail

Streamline client retention and contract renewals by automatically identifying expiring accounts, sending personalized reminder emails, and notifying account managers through Slack. This workflow ensu

High Level, Gmail, Slack +1
Email & Gmail

This powerful n8n workflow automatically processes, categorizes, and organizes your Gmail inbox using customizable rules stored in Google Sheets. Say goodbye to manual email sorting and hello to a per

Gmail, Google Sheets, Slack
Email & Gmail

This workflow automatically monitors solar energy production every 2 hours by fetching data from the Energidataservice API. If the energy output falls below a predefined threshold, it instantly notifi

HTTP Request, Gmail, Google Sheets +1
Email & Gmail

This workflow is an automated invoice payment tracking and reminder system for the Polish accounting service iFirma.pl. It monitors unpaid and overdue invoices, then automatically sends escalating rem

HTTP Request, Stop And Error, Slack +1
Email & Gmail

Automatically extract structured information from emails using AI-powered document analysis. This workflow processes emails from specified domains, classifies them by type, and extracts structured dat

Gmail, HTTP Request, AWS S3 +1