This workflow corresponds to n8n.io template #5965 — we link there as the canonical source.
This workflow follows the Agent → 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 →
{
"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
}
]
]
}
}
}
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.
gmailOAuth2mcpClientApiopenAiApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow contains community nodes that are only compatible with the self-hosted version of n8n.
Source: https://n8n.io/workflows/5965/ — 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.
Note: This template is for self-hosted n8n instances only
This workflow contains community nodes that are only compatible with the self-hosted version of n8n.
This workflow automatically monitors social media advertising performance across platforms to track campaign effectiveness and ROI. It saves you time by eliminating the need to manually check multiple
This workflow automatically monitors competitor pricing across multiple products and services to track market positioning and pricing strategies. It saves you time by eliminating the need to manually
This workflow contains community nodes that are only compatible with the self-hosted version of n8n.