Envoi automatisé des rappels de renouvellement client de GoHighLevel vers Gmail et Slack

Avancé

Ceci est unCRMworkflow d'automatisation du domainecontenant 19 nœuds.Utilise principalement des nœuds comme If, Code, Gmail, Merge, Slack. Envoi automatisé de rappels de renouvellement client de GoHighLevel vers Gmail, Slack et Google Sheets

Prérequis
  • Compte Google et informations d'identification Gmail API
  • Token Bot Slack ou URL Webhook
  • Informations d'identification Google Sheets API

Catégorie

Aperçu du workflow
Visualisation des connexions entre les nœuds, avec support du zoom et du déplacement
Exporter le workflow
Copiez la configuration JSON suivante dans n8n pour importer et utiliser ce workflow
{
  "id": "zAhUYo1pPedFF2vq",
  "meta": {
    "instanceId": "8443f10082278c46aa5cf3acf8ff0f70061a2c58bce76efac814b16290845177",
    "templateCredsSetupCompleted": true
  },
  "name": "Automate Client Renewal Alerts from GoHighLevel to Gmail and Slack",
  "tags": [],
  "nodes": [
    {
      "id": "e89a6dcb-42d4-4674-bd3d-2f91b86231b2",
      "name": "Note adhésive",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3120,
        -64
      ],
      "parameters": {
        "color": 4,
        "width": 420,
        "height": 656,
        "content": "## 🔄 Client Retention Renewal Reminder Workflow\n\nAutomatically identifies clients with contracts expiring within 10 days and sends personalized renewal reminders.\n\n### What This Workflow Does:\n- **Runs daily at 9 AM** to check for expiring contracts\n- **Fetches all contacts** from GoHighLevel CRM\n- **Filters clients** whose contracts expire in 0-10 days\n- **Sends renewal emails** to clients via Gmail\n- **Notifies account managers** via Slack\n- **Logs all activities** to Google Sheets for tracking\n\n### Business Benefits:\n- ✅ Never miss a renewal opportunity\n- ✅ Improve client retention rates\n- ✅ Automate manual follow-up tasks\n- ✅ Track renewal campaign effectiveness\n\n### Requirements:\n- GoHighLevel account with custom fields:\n  - Contract End Date field\n  - Account Manager field\n- Gmail account for sending emails\n- Slack workspace for notifications\n- Google Sheets for logging"
      },
      "typeVersion": 1
    },
    {
      "id": "9ffba3e1-2389-47df-8257-708871c6c5e4",
      "name": "Note adhésive 1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2656,
        -208
      ],
      "parameters": {
        "color": 5,
        "width": 280,
        "height": 240,
        "content": "## ⏰ Schedule Trigger Setup\n\nRuns daily at 9:00 AM server time.\n\n**Configuration:**\n- Cron: `0 9 * * *`\n- Frequency: Every day\n- Time: 9:00 AM\n\n**Why 9 AM?**\nEarly morning execution ensures:\n- Emails arrive during business hours\n- Account managers have full day to respond\n- Prevents weekend/holiday issues"
      },
      "typeVersion": 1
    },
    {
      "id": "94e0e170-fe29-42a6-9926-d052fbc28fd5",
      "name": "Planification quotidienne à 9h",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -2560,
        48
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 9 * * *"
            }
          ]
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "05b63bb3-1942-4f24-9d53-3b3f2a25a7f5",
      "name": "Note adhésive 2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2432,
        240
      ],
      "parameters": {
        "color": 5,
        "width": 280,
        "height": 396,
        "content": "## 📥 Fetch Contacts from CRM\n\n**Setup Instructions:**\n1. Connect your GoHighLevel account\n2. Set limit to 50 (or adjust based on needs)\n3. Ensure API permissions include contact read access\n\n**Required Custom Fields:**\n- Contract End Date (Date field)\n- Account Manager (Text field)\n\n**Note:** Increase limit if you have more than 50 active clients"
      },
      "typeVersion": 1
    },
    {
      "id": "5e3e0e62-267e-4728-a4ae-f92581607f06",
      "name": "Récupérer les contacts depuis GoHighLevel",
      "type": "n8n-nodes-base.highLevel",
      "position": [
        -2336,
        48
      ],
      "parameters": {
        "filters": {},
        "options": {},
        "operation": "getAll",
        "requestOptions": {}
      },
      "credentials": {
        "highLevelOAuth2Api": {
          "id": "N9Q1X1RWUjvRIRbt",
          "name": "HighLevel account 2"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "9e665b65-003d-430d-a7f7-48228b7dcad8",
      "name": "Note adhésive 3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2208,
        -272
      ],
      "parameters": {
        "color": 5,
        "width": 260,
        "height": 292,
        "content": "## 🔍 Validate Data Quality\n\nEnsures contacts have custom fields before processing.\n\n**Why This Matters:**\n- Prevents errors in downstream nodes\n- Filters out incomplete contact records\n- Improves workflow reliability"
      },
      "typeVersion": 1
    },
    {
      "id": "eb37756d-3de4-4d63-8215-b4e8520bcb5e",
      "name": "Vérifier les champs personnalisés",
      "type": "n8n-nodes-base.if",
      "position": [
        -2112,
        48
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "58341a8d-2417-47e1-b29b-be575b270c35",
              "operator": {
                "type": "array",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $json.customFields }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "f102174e-cba7-4d13-a322-f2327d9f1449",
      "name": "Note adhésive 4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1936,
        208
      ],
      "parameters": {
        "color": 5,
        "width": 280,
        "height": 404,
        "content": "## 🎯 Filter Expiring Contracts\n\n**Logic:**\n- Finds Contract End Date field\n- Calculates days until expiry\n- Filters: 0-10 days remaining\n\n**Customization:**\nChange `daysUntilExpiry <= 10` to adjust reminder window:\n- 7 days = 1 week notice\n- 14 days = 2 weeks notice\n- 30 days = 1 month notice\n\n**Important:** Update field IDs to match YOUR GoHighLevel custom fields"
      },
      "typeVersion": 1
    },
    {
      "id": "6f9a5a69-8ce9-46c1-88f2-d12a44a3f319",
      "name": "Filtrer les renouvellements (Code)",
      "type": "n8n-nodes-base.code",
      "position": [
        -1888,
        48
      ],
      "parameters": {
        "jsCode": "// Get current date at midnight for accurate day comparison\nconst today = new Date();\ntoday.setHours(0, 0, 0, 0);\n\n// Array to store filtered contacts\nconst filteredContacts = [];\n\n// Process each contact from input\nfor (const contact of $input.all()) {\n  const item = contact.json;\n  \n  // Check if contact has customFields\n  if (!item.customFields || !Array.isArray(item.customFields)) {\n    continue;\n  }\n  \n  // TODO: Replace with YOUR custom field ID for Contract End Date\n  const contractEndField = item.customFields.find(\n    field => field.id === 'YOUR_CONTRACT_END_DATE_FIELD_ID'\n  );\n  \n  // Skip if no contract end date exists\n  if (!contractEndField || !contractEndField.value) {\n    continue;\n  }\n  \n  // Parse contract end date (timestamp in milliseconds)\n  const contractEndDate = new Date(contractEndField.value);\n  contractEndDate.setHours(0, 0, 0, 0);\n  \n  // Calculate days until expiry\n  const daysUntilExpiry = Math.ceil(\n    (contractEndDate - today) / (1000 * 60 * 60 * 24)\n  );\n  \n  // Filter: expires within next 10 days (0-10 days)\n  if (daysUntilExpiry >= 0 && daysUntilExpiry <= 10) {\n    \n    // TODO: Replace with YOUR custom field ID for Account Manager\n    const accountManagerField = item.customFields.find(\n      field => field.id === 'YOUR_ACCOUNT_MANAGER_FIELD_ID'\n    );\n    \n    // Format the contract end date for display\n    const formattedDate = contractEndDate.toLocaleDateString('en-US', {\n      year: 'numeric',\n      month: 'long',\n      day: 'numeric'\n    });\n    \n    // Create enriched contact object\n    filteredContacts.push({\n      json: {\n        // Original contact data\n        id: item.id,\n        contactName: item.contactName,\n        firstName: item.firstName || 'N/A',\n        lastName: item.lastName || 'N/A',\n        email: item.email || 'No email on file',\n        companyName: item.companyName || 'N/A',\n        phone: item.phone,\n        \n        // Contract information\n        contractEndDate: formattedDate,\n        contractEndDateRaw: contractEndDate.toISOString(),\n        contractEndTimestamp: contractEndField.value,\n        daysUntilExpiry: daysUntilExpiry,\n        \n        // Account manager info\n        accountManager: accountManagerField?.value || 'Unassigned',\n        \n        // Additional fields for workflow\n        allCustomFields: item.customFields,\n        tags: item.tags || [],\n        source: item.source\n      }\n    });\n  }\n}\n\n// Return filtered contacts\nreturn filteredContacts;"
      },
      "typeVersion": 2
    },
    {
      "id": "6f7a46e5-115c-4bef-9cc7-e30b96b1b94d",
      "name": "Vérifier expiration sous 10 jours",
      "type": "n8n-nodes-base.filter",
      "position": [
        -1664,
        48
      ],
      "parameters": {
        "conditions": {
          "number": [
            {
              "value1": "={{ $json.daysUntilExpiry }}",
              "value2": 10,
              "operation": "smallerEqual"
            }
          ],
          "string": [
            {
              "value1": "={{ $json.contractEndDate }}",
              "operation": "isNotEmpty"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "3b9392da-852b-4692-bfac-5c177bbda695",
      "name": "Note adhésive 5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1536,
        -400
      ],
      "parameters": {
        "color": 5,
        "width": 280,
        "height": 340,
        "content": "## 📧 Send Client Email\n\n**Setup:**\n1. Connect Gmail account\n2. Replace recipient with: `={{ $json.email }}`\n3. Customize email template\n\n**Email Variables:**\n- `firstName` - Client first name\n- `lastName` - Client last name\n- `contractEndDate` - Formatted expiry date\n- `companyName` - Company name\n\n**Best Practice:** Test email with your own address first"
      },
      "typeVersion": 1
    },
    {
      "id": "17f722d7-781c-41d4-bd15-b84b187df947",
      "name": "Envoyer l'email de renouvellement via Gmail",
      "type": "n8n-nodes-base.gmail",
      "position": [
        -1440,
        -48
      ],
      "webhookId": "c62251a2-e50a-4f59-8e3e-d35403ca9d82",
      "parameters": {
        "sendTo": "={{ $json.email }}",
        "message": "=Hi {{ $json.firstName }} {{ $json.lastName }},\n\nThis is a friendly reminder that your contract with us is set to expire on {{ $json.contractEndDate }}.\n\nWe'd love to continue working with you! Please let us know if you'd like to discuss renewal options.\n\nYour account manager will be reaching out shortly.\n\nBest regards,\nYour Team",
        "options": {},
        "subject": "Important: Your Contract Renewal is Coming Up"
      },
      "typeVersion": 2.1
    },
    {
      "id": "3e716197-e31d-49d9-8c3e-b1ba215bed06",
      "name": "Note adhésive 6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1488,
        304
      ],
      "parameters": {
        "color": 5,
        "width": 280,
        "height": 384,
        "content": "## 📢 Slack Team Notification\n\n**Setup:**\n1. Connect Slack workspace\n2. Select channel for renewal alerts\n3. Customize message format\n\n**Recommended Channels:**\n- #renewals\n- #account-management\n- #sales-alerts\n\n**Note:** Ensure all account managers have access to the selected channel"
      },
      "typeVersion": 1
    },
    {
      "id": "79b9f0dd-1fd1-4562-b93e-99e3bc111aeb",
      "name": "Envoyer l'alerte Slack à l'équipe",
      "type": "n8n-nodes-base.slack",
      "position": [
        -1440,
        144
      ],
      "webhookId": "2d02c3a0-61c7-4742-b2d5-665e3ad8dab8",
      "parameters": {
        "text": "=🔔 *Contract Renewal Alert*\n\n*Client:* {{ $json.firstName }} {{ $json.lastName }}\n*Email:* {{ $json.email }}\n*Company:* {{ $json.companyName || \"N/A\" }}\n*Contract Expires:* {{ $json.contractEndDate }}\n*Days Remaining:* {{ $json.daysUntilExpiry }}\n*Account Manager:* {{ $json.accountManager }}\n\n✅ Renewal email has been sent to client.\n📋 Please follow up within 3 business days.",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_SLACK_CHANNEL_ID",
          "cachedResultName": "Select your renewals channel"
        },
        "otherOptions": {}
      },
      "typeVersion": 2.1
    },
    {
      "id": "f3448850-b573-416a-b34c-8e1e7d985151",
      "name": "Fusionner les résultats email et Slack",
      "type": "n8n-nodes-base.merge",
      "position": [
        -1216,
        48
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combinationMode": "mergeByPosition"
      },
      "typeVersion": 2.1
    },
    {
      "id": "96ae9e61-3ffc-4f04-b6ac-2a58495dc455",
      "name": "Note adhésive 7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1072,
        -272
      ],
      "parameters": {
        "color": 5,
        "width": 260,
        "height": 296,
        "content": "## 📊 Generate Summary Report\n\nCreates execution summary with:\n- Total reminders sent\n- Timestamp of execution\n- Success status\n\n**Used for:**\n- Tracking workflow performance\n- Logging to Google Sheets\n- Debugging issues"
      },
      "typeVersion": 1
    },
    {
      "id": "c61d0e08-0b24-4be6-bbcd-b58de927212a",
      "name": "Générer le rapport récapitulatif",
      "type": "n8n-nodes-base.code",
      "position": [
        -992,
        48
      ],
      "parameters": {
        "jsCode": "const totalReminders = $input.all().length;\nconst timestamp = new Date().toLocaleString();\n\nreturn {\n  json: {\n    summary: `Renewal Reminder Workflow Completed`,\n    totalRemindersSent: totalReminders,\n    timestamp: timestamp,\n    message: `${totalReminders} renewal reminder(s) sent successfully on ${timestamp}`\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "9e39598a-d4f0-43e9-9885-a306371772e1",
      "name": "Note adhésive 8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -752,
        256
      ],
      "parameters": {
        "color": 5,
        "width": 280,
        "height": 268,
        "content": "## 📝 Log to Google Sheets\n\n**Setup:**\n1. Create a Google Sheet for tracking\n2. Add columns: summary, totalRemindersSent, timestamp, message\n3. Connect your Google account\n4. Select your spreadsheet and sheet\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "ace3170b-c470-4458-b601-db08918f1572",
      "name": "Enregistrer les résultats dans Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -768,
        48
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [
            {
              "id": "summary",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "summary",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "totalRemindersSent",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "totalRemindersSent",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "timestamp",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "timestamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "message",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "message",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "autoMapInputData",
          "matchingColumns": []
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "Sheet1",
          "cachedResultName": "Select sheet name"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_GOOGLE_SHEET_ID",
          "cachedResultName": "Select your tracking sheet"
        }
      },
      "typeVersion": 4.7
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "180a6f20-55ff-43e1-bbd0-85e6eebaf0bb",
  "connections": {
    "6f9a5a69-8ce9-46c1-88f2-d12a44a3f319": {
      "main": [
        [
          {
            "node": "6f7a46e5-115c-4bef-9cc7-e30b96b1b94d",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "94e0e170-fe29-42a6-9926-d052fbc28fd5": {
      "main": [
        [
          {
            "node": "5e3e0e62-267e-4728-a4ae-f92581607f06",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "eb37756d-3de4-4d63-8215-b4e8520bcb5e": {
      "main": [
        [
          {
            "node": "6f9a5a69-8ce9-46c1-88f2-d12a44a3f319",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "c61d0e08-0b24-4be6-bbcd-b58de927212a": {
      "main": [
        [
          {
            "node": "ace3170b-c470-4458-b601-db08918f1572",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "79b9f0dd-1fd1-4562-b93e-99e3bc111aeb": {
      "main": [
        [
          {
            "node": "f3448850-b573-416a-b34c-8e1e7d985151",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "17f722d7-781c-41d4-bd15-b84b187df947": {
      "main": [
        [
          {
            "node": "f3448850-b573-416a-b34c-8e1e7d985151",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "f3448850-b573-416a-b34c-8e1e7d985151": {
      "main": [
        [
          {
            "node": "c61d0e08-0b24-4be6-bbcd-b58de927212a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "6f7a46e5-115c-4bef-9cc7-e30b96b1b94d": {
      "main": [
        [
          {
            "node": "17f722d7-781c-41d4-bd15-b84b187df947",
            "type": "main",
            "index": 0
          },
          {
            "node": "79b9f0dd-1fd1-4562-b93e-99e3bc111aeb",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "5e3e0e62-267e-4728-a4ae-f92581607f06": {
      "main": [
        [
          {
            "node": "eb37756d-3de4-4d63-8215-b4e8520bcb5e",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Foire aux questions

Comment utiliser ce workflow ?

Copiez le code de configuration JSON ci-dessus, créez un nouveau workflow dans votre instance n8n et sélectionnez "Importer depuis le JSON", collez la configuration et modifiez les paramètres d'authentification selon vos besoins.

Dans quelles scénarios ce workflow est-il adapté ?

Avancé - CRM

Est-ce payant ?

Ce workflow est entièrement gratuit et peut être utilisé directement. Veuillez noter que les services tiers utilisés dans le workflow (comme l'API OpenAI) peuvent nécessiter un paiement de votre part.

Informations sur le workflow
Niveau de difficulté
Avancé
Nombre de nœuds19
Catégorie1
Types de nœuds10
Description de la difficulté

Adapté aux utilisateurs avancés, avec des workflows complexes contenant 16+ nœuds

Auteur
Rahul Joshi

Rahul Joshi

@rahul08

Rahul Joshi is a seasoned technology leader specializing in the n8n automation tool and AI-driven workflow automation. With deep expertise in building open-source workflow automation and self-hosted automation platforms, he helps organizations eliminate manual processes through intelligent n8n ai agent automation solutions.

Liens externes
Voir sur n8n.io

Partager ce workflow

Catégories

Catégories: 34