{
  "id": "WGiTjBBWUXkklgZq",
  "name": "Automate rent reminders and late rent alerts with AI, Google Sheets, Gmail and Telegram",
  "tags": [],
  "nodes": [
    {
      "id": "7f601d5c-7523-4d6a-b76f-1dcb953fd8b3",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        0
      ],
      "parameters": {
        "width": 480,
        "height": 896,
        "content": "## Automate rent reminders and late rent alerts with AI, Google Sheets, Gmail and Telegram\n\n### How it works\n\nThis workflow automates rent collection follow-ups using two scheduled paths. A daily path reads tenant ledger data from Google Sheets, checks for overdue rent, uses an AI agent to draft reminders, sends valid reminders through Gmail, logs the action, and alerts the landlord on Telegram when escalation is needed. A weekly path summarizes ledger information with AI and sends the collection report by Gmail and Telegram.\n\n### Setup steps\n\n- Configure Google Sheets credentials and point the ledger read and log append nodes to the correct spreadsheet, worksheets, and column names.\n- Configure Gmail credentials for both tenant reminder emails and weekly summary emails, including sender account and recipient fields.\n- Configure Telegram bot credentials and chat IDs for ledger issue alerts, AI failure alerts, landlord escalation alerts, and weekly summary delivery.\n- Configure OpenAI credentials for the reminder and summary AI model nodes, and review the prompts/fields expected by each AI agent.\n- Set the daily and weekly schedule trigger times to match the rent reminder cadence and reporting schedule.\n\n### Customization\n\nAdjust the overdue and escalation IF conditions, AI prompt wording, Gmail subject/body templates, Telegram message text, and Google Sheets columns to match the property manager\u2019s rent policy and ledger format."
      },
      "typeVersion": 1
    },
    {
      "id": "a5e7c548-8012-4046-a5d5-fb7166973094",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        560,
        224
      ],
      "parameters": {
        "color": 7,
        "width": 864,
        "height": 400,
        "content": "## Daily ledger intake\n\nStarts the daily reminder run, reads the tenant ledger from Google Sheets, verifies the read succeeded, and sends a Telegram alert if the ledger cannot be processed."
      },
      "typeVersion": 1
    },
    {
      "id": "2e4ce2f4-9de9-4cbc-9a1d-3c813acbbeff",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1456,
        80
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 336,
        "content": "## Tenant overdue filter\n\nNormalizes tenant fields such as name, unit, rent amount, and email, then checks whether the tenant is overdue and should receive a reminder."
      },
      "typeVersion": 1
    },
    {
      "id": "4d048f32-0e63-492d-82a0-d032943b1a7c",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1904,
        96
      ],
      "parameters": {
        "color": 7,
        "width": 544,
        "height": 528,
        "content": "## AI reminder drafting\n\nUses the OpenAI-backed reminder agent to generate a rent reminder, then extracts structured reminder fields such as stage, subject, body, and tenant name."
      },
      "typeVersion": 1
    },
    {
      "id": "8d2c98c8-1d40-49c8-9e6e-81b473329539",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2480,
        0
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 512,
        "content": "## Draft validation and send\n\nValidates the AI-generated draft, sends valid reminder emails through Gmail, and routes invalid AI output to a Telegram failure alert."
      },
      "typeVersion": 1
    },
    {
      "id": "8525b0e9-ec3f-4637-8e61-87a6a4d135bc",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2928,
        0
      ],
      "parameters": {
        "color": 7,
        "width": 640,
        "height": 320,
        "content": "## Reminder log escalation\n\nAppends the sent reminder to the Google Sheets log, checks whether the case needs escalation, and notifies the landlord on Telegram when required."
      },
      "typeVersion": 1
    },
    {
      "id": "5bde2294-eef8-4db9-8905-18b8bdc591c5",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        560,
        656
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 320,
        "content": "## Weekly ledger intake\n\nStarts the weekly reporting path and reads the same ledger data from Google Sheets for summary generation."
      },
      "typeVersion": 1
    },
    {
      "id": "2cbf8363-165b-4e95-b011-b706557204a6",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1008,
        656
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 320,
        "content": "## Weekly collection aggregation\n\nBuilds tenant-level summary lines and aggregates collection metrics for the weekly rent report."
      },
      "typeVersion": 1
    },
    {
      "id": "137a7a0d-54fd-40d5-8ab1-a96d531e8c6f",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1456,
        656
      ],
      "parameters": {
        "color": 7,
        "width": 544,
        "height": 512,
        "content": "## AI summary writing\n\nUses the OpenAI-backed summary agent to turn the aggregated rent collection data into a written report and extracts the final report text."
      },
      "typeVersion": 1
    },
    {
      "id": "359316f4-e55c-4f76-a6a7-631270861b2e",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2032,
        656
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 320,
        "content": "## Weekly summary delivery\n\nSends the weekly rent collection summary by Gmail and then posts the same summary to Telegram."
      },
      "typeVersion": 1
    },
    {
      "id": "2f770ac5-aaeb-4e0a-83d1-b3ccec9d50f8",
      "name": "When Daily Reminder Due",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        608,
        352
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 8 * * *"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "c243d891-1d4c-4481-94a0-7a5b86404154",
      "name": "Read Ledger from Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        832,
        352
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "TenantLedger"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "1RWc76RE-LvYOwbOdbYti2nVcZyOtoVu-Bgw5WrBJ9nQ"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "0824f04b-8b43-4b10-a918-069b0b3a34ef",
      "name": "Check Ledger Read Success",
      "type": "n8n-nodes-base.if",
      "position": [
        1056,
        352
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "v1",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              },
              "leftValue": "={{ $json.tenant_name }}",
              "rightValue": ""
            },
            {
              "id": "v2",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              },
              "leftValue": "={{ $json.email }}",
              "rightValue": ""
            },
            {
              "id": "v3",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              },
              "leftValue": "={{ $json.due_day }}",
              "rightValue": ""
            },
            {
              "id": "v4",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              },
              "leftValue": "={{ $json.rent_amount }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "087e770f-35f1-404b-a7de-1c0bb51e1e74",
      "name": "Notify Ledger Issue Telegram",
      "type": "n8n-nodes-base.telegram",
      "position": [
        1280,
        448
      ],
      "parameters": {
        "text": "={{ 'Rent reminder sweep skipped: tenant ' + ($json.tenant_name || 'unknown') + ' is missing a required field (tenant name, email, due day or rent amount). Please fix the TenantLedger sheet row and rerun.' }}",
        "chatId": "123456789",
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "a04b1858-f1c8-4c59-8d70-062e1b1d3bf4",
      "name": "Set Tenant Information",
      "type": "n8n-nodes-base.set",
      "position": [
        1504,
        256
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "n1",
              "name": "tenant_name",
              "type": "string",
              "value": "={{ $json.tenant_name }}"
            },
            {
              "id": "n2",
              "name": "unit",
              "type": "string",
              "value": "={{ $json.unit }}"
            },
            {
              "id": "n3",
              "name": "rent_amount",
              "type": "string",
              "value": "={{ $json.rent_amount }}"
            },
            {
              "id": "n4",
              "name": "email",
              "type": "string",
              "value": "={{ $json.email }}"
            },
            {
              "id": "n5",
              "name": "due_day",
              "type": "string",
              "value": "={{ $json.due_day }}"
            },
            {
              "id": "n6",
              "name": "status",
              "type": "string",
              "value": "={{ $json.status || 'unpaid' }}"
            },
            {
              "id": "n7",
              "name": "reminder_stage",
              "type": "string",
              "value": "={{ $json.reminder_stage || 'none' }}"
            },
            {
              "id": "n8",
              "name": "due_date",
              "type": "string",
              "value": "={{ $now.set({ day: parseInt($json.due_day, 10) || 1 }).toISODate() }}"
            },
            {
              "id": "n9",
              "name": "days_overdue",
              "type": "number",
              "value": "={{ Math.floor($now.diff($now.set({ day: parseInt($json.due_day, 10) || 1 }).startOf('day'), 'days').days) }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "1d95b4e3-e4d9-40c2-aaef-b437f5f9904c",
      "name": "Check Rent Overdue",
      "type": "n8n-nodes-base.if",
      "position": [
        1728,
        256
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "o1",
              "operator": {
                "type": "number",
                "operation": "gte"
              },
              "leftValue": "={{ $json.days_overdue }}",
              "rightValue": 0
            },
            {
              "id": "o2",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $json.status }}",
              "rightValue": "paid"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "3a9895cf-76d8-430a-bcf2-d4acfaff2e9d",
      "name": "AI Rent Reminder Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1952,
        256
      ],
      "parameters": {
        "text": "={{ 'Draft a rent reminder email for this tenant. Tenant details: ' + JSON.stringify($json) + '. The rent was due on ' + $json.due_date + ' and is ' + $json.days_overdue + ' day(s) overdue. Choose the reminder stage: gentle (0 to 4 days overdue), firm (5 to 9 days overdue) or final (10 or more days overdue). Match the tone of the body to the stage: gentle is a friendly nudge, firm is polite but clear that payment is expected soon, final is a clear and urgent notice. Return ONLY valid JSON with keys: stage (string), subject (string), body (string, max 60 words).' }}",
        "options": {
          "systemMessage": "You are a rent collection assistant for a small landlord. Write polite, professional reminder emails that make it easy for tenants to pay while keeping the relationship positive. Never threaten or use aggressive language. Always return valid JSON only."
        },
        "promptType": "define"
      },
      "typeVersion": 3.1
    },
    {
      "id": "91eb6406-20be-43da-84ad-dba1d4461632",
      "name": "OpenAI GPT-4 Reminder Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        2256,
        496
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini",
          "cachedResultName": "gpt-4o-mini"
        },
        "options": {
          "temperature": 0.2
        },
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "b409cd2f-bf63-498b-b18c-c7d0cefd0dfd",
      "name": "Build Reminder Details",
      "type": "n8n-nodes-base.set",
      "position": [
        2304,
        256
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "e1",
              "name": "stage",
              "type": "string",
              "value": "={{ JSON.parse(($json.output || '{}').replace(/```json\\n?/g, '').replace(/```/g, '')).stage || '' }}"
            },
            {
              "id": "e2",
              "name": "subject",
              "type": "string",
              "value": "={{ JSON.parse(($json.output || '{}').replace(/```json\\n?/g, '').replace(/```/g, '')).subject || '' }}"
            },
            {
              "id": "e3",
              "name": "body",
              "type": "string",
              "value": "={{ JSON.parse(($json.output || '{}').replace(/```json\\n?/g, '').replace(/```/g, '')).body || '' }}"
            },
            {
              "id": "e4",
              "name": "tenant_name",
              "type": "string",
              "value": "={{ $('Set Tenant Information').item.json.tenant_name }}"
            },
            {
              "id": "e5",
              "name": "unit",
              "type": "string",
              "value": "={{ $('Set Tenant Information').item.json.unit }}"
            },
            {
              "id": "e6",
              "name": "rent_amount",
              "type": "string",
              "value": "={{ $('Set Tenant Information').item.json.rent_amount }}"
            },
            {
              "id": "e7",
              "name": "email",
              "type": "string",
              "value": "={{ $('Set Tenant Information').item.json.email }}"
            },
            {
              "id": "e8",
              "name": "due_date",
              "type": "string",
              "value": "={{ $('Set Tenant Information').item.json.due_date }}"
            },
            {
              "id": "e9",
              "name": "days_overdue",
              "type": "number",
              "value": "={{ $('Set Tenant Information').item.json.days_overdue }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "9b8dd09e-f04c-4ad6-9d8a-d2acd6e279b0",
      "name": "Check Reminder Draft Validity",
      "type": "n8n-nodes-base.if",
      "position": [
        2528,
        256
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "d1",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              },
              "leftValue": "={{ $json.subject }}",
              "rightValue": ""
            },
            {
              "id": "d2",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              },
              "leftValue": "={{ $json.body }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "78145d08-6670-4010-9fda-b4b5382ef649",
      "name": "Notify AI Failure Telegram",
      "type": "n8n-nodes-base.telegram",
      "position": [
        2752,
        352
      ],
      "parameters": {
        "text": "={{ 'Rent reminder could not be drafted for ' + $json.tenant_name + ' (Unit ' + $json.unit + '). The AI output was invalid. Please check the workflow execution log.' }}",
        "chatId": "123456789",
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "fcfe3541-832f-476e-a9f7-eb3c8a83b0fd",
      "name": "Send Rent Reminder Email",
      "type": "n8n-nodes-base.gmail",
      "position": [
        2752,
        160
      ],
      "parameters": {
        "sendTo": "={{ $json.email }}",
        "message": "={{ $json.body }}",
        "options": {},
        "subject": "={{ $json.subject }}",
        "emailType": "text"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "2ddfc6cc-fb26-4acd-a807-801227a8e04e",
      "name": "Log Reminder in Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2976,
        160
      ],
      "parameters": {
        "columns": {
          "value": {
            "unit": "={{ $('Set Tenant Information').item.json.unit }}",
            "stage": "={{ $('Build Reminder Details').item.json.stage }}",
            "email_sent": "yes",
            "rent_amount": "={{ $('Set Tenant Information').item.json.rent_amount }}",
            "tenant_name": "={{ $('Set Tenant Information').item.json.tenant_name }}",
            "days_overdue": "={{ $('Set Tenant Information').item.json.days_overdue }}",
            "reminder_date": "={{ $now.toISODate() }}"
          },
          "schema": [
            {
              "id": "reminder_date",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "reminder_date",
              "defaultMatch": true,
              "canBeUsedToMatch": true
            },
            {
              "id": "tenant_name",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "tenant_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "unit",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "unit",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "rent_amount",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "rent_amount",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "days_overdue",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "days_overdue",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "stage",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "stage",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "email_sent",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "email_sent",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": []
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "ReminderLog"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "1RWc76RE-LvYOwbOdbYti2nVcZyOtoVu-Bgw5WrBJ9nQ"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "5d30b093-0930-43da-ae8d-d6e70256bedf",
      "name": "Check for Escalation",
      "type": "n8n-nodes-base.if",
      "position": [
        3200,
        160
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "s1",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $('Build Reminder Details').item.json.stage }}",
              "rightValue": "firm"
            },
            {
              "id": "s2",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $('Build Reminder Details').item.json.stage }}",
              "rightValue": "final"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "8ec3c466-f93d-4d69-b451-0c240f68e895",
      "name": "Notify Landlord via Telegram",
      "type": "n8n-nodes-base.telegram",
      "position": [
        3424,
        160
      ],
      "parameters": {
        "text": "={{ 'Rent escalation: ' + $('Set Tenant Information').item.json.tenant_name + ' (Unit ' + $('Set Tenant Information').item.json.unit + '), ' + $('Set Tenant Information').item.json.rent_amount + ', ' + $('Set Tenant Information').item.json.days_overdue + ' day(s) overdue, stage ' + $('Build Reminder Details').item.json.stage + '. A reminder email was sent.' }}",
        "chatId": "123456789",
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "6e7977c8-c807-475d-9b5e-168929aa0937",
      "name": "When Weekly Summary Due",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        608,
        816
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 9 * * 1"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "e93133a5-4fb7-4560-9758-dcd048bc2757",
      "name": "Read Weekly Ledger from Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        832,
        816
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "TenantLedger"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "1RWc76RE-LvYOwbOdbYti2nVcZyOtoVu-Bgw5WrBJ9nQ"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "b985d9cc-4842-4a6b-9ea3-15cc3e43ced2",
      "name": "Prepare Tenant Summary Lines",
      "type": "n8n-nodes-base.set",
      "position": [
        1056,
        816
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "t1",
              "name": "tenant_line",
              "type": "string",
              "value": "={{ $json.tenant_name + ' (Unit ' + $json.unit + '): ' + $json.rent_amount + ' | status ' + ($json.status || 'unpaid') + ' | ' + Math.max(0, Math.floor($now.diff($now.set({ day: parseInt($json.due_day, 10) || 1 }).startOf('day'), 'days').days)) + ' day(s) overdue' }}"
            },
            {
              "id": "t2",
              "name": "rent_amount_num",
              "type": "number",
              "value": "={{ parseFloat($json.rent_amount) || 0 }}"
            },
            {
              "id": "t3",
              "name": "unit_count",
              "type": "number",
              "value": "=1"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "f303ef46-b079-46b5-a561-bee0759d91d6",
      "name": "Summarize Rent Collections",
      "type": "n8n-nodes-base.summarize",
      "position": [
        1280,
        816
      ],
      "parameters": {
        "options": {},
        "fieldsToSummarize": {
          "values": [
            {
              "field": "tenant_line",
              "separateBy": "\n",
              "aggregation": "concatenate"
            },
            {
              "field": "rent_amount_num",
              "aggregation": "sum"
            },
            {
              "field": "unit_count",
              "aggregation": "sum"
            }
          ]
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "dc971f84-96b4-48e8-b361-68d907507d8c",
      "name": "AI Weekly Summary Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1504,
        816
      ],
      "parameters": {
        "text": "={{ 'Write a short weekly rent report for the landlord. Tenant ledger lines: ' + $json.concatenated_tenant_line + '. Total units: ' + $json.sum_unit_count + '. Total monthly rent across all units: ' + $json.sum_rent_amount_num + '. From the lines, count how many tenants are paid and how many are unpaid, and name the most overdue tenant. Keep it under 150 words, plain text. Return ONLY valid JSON with key: report (string).' }}",
        "options": {
          "systemMessage": "You are a rent collection assistant for a small landlord. Produce a clear weekly summary of rent collections. Always return valid JSON only."
        },
        "promptType": "define"
      },
      "typeVersion": 3.1
    },
    {
      "id": "e6454773-9d2a-49ee-949a-03f45f6cdd21",
      "name": "OpenAI GPT-4 Summary Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1584,
        1072
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini",
          "cachedResultName": "gpt-4o-mini"
        },
        "options": {
          "temperature": 0.3
        },
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "5bb2b428-e485-4709-ab9c-839437c3b35a",
      "name": "Build Weekly Summary Details",
      "type": "n8n-nodes-base.set",
      "position": [
        1856,
        816
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "r1",
              "name": "report",
              "type": "string",
              "value": "={{ JSON.parse(($json.output || '{}').replace(/```json\\n?/g, '').replace(/```/g, '')).report || $json.output }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "c2b9a633-b08c-4af6-b71b-6d6ca7a0241b",
      "name": "Email Weekly Summary",
      "type": "n8n-nodes-base.gmail",
      "position": [
        2080,
        816
      ],
      "parameters": {
        "message": "={{ $json.report }}",
        "options": {},
        "subject": "Weekly rent collection summary",
        "emailType": "text"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "5cc4d68e-3b38-43e2-bb5f-6c7840609f38",
      "name": "Send Weekly Summary Telegram",
      "type": "n8n-nodes-base.telegram",
      "position": [
        2304,
        816
      ],
      "parameters": {
        "text": "={{ 'Weekly rent summary\\n\\n' + $('Build Weekly Summary Details').item.json.report }}",
        "chatId": "123456789",
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    }
  ],
  "active": false,
  "settings": {
    "timezone": "Asia/Jakarta",
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "versionId": "94a45961-b0e7-4204-ad35-cb1fb8abdd50",
  "nodeGroups": [],
  "connections": {
    "Check Rent Overdue": {
      "main": [
        [
          {
            "node": "AI Rent Reminder Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check for Escalation": {
      "main": [
        [
          {
            "node": "Notify Landlord via Telegram",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Email Weekly Summary": {
      "main": [
        [
          {
            "node": "Send Weekly Summary Telegram",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Rent Reminder Agent": {
      "main": [
        [
          {
            "node": "Build Reminder Details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Reminder Details": {
      "main": [
        [
          {
            "node": "Check Reminder Draft Validity",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log Reminder in Sheets": {
      "main": [
        [
          {
            "node": "Check for Escalation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Tenant Information": {
      "main": [
        [
          {
            "node": "Check Rent Overdue",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Weekly Summary Agent": {
      "main": [
        [
          {
            "node": "Build Weekly Summary Details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read Ledger from Sheets": {
      "main": [
        [
          {
            "node": "Check Ledger Read Success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When Daily Reminder Due": {
      "main": [
        [
          {
            "node": "Read Ledger from Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When Weekly Summary Due": {
      "main": [
        [
          {
            "node": "Read Weekly Ledger from Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Rent Reminder Email": {
      "main": [
        [
          {
            "node": "Log Reminder in Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Ledger Read Success": {
      "main": [
        [
          {
            "node": "Set Tenant Information",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Notify Ledger Issue Telegram",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI GPT-4 Summary Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Weekly Summary Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Summarize Rent Collections": {
      "main": [
        [
          {
            "node": "AI Weekly Summary Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI GPT-4 Reminder Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Rent Reminder Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Build Weekly Summary Details": {
      "main": [
        [
          {
            "node": "Email Weekly Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Tenant Summary Lines": {
      "main": [
        [
          {
            "node": "Summarize Rent Collections",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Reminder Draft Validity": {
      "main": [
        [
          {
            "node": "Send Rent Reminder Email",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Notify AI Failure Telegram",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read Weekly Ledger from Sheets": {
      "main": [
        [
          {
            "node": "Prepare Tenant Summary Lines",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}