{"updatedAt":"2025-11-30T15:55:43.530Z","createdAt":"2025-11-30T14:22:32.513Z","id":"1M7DW5S6VWz9VpBh","name":"digest","active":false,"isArchived":false,"nodes":[{"parameters":{"rule":{"interval":[{"triggerAtHour":21}]}},"type":"n8n-nodes-base.scheduleTrigger","typeVersion":1.2,"position":[64,112],"id":"898b2c59-c464-41e9-8acb-caf02ce2a5c4","name":"Schedule Trigger"},{"parameters":{"jsCode":"// определяем начало и конец текущего дня (МСК)\nconst now = new Date(new Date().toLocaleString('en-US', { timeZone: 'Europe/Moscow' }));\nconst pad = n => String(n).padStart(2, '0');\nconst date = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}`;\n\nreturn [{\n json: {\n date, // '2025-05-16'\n dayStart: `${date}T00:00:00`,\n dayEnd: `${date}T23:59:59`\n }\n}];\n"},"type":"n8n-nodes-base.code","typeVersion":2,"position":[240,112],"id":"1299704b-b649-4672-a00b-9d05d7e47964","name":"calcRange"},{"parameters":{"jsCode":"// items = массив строк из таблицы meals\nconst users = {}; // chat_id → агрегаты\n\nfor (const { json: r } of items) {\n const id = r.chat_id;\n const dt = new Date(r.eaten_at);\n\n if (!users[id]) {\n users[id] = {\n chat_id: id, // ← для Telegram\n gpt: { // ← для LLM\n date: $items('calcRange')[0].json.date,\n kcal: 0, prot: 0, fat: 0, carb: 0,\n meals: [] // строки «HH:MM — блюдо 200 г»\n }\n };\n }\n\n const u = users[id].gpt;\n\n // суммарные КБЖУ\n u.kcal += r.kcal;\n u.prot += r.prot;\n u.fat += r.fat;\n u.carb += r.carb;\n\n // строка тайм-лайна\n const hhmm = dt.toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit' });\n u.meals.push(`${hhmm} — ${r.dish} ${r.grams} г`);\n}\n\n// превращаем в массив items\nreturn Object.values(users).map(j => ({ json: j }));\n"},"type":"n8n-nodes-base.code","typeVersion":2,"position":[624,112],"id":"8b675099-d670-400a-8f3e-55950d7f4527","name":"groupByUser"},{"parameters":{"modelId":{"__rl":true,"value":"chatgpt-4o-latest","mode":"list","cachedResultName":"CHATGPT-4O-LATEST"},"messages":{"values":[{"content":"=Ты нутри-диетолог-бот. На вход приходит отчет о питании пользователя в JSON:\n{\n \"date\": \"YYYY-MM-DD\",\n \"kcal\": число | null,\n \"prot\": число | null,\n \"fat\" : число | null,\n \"carb\": число | null,\n \"meals\": [ \"08:00 — …\", … ] // массив может быть пуст\n}\n\n✅ Если данные по КБЖУ есть - сделай отчёт:\n\n• Итог КБЖУ за день: kcal, Б, Ж, У \n• Замечания: (кратко, только если есть замечания по рациону пользователя) \n• Совет на завтра: (1 конкретная рекомендация по улучшению самочувствия или питания)\n\nВ конце: \"Если будут вопросы — пиши :)\"\n\n--------------------------------\nФормат:\n\n• Telegram-Markdown Legacy \n• Сделай текст визуально приятным, важное выдели\n• жирный — одна `*`, курсив — одна `_` \n• до 3 тематических эмоджи во всём сообщении \n• Не выдавай ``` и не возвращай JSON.\n","role":"system"},{"content":"={{ JSON.stringify($json.gpt, null, 2) }}"}]},"options":{}},"type":"@n8n/n8n-nodes-langchain.openAi","typeVersion":1.8,"position":[800,112],"id":"9273841b-ded5-453c-835a-65914ce7b014","name":"digestGPT","credentials":{"openAiApi":{"id":"PvUURuR361IXH0ve","name":"OpenAi account"}}},{"parameters":{"operation":"getAll","tableId":"meals","returnAll":true,"matchType":"allFilters","filters":{"conditions":[{"keyName":"deleted","condition":"is","keyValue":"false"},{"keyName":"eaten_at","condition":"lte","keyValue":"={{ $json.dayEnd }}"},{"keyName":"eaten_at","condition":"gte","keyValue":"={{ $json.dayStart }}"}]}},"type":"n8n-nodes-base.supabase","typeVersion":1,"position":[432,112],"id":"001813d5-c8fe-416a-aee5-4ad1532098be","name":"GET today","alwaysOutputData":false,"credentials":{"supabaseApi":{"id":"OoOx3pPUNd1lRJTr","name":"Supabase account"}}},{"parameters":{"content":"# РАССЫЛКА каждый день в 21:00 по мск\n\n\n\n","height":352,"width":1718,"color":6},"id":"f535baca-c956-4724-9d19-43bf603c2a24","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[0,0],"typeVersion":1},{"parameters":{"method":"POST","url":"https://rosfwogfdgfdgfdgfdhcc.supabase.co/rest/v1/rpc/upsert_digest","authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth","sendHeaders":true,"headerParameters":{"parameters":[{"name":"apikey","value":"KEY"}]},"sendBody":true,"bodyParameters":{"parameters":[{"name":"_chat_id","value":"={{ $('groupByUser').item.json.chat_id }}"},{"name":"_for_date","value":"={{ $('groupByUser').item.json.gpt.date }}"},{"name":"_kcal","value":"={{ $('groupByUser').item.json.gpt.kcal }}"},{"name":"_prot","value":"={{ $('groupByUser').item.json.gpt.prot }}"},{"name":"_fat","value":"={{ $('groupByUser').item.json.gpt.fat }}"},{"name":"_carb","value":"={{ $('groupByUser').item.json.gpt.carb }}"},{"name":"_meals_json","value":"={{ $('groupByUser').item.json.gpt.meals }}"},{"name":"_summary_md","value":"={{ $('digestGPT').item.json.message.content }}"},{"name":"_msg_id","value":"={{ $json.result.message_id }}"}]},"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.2,"position":[1552,112],"id":"787493b2-e4e6-47be-9e54-93a9e9bd7aea","name":"SAVE SUPA digest","credentials":{"httpHeaderAuth":{"id":"8MpbqGPzLpfPWyM8","name":"Header Auth account"}}},{"parameters":{"chatId":"={{ $('groupByUser').item.json.chat_id }}","text":"={{ $json[\"message\"][\"content\"] || $json }}","additionalFields":{"appendAttribution":false,"parse_mode":"Markdown"}},"type":"n8n-nodes-base.telegram","typeVersion":1.2,"position":[1344,112],"id":"270ba6ba-b8a7-4493-85c5-f71dd2102678","name":"SEND","webhookId":"f28557c8-d474-47fe-9f04-5d6dbb9bd96c","credentials":{"telegramApi":{"id":"R8VDF53JH3mzhoHd","name":"Telegram dieta"}}},{"parameters":{"jsCode":"// убираем экранирование у формат-маркеров * и _\nif ($json.message?.content) {\n $json.message.content = $json.message.content\n // сначала двойные обратные слэши\n .replace(/\\\\([*_])/g, '$1');\n}\nreturn $json;\n"},"type":"n8n-nodes-base.code","typeVersion":2,"position":[1136,112],"id":"4b406b0b-47de-4cc3-8c39-969e8f542487","name":"Escape"}],"connections":{"Schedule Trigger":{"main":[[{"node":"calcRange","type":"main","index":0}]]},"calcRange":{"main":[[{"node":"GET today","type":"main","index":0}]]},"groupByUser":{"main":[[{"node":"digestGPT","type":"main","index":0}]]},"digestGPT":{"main":[[{"node":"Escape","type":"main","index":0}]]},"GET today":{"main":[[{"node":"groupByUser","type":"main","index":0}]]},"SEND":{"main":[[{"node":"SAVE SUPA digest","type":"main","index":0}]]},"Escape":{"main":[[{"node":"SEND","type":"main","index":0}]]}},"settings":{"executionOrder":"v1"},"staticData":{"node:Schedule Trigger":{"recurrenceRules":[]}},"meta":{"templateCredsSetupCompleted":true},"pinData":{},"versionId":"16512367-e4b6-494e-97ef-e749639ca6cc","activeVersionId":null,"triggerCount":1,"shared":[{"updatedAt":"2025-11-30T14:22:32.513Z","createdAt":"2025-11-30T14:22:32.513Z","role":"workflow:owner","workflowId":"1M7DW5S6VWz9VpBh","projectId":"sYuiFAb87pAir6jV"}],"activeVersion":null,"tags":[]}