{ "id": "w0oJ1i6sESvaB5W1", "name": "⏰ Actual β€” Reminder Estratto Conto [Schedule]", "nodes": [ { "id": "n_cron", "name": "⏰ Cron Giornaliero", "type": "n8n-nodes-base.scheduleTrigger", "typeVersion": 1.2, "position": [ 0, 300 ], "parameters": { "rule": { "interval": [ { "triggerAtHour": 9, "field": "hours" } ] } } }, { "id": "n_verifica", "name": "πŸ“‹ Verifica Task Scaduto", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 240, 300 ], "parameters": { "jsCode": "\nconst TASK_NAME = 'Actual - Estratto conto';\nconst TASKLIST_NAME = 'Finanze';\nconst today = new Date();\ntoday.setHours(0,0,0,0);\n\ntry {\n // Get task lists\n const listsRes = await this.helpers.requestWithAuthentication.call(\n this,\n 'googleCalendarOAuth2Api',\n {\n method: 'GET',\n url: 'https://tasks.googleapis.com/tasks/v1/users/@me/lists',\n json: true\n }\n );\n \n const taskList = (listsRes.items || []).find(l => l.title === TASKLIST_NAME);\n if (!taskList) {\n return [{ json: { send_reminder: false, reason: `Lista \"${TASKLIST_NAME}\" non trovata` } }];\n }\n \n // Get pending tasks\n const tasksRes = await this.helpers.requestWithAuthentication.call(\n this,\n 'googleCalendarOAuth2Api',\n {\n method: 'GET',\n url: `https://tasks.googleapis.com/tasks/v1/lists/${taskList.id}/tasks?showCompleted=false&showHidden=false`,\n json: true\n }\n );\n \n const task = (tasksRes.items || []).find(t => t.title === TASK_NAME && t.status !== 'completed');\n if (!task) {\n return [{ json: { send_reminder: false, reason: 'Task non trovato o giΓ  completato' } }];\n }\n \n // Check if due date is today or past\n let isDue = false;\n let dueInfo = 'nessuna scadenza';\n if (task.due) {\n const dueDate = new Date(task.due);\n dueDate.setHours(0,0,0,0);\n isDue = dueDate <= today;\n dueInfo = task.due.split('T')[0];\n } else {\n // No due date set β€” send reminder anyway (task exists and is not done)\n isDue = true;\n }\n \n return [{ json: {\n send_reminder: isDue,\n task_id: task.id,\n tasklist_id: taskList.id,\n due: dueInfo,\n reason: isDue ? `Task scaduto il ${dueInfo}` : `Task in scadenza il ${dueInfo}`\n } }];\n} catch(e) {\n return [{ json: { send_reminder: false, reason: `Errore Tasks API: ${e.message}` } }];\n}\n", "mode": "runOnceForAllItems" } }, { "id": "n_if_due", "name": "❓ Task Scaduto?", "type": "n8n-nodes-base.if", "typeVersion": 2, "position": [ 480, 300 ], "parameters": { "conditions": { "options": { "caseSensitive": true, "leftValue": "", "typeValidation": "strict" }, "conditions": [ { "id": "cond_due", "leftValue": "={{ $json.send_reminder }}", "rightValue": true, "operator": { "type": "boolean", "operation": "true", "singleValue": true } } ], "combinator": "and" } } }, { "id": "n_reminder", "name": "πŸ“± Reminder Telegram", "type": "n8n-nodes-base.telegram", "typeVersion": 1.2, "position": [ 720, 180 ], "parameters": { "chatId": "-4814221197", "text": "πŸ“Š *Reminder: Estratto Conto*\n\nRicordati di scaricare e caricare l'estratto conto bancario!\n\nMandami il file CSV su Telegram con caption:\n`Estratto conto`\n\n_Il task \"Actual - Estratto conto\" risulta in scadenza β€” sarΓ  marcato completato automaticamente dopo il caricamento._", "additionalFields": { "parse_mode": "Markdown" } }, "credentials": { "telegramApi": { "id": "uTXHLqcCJxbOvqN3", "name": "Telegram account" } } } ], "connections": { "⏰ Cron Giornaliero": { "main": [ [ { "node": "πŸ“‹ Verifica Task Scaduto", "type": "main", "index": 0 } ] ] }, "πŸ“‹ Verifica Task Scaduto": { "main": [ [ { "node": "❓ Task Scaduto?", "type": "main", "index": 0 } ] ] }, "❓ Task Scaduto?": { "main": [ [ { "node": "πŸ“± Reminder Telegram", "type": "main", "index": 0 } ], [] ] } }, "settings": { "executionOrder": "v1", "callerPolicy": "workflowsFromSameOwner", "availableInMCP": false }, "triggerCount": 1, "versionId": "ed54aeb1-f6ad-4605-a102-09e177e6eb9d", "owner": { "type": "personal", "projectId": "Hdttz401OqqtObPo", "projectName": "Martin Tahiraj ", "personalEmail": "tahiraj.martin@gmail.com" }, "parentFolderId": null, "isArchived": false }