Files
n8n/backups/2025-12-27/digest.json
2025-12-27 21:50:09 +00:00

1 line
7.7 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"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":[]}