{
  "id": "JC8NHUFMRr3Ss4U1",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "22 Monitor Churn Indicators",
  "tags": [],
  "nodes": [
    {
      "id": "25d6648a-74f7-46eb-afb9-d2e305373165",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        380,
        280
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "42614abe-c0a6-4149-b0cc-96dbe6cade08",
      "name": "Daily Check Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -60,
        0
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 9
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "f2f3dcdf-00d8-46ac-951a-4c1a7c964068",
      "name": "Set Admin Dashboard URL",
      "type": "n8n-nodes-base.set",
      "position": [
        140,
        0
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "c07e5c58-b422-4384-85a5-a8049080f8f9",
              "name": "database",
              "type": "string",
              "value": "https://docs.google.com/spreadsheets/YOUR_AWS_SECRET_KEY_HERE?gid=1026450716#gid=1026450716"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "2f224d5a-e0c7-4651-80de-b298e4cf5f5a",
      "name": "Scrape User Data (AI Agent)",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        440,
        0
      ],
      "parameters": {
        "text": "=scrape the database URL below and extract the data.\nURL: {{ $json.database }}",
        "options": {},
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 2
    },
    {
      "id": "c9eab14a-dd60-4a99-aa61-5a42fb9f7a72",
      "name": "Bright Data MCP Client",
      "type": "n8n-nodes-mcp.mcpClientTool",
      "position": [
        580,
        280
      ],
      "parameters": {
        "toolName": "scrape_as_markdown",
        "operation": "executeTool",
        "toolParameters": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Tool_Parameters', ``, 'json') }}"
      },
      "credentials": {
        "mcpClientApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "ea714fc5-b2cc-44dd-821e-2beaa818937e",
      "name": "Format User Login Data",
      "type": "n8n-nodes-base.code",
      "position": [
        780,
        0
      ],
      "parameters": {
        "jsCode": "// 1\ufe0f\u20e3 Get the input array from the agent response\nconst users = items[0].json.output;\n\n// 2\ufe0f\u20e3 Map each user to an individual n8n item\nconst output = users.map(user => {\n  return {\n    json: {\n      name: user.name,\n      email: user.email,\n      last_login: user.last_login,\n      plan: user.plan\n    }\n  };\n});\n\n// 3\ufe0f\u20e3 Return the output array with each user as separate item\nreturn output;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "598f0e1b-e8d7-47c6-ba60-d390151359f1",
      "name": "Convert Date to Days Since Login",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        960,
        0
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini",
          "cachedResultName": "GPT-4O-MINI"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "content": "=I will provide you with a last login date in YYYY-MM-DD format.\n\nPlease calculate the number of days between that date and today, and respond only with:\n\n<number_of_days>\n\nFor example, if the last login date is 2024-06-01, and today is 2024-07-01, then reply:\n\n30\n\nHere is the last login date: {{ $json.last_login }}\n"
            }
          ]
        }
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.8
    },
    {
      "id": "6ace5da5-be7e-4b65-9b03-87460b040dd5",
      "name": "Convert Days to Integer",
      "type": "n8n-nodes-base.set",
      "position": [
        1280,
        0
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "45b3fe33-21b3-4ece-ac05-e9bd693ae035",
              "name": "message.content",
              "type": "number",
              "value": "={{ $json.message.content }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "7cd275d8-32e8-4b66-8b3b-4b9fbaff6f7c",
      "name": "Check Inactive Threshold (>=30 days)",
      "type": "n8n-nodes-base.if",
      "position": [
        1680,
        0
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "a52ad37c-cc43-44a0-8018-9f7ef657a974",
              "operator": {
                "type": "number",
                "operation": "gte"
              },
              "leftValue": "={{ $json.message.content }}",
              "rightValue": 30
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "d960ebcd-7571-4bad-9940-a89cd5b96b94",
      "name": "Send Re-engagement Email",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1920,
        -140
      ],
      "parameters": {
        "sendTo": "={{ $('Format User Login Data').item.json.email }}",
        "message": "=We are missing you.\n\nYou haven't visited our application from a while. So we just wanted to reach out in case there is some problems.\n\nWe would like you to come back.\n\nKind regards,\nTeam [company name]",
        "options": {},
        "subject": "We are missing you, we have an offer for you",
        "emailType": "text"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "88a609e0-e60b-47d5-9da8-28302a4e3a4d",
      "name": "Do Nothing (User Active)",
      "type": "n8n-nodes-base.noOp",
      "position": [
        1920,
        140
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "66cc00e8-e9c9-454f-b600-ecc771e57ca3",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -80,
        -680
      ],
      "parameters": {
        "color": 6,
        "width": 360,
        "height": 860,
        "content": "## \ud83e\udde9 **Section 1: Trigger & Dashboard Input**\n\n**\ud83d\udd01 Schedule Trigger** \u2192 **\ud83d\udcdd Edit Fields**\n\n### \ud83d\udd39 What Happens Here:\n\n* **\u23f0 Schedule Trigger** runs the workflow automatically (e.g., daily).\n* **\ud83d\udcdd Edit Fields** manually sets the URL of the admin dashboard containing user data.\n\n### \ud83d\udca1 Beginner Tip:\n\nThis section starts everything. You define *where* the user data lives by setting the dashboard URL. You don\u2019t need coding\u2014just copy-paste the dashboard URL.\n\n### \ud83d\udd27 Icons Summary:\n\n* \u23f0 **Schedule Trigger** = Starts the automation\n* \u270f\ufe0f **Edit Fields** = Inputs the dashboard URL\n\n---\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "9d74403a-fd7d-41c1-b866-91ff1fdc0fa2",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        400,
        -720
      ],
      "parameters": {
        "color": 3,
        "width": 1040,
        "height": 900,
        "content": "## \ud83e\udd16 **Section 2: AI-Powered Scraping & Date Transformation**\n\n**\ud83e\udde0 AI Agent + MCP Client** \u2192 **{} Code** \u2192 **OpenAI Message Model** \u2192 **\ud83d\udcdd Edit Fields1**\n\n### \ud83d\udd39 What Happens Here:\n\n* **\ud83e\udd16 AI Agent** uses Bright Data MCP to scrape user data from the URL (like last login info).\n* **\ud83e\udde9 MCP Client + Structured Output Parser** help the agent fetch and structure the scraped data.\n* **{} Code Node** formats this data and isolates the `last_login_date` (e.g., \"2024-06-01\").\n* **\ud83e\udde0 OpenAI Message Model** is used smartly to convert `\"2024-06-01\"` into `\"30\"` (number of days since last login).\n* **\ud83d\udcdd Edit Fields1** converts the data type from string to integer.\n\n### \ud83d\udca1 Beginner Tip:\n\nYou're combining **web scraping with AI** here. Even if you don\u2019t know code, the AI agent and OpenAI node are doing the heavy lifting\u2014transforming raw dates into meaningful values.\n\n### \ud83d\udd27 Icons Summary:\n\n* \ud83e\udd16 **AI Agent** = Fetches the data\n* \ud83d\udedc **MCP Client** = Connects to Bright Data\u2019s mobile proxy\n* \ud83e\udde9 **Structured Parser** = Makes scraped data usable\n* {} **Code Node** = Cleans and prepares the data\n* \ud83e\udde0 **OpenAI** = Converts date to \u201cdays ago\u201d\n* \u270f\ufe0f **Edit Fields1** = Converts to a number\n\n---\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "ba433321-f29a-4f05-beb0-7a2943c7e362",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1640,
        -540
      ],
      "parameters": {
        "color": 5,
        "width": 400,
        "height": 860,
        "content": "## \u2709\ufe0f **Section 3: Smart Notification Logic**\n\n**\u2696\ufe0f IF Node** \u2192 **\ud83d\udce7 Gmail** OR **\u27a1\ufe0f No Operation**\n\n### \ud83d\udd39 What Happens Here:\n\n* **\u2696\ufe0f IF Node** checks if the number of days since last login is **greater than or equal to 30**.\n* If **True** \u27a1\ufe0f send an email using **\ud83d\udce7 Gmail Node**.\n* If **False** \u27a1\ufe0f just **do nothing** with **\u27a1\ufe0f No Operation Node**.\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "4422fbed-c696-4511-80ef-4a6eca6c9f64",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2180,
        -540
      ],
      "parameters": {
        "color": 7,
        "width": 380,
        "height": 240,
        "content": "## I\u2019ll receive a tiny commission if you join Bright Data through this link\u2014thanks for fueling more free content!\n\n### https://get.brightdata.com/1tndi4600b25"
      },
      "typeVersion": 1
    },
    {
      "id": "07a48184-3a1b-4756-8d79-b552df19a45d",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1740,
        -640
      ],
      "parameters": {
        "color": 4,
        "width": 1300,
        "height": 320,
        "content": "=======================================\n            WORKFLOW ASSISTANCE\n=======================================\nFor any questions or support, please contact:\n    Yaron@nofluff.online\n\nExplore more tips and tutorials here:\n   - YouTube: https://www.youtube.com/@YaronBeen/videos\n   - LinkedIn: https://www.linkedin.com/in/yaronbeen/\n=======================================\n"
      },
      "typeVersion": 1
    },
    {
      "id": "07f592f8-0aac-4817-9c6f-5c62325b794b",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1740,
        -300
      ],
      "parameters": {
        "color": 4,
        "width": 1289,
        "height": 2278,
        "content": "# \u2705 **Workflow Title: Inactive User Detection & Re-engagement Email Automation**\n\n---\n\n## \ud83e\udde9 **Section 1: Trigger & Dashboard Input**\n\n**\ud83d\udd01 Schedule Trigger** \u2192 **\ud83d\udcdd Edit Fields**\n\n### \ud83d\udd39 What Happens Here:\n\n* **\u23f0 Schedule Trigger** runs the workflow automatically (e.g., daily).\n* **\ud83d\udcdd Edit Fields** manually sets the URL of the admin dashboard containing user data.\n\n### \ud83d\udca1 Beginner Tip:\n\nThis section starts everything. You define *where* the user data lives by setting the dashboard URL. You don\u2019t need coding\u2014just copy-paste the dashboard URL.\n\n### \ud83d\udd27 Icons Summary:\n\n* \u23f0 **Schedule Trigger** = Starts the automation\n* \u270f\ufe0f **Edit Fields** = Inputs the dashboard URL\n\n---\n\n## \ud83e\udd16 **Section 2: AI-Powered Scraping & Date Transformation**\n\n**\ud83e\udde0 AI Agent + MCP Client** \u2192 **{} Code** \u2192 **OpenAI Message Model** \u2192 **\ud83d\udcdd Edit Fields1**\n\n### \ud83d\udd39 What Happens Here:\n\n* **\ud83e\udd16 AI Agent** uses Bright Data MCP to scrape user data from the URL (like last login info).\n* **\ud83e\udde9 MCP Client + Structured Output Parser** help the agent fetch and structure the scraped data.\n* **{} Code Node** formats this data and isolates the `last_login_date` (e.g., \"2024-06-01\").\n* **\ud83e\udde0 OpenAI Message Model** is used smartly to convert `\"2024-06-01\"` into `\"30\"` (number of days since last login).\n* **\ud83d\udcdd Edit Fields1** converts the data type from string to integer.\n\n### \ud83d\udca1 Beginner Tip:\n\nYou're combining **web scraping with AI** here. Even if you don\u2019t know code, the AI agent and OpenAI node are doing the heavy lifting\u2014transforming raw dates into meaningful values.\n\n### \ud83d\udd27 Icons Summary:\n\n* \ud83e\udd16 **AI Agent** = Fetches the data\n* \ud83d\udedc **MCP Client** = Connects to Bright Data\u2019s mobile proxy\n* \ud83e\udde9 **Structured Parser** = Makes scraped data usable\n* {} **Code Node** = Cleans and prepares the data\n* \ud83e\udde0 **OpenAI** = Converts date to \u201cdays ago\u201d\n* \u270f\ufe0f **Edit Fields1** = Converts to a number\n\n---\n\n## \u2709\ufe0f **Section 3: Smart Notification Logic**\n\n**\u2696\ufe0f IF Node** \u2192 **\ud83d\udce7 Gmail** OR **\u27a1\ufe0f No Operation**\n\n### \ud83d\udd39 What Happens Here:\n\n* **\u2696\ufe0f IF Node** checks if the number of days since last login is **greater than or equal to 30**.\n* If **True** \u27a1\ufe0f send an email using **\ud83d\udce7 Gmail Node**.\n* If **False** \u27a1\ufe0f just **do nothing** with **\u27a1\ufe0f No Operation Node**.\n\n### \ud83d\udca1 Beginner Tip:\n\nThis section automates your decision-making! You\u2019re now reaching out only to **inactive users**\u2014this is powerful for **re-engagement**.\n\n### \ud83d\udd27 Icons Summary:\n\n* \u2696\ufe0f **If Node** = Makes the decision\n* \ud83d\udce7 **Gmail** = Sends the message\n* \u27a1\ufe0f **No Operation** = Ignores the user if they recently logged in\n\n---\n\n## \ud83c\udf1f **Real-World Use Case**\n\nThis workflow is **perfect for SaaS applications**. It helps:\n\n* Detect users who haven't logged in recently\n* Alert or re-engage them with tailored emails\n* Maintain active user base and reduce churn\n\n---\n\n## \ud83e\udde0 How Can a Beginner Take Advantage?\n\n1. **No coding? No problem.** Just update the URL in the Edit Fields node.\n2. Customize the **email message** inside the Gmail node.\n3. Schedule this to run **daily/weekly** to automatically track user inactivity.\n4. Connect this to a **CRM** or **Google Sheets** to log alerts.\n\n---\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "b943feef-921c-4958-a656-b64ef489822b",
      "name": "Auto-fixing Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserAutofixing",
      "position": [
        740,
        280
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "7026ca7f-f4d3-4d15-920a-ce84a3da578d",
      "name": "OpenAI Chat Model1",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        720,
        500
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "c4772d37-4e51-48e2-b8aa-2b47f1b25503",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        880,
        500
      ],
      "parameters": {
        "jsonSchemaExample": "[\n  {\n    \"name\": \"User 1\",\n    \"email\": \"user@example.com\",\n    \"last_login\": \"2024-06-01\",\n    \"plan\": \"Pro\"\n  },\n  {\n    \"name\": \"User 2\",\n    \"email\": \"user@example.com\",\n    \"last_login\": \"2024-05-20\",\n    \"plan\": \"Free\"\n  },\n  {\n    \"name\": \"User 3\",\n    \"email\": \"user@example.com\",\n    \"last_login\": \"2024-04-15\",\n    \"plan\": \"Enterprise\"\n  },\n  {\n    \"name\": \"User 4\",\n    \"email\": \"user@example.com\",\n    \"last_login\": \"2024-07-01\",\n    \"plan\": \"Pro\"\n  },\n  {\n    \"name\": \"User 5\",\n    \"email\": \"user@example.com\",\n    \"last_login\": \"2024-03-25\",\n    \"plan\": \"Free\"\n  },\n  {\n    \"name\": \"User 6\",\n    \"email\": \"user@example.com\",\n    \"last_login\": \"2024-05-10\",\n    \"plan\": \"Enterprise\"\n  },\n  {\n    \"name\": \"User 7\",\n    \"email\": \"user@example.com\",\n    \"last_login\": \"2024-06-20\",\n    \"plan\": \"Pro\"\n  },\n  {\n    \"name\": \"User 8\",\n    \"email\": \"user@example.com\",\n    \"last_login\": \"2024-04-05\",\n    \"plan\": \"Free\"\n  },\n  {\n    \"name\": \"User 9\",\n    \"email\": \"user@example.com\",\n    \"last_login\": \"2024-05-30\",\n    \"plan\": \"Enterprise\"\n  },\n  {\n    \"name\": \"User 10\",\n    \"email\": \"user@example.com\",\n    \"last_login\": \"2024-03-15\",\n    \"plan\": \"Pro\"\n  }\n]\n"
      },
      "typeVersion": 1.2
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "3590dd60-19d3-4b24-98e0-c6e495a0b9c0",
  "connections": {
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Scrape User Data (AI Agent)",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "Auto-fixing Output Parser",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Daily Check Trigger": {
      "main": [
        [
          {
            "node": "Set Admin Dashboard URL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Bright Data MCP Client": {
      "ai_tool": [
        [
          {
            "node": "Scrape User Data (AI Agent)",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Format User Login Data": {
      "main": [
        [
          {
            "node": "Convert Date to Days Since Login",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Convert Days to Integer": {
      "main": [
        [
          {
            "node": "Check Inactive Threshold (>=30 days)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Admin Dashboard URL": {
      "main": [
        [
          {
            "node": "Scrape User Data (AI Agent)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Auto-fixing Output Parser",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Auto-fixing Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Scrape User Data (AI Agent)",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Scrape User Data (AI Agent)": {
      "main": [
        [
          {
            "node": "Format User Login Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Convert Date to Days Since Login": {
      "main": [
        [
          {
            "node": "Convert Days to Integer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Inactive Threshold (>=30 days)": {
      "main": [
        [
          {
            "node": "Send Re-engagement Email",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Do Nothing (User Active)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}