{ "kind": "open-flow-workflow", "version": 1, "name": "Unread Email Digest", "content": { "modelVersion": 14, "document": { "bindings": {}, "graph": { "nodes": { "n_182d15eb8e2b5459": { "name": "Weekday morning", "kind": "cron", "cronTimes": [ { "type": "cron", "expression": "0 8 * * 1-5", "timezone": "UTC" } ] }, "n_92563f22e8707ef2": { "inputs": { "query": { "kind": "value", "value": "is:unread newer_than:1d -category:promotions -category:social" }, "maxResults": { "kind": "value", "value": 25 }, "detail": { "kind": "value", "value": "full" } }, "name": "Read unread email", "kind": "task", "task": { "inputs": [ { "description": "Gmail search query.", "jsonSchema": { "type": "string", "description": "Gmail search query." }, "nullable": true, "handle": "query", "value": null }, { "description": "Gmail label IDs.", "jsonSchema": { "type": "array", "items": { "type": "string", "minLength": 1 }, "description": "Gmail label IDs." }, "nullable": true, "handle": "labelIds", "value": null }, { "description": "Whether to include Spam and Trash.", "jsonSchema": { "type": "boolean", "description": "Whether to include Spam and Trash." }, "nullable": true, "handle": "includeSpamTrash", "value": null }, { "description": "Message detail level.", "jsonSchema": { "type": "string", "enum": [ "ids", "summary", "full" ], "description": "Message detail level.", "default": "summary" }, "nullable": true, "handle": "detail", "value": "summary" }, { "description": "Maximum number of results to return.", "jsonSchema": { "type": "integer", "minimum": 1, "maximum": 500, "description": "Maximum number of results to return." }, "nullable": true, "handle": "maxResults", "value": null }, { "description": "Opaque pagination token returned by Gmail.", "jsonSchema": { "type": "string", "description": "Opaque pagination token returned by Gmail." }, "nullable": true, "handle": "pageToken", "value": null } ], "outputs": [ { "description": "Returned messages.", "jsonSchema": { "type": "array", "items": { "anyOf": [ { "type": "object", "properties": { "messageId": { "type": "string", "minLength": 1, "description": "Gmail message ID." }, "threadId": { "type": "string", "minLength": 1, "description": "Gmail thread ID." }, "labelIds": { "type": "array", "items": { "type": "string", "minLength": 1 }, "description": "Gmail label IDs." }, "subject": { "type": "string", "description": "Message subject." }, "sender": { "type": "string", "description": "Message sender." }, "to": { "type": "string", "description": "Message recipients." }, "messageTimestamp": { "type": "string", "description": "Message timestamp." } }, "additionalProperties": true, "required": [ "messageId", "threadId", "labelIds", "subject", "sender", "to", "messageTimestamp" ], "description": "Normalized Gmail message summary." }, { "type": "object", "properties": { "messageId": { "type": "string", "minLength": 1, "description": "Gmail message ID." }, "threadId": { "type": "string", "minLength": 1, "description": "Gmail thread ID." }, "labelIds": { "type": "array", "items": { "type": "string", "minLength": 1 }, "description": "Gmail label IDs." }, "subject": { "type": "string", "description": "Message subject." }, "sender": { "type": "string", "description": "Message sender." }, "to": { "type": "string", "description": "Message recipients." }, "messageTimestamp": { "type": "string", "description": "Message timestamp." }, "preview": { "type": "object", "additionalProperties": true, "description": "Gmail API object." }, "payload": { "anyOf": [ { "type": "object", "additionalProperties": true, "description": "Gmail API object." }, { "type": "null" } ] }, "messageText": { "type": "string", "description": "Extracted message body text." }, "attachmentList": { "type": "array", "items": { "type": "object", "additionalProperties": true, "description": "Gmail API object." }, "description": "Message attachments." }, "raw": { "type": "string", "description": "Raw RFC 2822 message when requested." } }, "additionalProperties": true, "required": [ "messageId", "threadId", "labelIds", "subject", "sender", "to", "messageTimestamp" ], "description": "Normalized Gmail message." }, { "type": "object", "additionalProperties": true, "description": "Gmail API object." } ] }, "description": "Returned messages." }, "nullable": false, "handle": "messages" }, { "jsonSchema": { "anyOf": [ { "type": "string", "description": "Opaque pagination token returned by Gmail." }, { "type": "null" } ] }, "nullable": true, "handle": "nextPageToken" }, { "description": "Approximate result count.", "jsonSchema": { "type": "integer", "description": "Approximate result count." }, "nullable": true, "handle": "resultSizeEstimate" } ], "name": "Read unread email", "executor": { "kind": "connector", "action": "gmail.fetch_emails" } } }, "n_40dd8ed0a9f798fb": { "inputs": { "messages": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_92563f22e8707ef2", "output": "messages" } ] } }, "name": "Prepare email batch", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "array", "items": { "type": "object" } }, "nullable": false, "handle": "messages" } ], "outputs": [ { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "vuoto" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "totale" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "testoEmail" } ], "name": "Prepare email batch", "moduleId": "n_1714968c4b1ba48d", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_7c8262ddcaa72928": { "inputs": {}, "name": "Has unread email", "kind": "condition", "matchMode": "first", "cases": [ { "output": "has-email", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_40dd8ed0a9f798fb", "output": "vuoto" } }, "operator": "==", "right": { "kind": "value", "value": false } } ] } ] } ] }, "n_a07caef8b48c6f01": { "inputs": { "totale": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_40dd8ed0a9f798fb", "output": "totale" } ] }, "testoEmail": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_40dd8ed0a9f798fb", "output": "testoEmail" } ] } }, "name": "Summarize email", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "items": { "type": "object" }, "type": "array" }, "nullable": true, "handle": "messages", "value": null }, { "jsonSchema": { "items": { "type": "object" }, "minItems": 1, "type": "array" }, "nullable": false, "handle": "template", "value": [ { "role": "system", "content": "Sei l'assistente di un imprenditore italiano. Ricevi l'elenco delle email non lette e produci una rassegna mattutina in italiano, breve e pratica, in questo formato:\n\n🔴 URGENTI (rispondere oggi):\n- [mittente]: [cosa vuole in max 10 parole]\n\n🟡 IMPORTANTI (questa settimana):\n- ...\n\n⚪ IL RESTO:\n- una riga sola che raggruppa il resto\n\nSii sintetico. Se qualcosa sembra un cliente arrabbiato o un'opportunità di vendita, segnalalo per primo." }, { "role": "user", "content": "Ecco le {{totale}} email non lette:\n\n{{testoEmail}}" } ] }, { "jsonSchema": { "type": "object" }, "nullable": false, "handle": "model", "value": { "model": "gpt-4o-mini" } }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "totale" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "testoEmail" } ], "outputs": [ { "description": "Generated response.", "jsonSchema": { "type": "string" }, "nullable": false, "handle": "output" } ], "name": "Summarize email", "executor": { "kind": "llm", "mode": "chat" } } }, "n_935fce86ead1d787": { "inputs": { "summary": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_a07caef8b48c6f01", "output": "output" } ] }, "timezone": { "kind": "value", "value": "UTC" } }, "name": "Format digest", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "summary" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "timezone" } ], "outputs": [ { "jsonSchema": { "type": "string", "minLength": 1, "maxLength": 4096, "description": "The text of the message to send." }, "nullable": false, "handle": "text" } ], "name": "Format digest", "moduleId": "n_96692bef5aa03ad7", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_b034f6a39f94f37c": { "inputs": { "chatId": { "kind": "value", "value": "@YOUR_TELEGRAM_CHANNEL" }, "text": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_935fce86ead1d787", "output": "text" } ] } }, "name": "Send digest", "kind": "task", "task": { "inputs": [ { "description": "The target Telegram chat ID or channel username.", "jsonSchema": { "anyOf": [ { "type": "integer", "description": "A numeric Telegram chat identifier." }, { "type": "string", "pattern": "^-?\\d+$", "description": "A numeric Telegram chat identifier encoded as a string." }, { "type": "string", "pattern": "^@[A-Za-z0-9_]+$", "description": "A Telegram @username for a public chat or channel." } ], "description": "The target Telegram chat ID or channel username." }, "nullable": false, "handle": "chatId" }, { "description": "The text of the message to send.", "jsonSchema": { "type": "string", "minLength": 1, "maxLength": 4096, "description": "The text of the message to send." }, "nullable": false, "handle": "text" }, { "description": "The unique identifier of the Telegram business connection.", "jsonSchema": { "type": "string", "minLength": 1, "description": "The unique identifier of the Telegram business connection." }, "nullable": true, "handle": "businessConnectionId", "value": null }, { "description": "The parse mode used for message entities.", "jsonSchema": { "type": "string", "enum": [ "Markdown", "MarkdownV2", "HTML" ], "description": "The parse mode used for message entities." }, "nullable": true, "handle": "parseMode", "value": null }, { "description": "Whether to send the message silently.", "jsonSchema": { "type": "boolean", "description": "Whether to send the message silently." }, "nullable": true, "handle": "disableNotification", "value": null }, { "description": "Whether to protect the sent message from forwarding and saving.", "jsonSchema": { "type": "boolean", "description": "Whether to protect the sent message from forwarding and saving." }, "nullable": true, "handle": "protectContent", "value": null }, { "description": "Whether to disable link previews in the message.", "jsonSchema": { "type": "boolean", "description": "Whether to disable link previews in the message." }, "nullable": true, "handle": "disableWebPagePreview", "value": null }, { "description": "The forum topic ID for the target message thread.", "jsonSchema": { "type": "integer", "minimum": 1, "description": "The forum topic ID for the target message thread." }, "nullable": true, "handle": "messageThreadId", "value": null }, { "description": "The message ID to reply to.", "jsonSchema": { "type": "integer", "minimum": 1, "description": "The message ID to reply to." }, "nullable": true, "handle": "replyToMessageId", "value": null } ], "outputs": [ { "description": "A normalized Telegram message record.", "jsonSchema": { "type": "object", "properties": {}, "additionalProperties": true, "description": "A normalized Telegram message record." }, "nullable": false, "handle": "output" } ], "name": "Send digest", "executor": { "kind": "connector", "action": "telegram.send_message", "outputMode": "value" } } } }, "edges": [ { "source": "n_182d15eb8e2b5459", "target": "n_92563f22e8707ef2" }, { "source": "n_92563f22e8707ef2", "target": "n_40dd8ed0a9f798fb" }, { "source": "n_40dd8ed0a9f798fb", "target": "n_7c8262ddcaa72928" }, { "source": "n_7c8262ddcaa72928", "target": "n_a07caef8b48c6f01", "sourceHandle": "has-email" }, { "source": "n_a07caef8b48c6f01", "target": "n_935fce86ead1d787" }, { "source": "n_935fce86ead1d787", "target": "n_b034f6a39f94f37c" } ] } }, "modules": { "n_1714968c4b1ba48d": { "name": "Prepare email batch", "imports": [], "source": "export default ({ messages }) => {\n const lines = messages.map((email) => {\n const sender = email.sender || 'Sconosciuto';\n const subject = email.subject || '(senza oggetto)';\n const preview = String(email.preview?.body || email.messageText || '').slice(0, 200).replace(/\\s+/g, ' ');\n return 'DA: ' + sender + '\\nOGGETTO: ' + subject + '\\nANTEPRIMA: ' + preview + '\\n---';\n });\n return { vuoto: lines.length === 0, totale: lines.length, testoEmail: lines.join('\\n') };\n};\n" }, "n_96692bef5aa03ad7": { "name": "Format digest", "imports": [], "source": "export default ({ summary, timezone }) => {\n const parts = Object.fromEntries(\n new Intl.DateTimeFormat('en-GB', { timeZone: timezone, day: '2-digit', month: '2-digit' })\n .formatToParts(new Date()).map((part) => [part.type, part.value]),\n );\n return { text: '☕ Rassegna email del ' + parts.day + '/' + parts.month + '\\n\\n' + summary };\n};\n" } } }, "presentation": { "designer": { "version": 1, "flow": { "direction": "vertical" } } } }