Weekly cash flow summary on Telegram

Every Sunday, see money in, money out, net and your biggest expenses of the week on Telegram.

Easy Saves ~2 hours/month Finance & AdminBy Flowngn team

Works with n8n · Make · Zapier

How it works

Trigger: Schedule — Sundays at 8:00
  1. Read the Ledger sheet (date, type, amount, category).
  2. Add up the last 7 days of income and expenses.
  3. Send in, out, net and the top 3 expenses to Telegram.

Diagram

Sundays 8:00Schedule TriggerGRead ledgerGoogle Sheets{ }Money in and outCodeTSend to TelegramTelegram
Trigger App Code

Code

JavaScript used in the Code step — already included in the template below.

Money in and out · Code node
// Ledger sheet columns: date (YYYY-MM-DD) | type (income/expense) | amount | category | description
// Sums the last 7 days of money in and out, with the biggest expenses.
const since = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().slice(0, 10);
const num = (v) => Number(String(v).replace(/[^0-9.-]/g, "")) || 0;
const fmt = (n) => n.toLocaleString("en-US", { maximumFractionDigits: 0 });

const rows = $input.all().map((item) => item.json).filter((r) => String(r.date).slice(0, 10) >= since);
const income = rows.filter((r) => /income/i.test(r.type)).reduce((s, r) => s + num(r.amount), 0);
const expenses = rows.filter((r) => /expense/i.test(r.type));
const out = expenses.reduce((s, r) => s + num(r.amount), 0);
const top = expenses
  .sort((a, b) => num(b.amount) - num(a.amount))
  .slice(0, 3)
  .map((r) => `• ${fmt(num(r.amount))} ${r.category || ""}: ${r.description || ""}`.trim());

return [{
  json: {
    message:
      `💰 Last 7 days\nIn: ${fmt(income)}\nOut: ${fmt(out)}\nNet: ${income - out >= 0 ? "+" : ""}${fmt(income - out)}` +
      (top.length ? `\n\nBiggest expenses:\n${top.join("\n")}` : ""),
  },
}];

Build it

Pick your tool — same automation, step by step.

Copy and paste straight into an n8n canvas (Ctrl+V), or download and use Import from File. Then connect your own credentials and replace every YOUR_… placeholder.

Workflow JSON
Show code (137 lines)
{
  "name": "Weekly cash flow summary on Telegram (Flowngn)",
  "nodes": [
    {
      "parameters": {
        "content": "## Weekly cash flow summary on Telegram\nEvery Sunday, see money in, money out, net and your biggest expenses of the week on Telegram.\n\n**Setup**\n1. Open each node and connect your own credentials.\n2. Replace every YOUR_… placeholder.\n3. Test once, then activate.\n\nFree template from Flowngn",
        "height": 260,
        "width": 340
      },
      "id": "3f36aaf0-8bb5-49c1-a1a3-cee797bc05e2",
      "name": "Setup notes",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -420,
        -60
      ]
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 8 * * 0"
            }
          ]
        }
      },
      "id": "3f36aaf0-8bb5-49c1-a1a3-cee797bc05e2",
      "name": "Sundays 8:00",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        0,
        0
      ]
    },
    {
      "parameters": {
        "operation": "read",
        "documentId": {
          "__rl": true,
          "value": "YOUR_SPREADSHEET_ID",
          "mode": "id"
        },
        "sheetName": {
          "__rl": true,
          "value": "Ledger",
          "mode": "name"
        },
        "options": {}
      },
      "id": "3f36aaf0-8bb5-49c1-a1a3-cee797bc05e2",
      "name": "Read ledger",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [
        300,
        0
      ]
    },
    {
      "parameters": {
        "jsCode": "// Ledger sheet columns: date (YYYY-MM-DD) | type (income/expense) | amount | category | description\n// Sums the last 7 days of money in and out, with the biggest expenses.\nconst since = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().slice(0, 10);\nconst num = (v) => Number(String(v).replace(/[^0-9.-]/g, \"\")) || 0;\nconst fmt = (n) => n.toLocaleString(\"en-US\", { maximumFractionDigits: 0 });\n\nconst rows = $input.all().map((item) => item.json).filter((r) => String(r.date).slice(0, 10) >= since);\nconst income = rows.filter((r) => /income/i.test(r.type)).reduce((s, r) => s + num(r.amount), 0);\nconst expenses = rows.filter((r) => /expense/i.test(r.type));\nconst out = expenses.reduce((s, r) => s + num(r.amount), 0);\nconst top = expenses\n  .sort((a, b) => num(b.amount) - num(a.amount))\n  .slice(0, 3)\n  .map((r) => `• ${fmt(num(r.amount))} ${r.category || \"\"}: ${r.description || \"\"}`.trim());\n\nreturn [{\n  json: {\n    message:\n      `💰 Last 7 days\\nIn: ${fmt(income)}\\nOut: ${fmt(out)}\\nNet: ${income - out >= 0 ? \"+\" : \"\"}${fmt(income - out)}` +\n      (top.length ? `\\n\\nBiggest expenses:\\n${top.join(\"\\n\")}` : \"\"),\n  },\n}];"
      },
      "id": "3f36aaf0-8bb5-49c1-a1a3-cee797bc05e2",
      "name": "Money in and out",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        600,
        0
      ]
    },
    {
      "parameters": {
        "chatId": "YOUR_CHAT_ID",
        "text": "={{ $json.message }}",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "id": "3f36aaf0-8bb5-49c1-a1a3-cee797bc05e2",
      "name": "Send to Telegram",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        900,
        0
      ]
    }
  ],
  "connections": {
    "Sundays 8:00": {
      "main": [
        [
          {
            "node": "Read ledger",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read ledger": {
      "main": [
        [
          {
            "node": "Money in and out",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Money in and out": {
      "main": [
        [
          {
            "node": "Send to Telegram",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "tags": []
}

Open in the playground to edit →

Tips

  • Works with the same Ledger sheet as the bookkeeping agent.

Related flows