{ "kind": "open-flow-workflow", "version": 1, "name": "Google Drive New File Email Alert", "content": { "modelVersion": 14, "document": { "bindings": {}, "graph": { "nodes": { "n_f530894643d7b5e1": { "name": "Watch for new Drive files", "kind": "poll", "config": { "changeType": { "kind": "value", "value": "created" }, "folderId": { "kind": "value", "value": "YOUR_GOOGLE_DRIVE_FOLDER_ID" }, "driveId": { "kind": "value", "value": "" }, "itemTypes": { "kind": "value", "value": [ "file" ] }, "mimeTypes": { "kind": "value", "value": [] }, "namePrefix": { "kind": "value", "value": "" }, "maxFilesPerPoll": { "kind": "value", "value": 50 } }, "definition": { "configInputs": [ { "jsonSchema": { "type": "string", "enum": [ "created", "updated" ] }, "nullable": false, "handle": "changeType" }, { "jsonSchema": { "type": "string", "pattern": "^[A-Za-z0-9_-]{0,512}$" }, "nullable": false, "handle": "driveId", "value": "" }, { "jsonSchema": { "type": "string", "pattern": "^[A-Za-z0-9_-]{2,512}$" }, "nullable": false, "handle": "folderId" }, { "jsonSchema": { "type": "array", "items": { "type": "string", "enum": [ "file", "folder" ] }, "minItems": 1, "uniqueItems": true }, "nullable": false, "handle": "itemTypes", "value": [ "file" ] }, { "jsonSchema": { "type": "array", "items": { "type": "string", "minLength": 1 } }, "nullable": false, "handle": "mimeTypes", "value": [] }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "namePrefix", "value": "" }, { "collapsed": true, "group": "Advanced settings" }, { "jsonSchema": { "type": "integer", "minimum": 1, "maximum": 200 }, "nullable": false, "handle": "maxFilesPerPoll", "value": 50 } ], "definitionVersion": 2, "description": "Polls one Google Drive folder and triggers when a file or folder directly inside it is created or updated.", "displayName": "File or Folder Change in a Folder", "key": "googledrive.on_file_change", "name": "on_file_change", "outputs": [ { "jsonSchema": { "type": "array", "items": { "type": "object", "properties": { "createdTime": { "type": [ "string", "null" ] }, "driveId": { "type": [ "string", "null" ] }, "eventType": { "type": "string", "enum": [ "file_created", "file_updated", "folder_created", "folder_updated" ] }, "fileId": { "type": "string" }, "itemType": { "type": "string", "enum": [ "file", "folder" ] }, "lastModifyingUser": { "type": [ "object", "null" ] }, "mimeType": { "type": "string" }, "modifiedTime": { "type": [ "string", "null" ] }, "name": { "type": "string" }, "parents": { "type": "array", "items": { "type": "string" } }, "size": { "type": "string" }, "webViewLink": { "type": [ "string", "null" ] } }, "additionalProperties": false, "required": [ "eventType", "itemType", "fileId", "name", "mimeType", "createdTime", "modifiedTime", "parents", "webViewLink", "driveId", "lastModifyingUser" ] } }, "nullable": false, "handle": "events" } ], "provider": "googledrive", "type": "poll" }, "pollTimes": [ { "type": "every", "unit": "minute", "value": 1 } ] }, "n_cd567ae4afd4d8f0": { "inputs": { "events": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_f530894643d7b5e1", "output": "events" } ] } }, "name": "Validate the new-file batch", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "array", "items": { "type": "object", "properties": { "createdTime": { "type": [ "string", "null" ] }, "driveId": { "type": [ "string", "null" ] }, "eventType": { "type": "string", "enum": [ "file_created", "file_updated", "folder_created", "folder_updated" ] }, "fileId": { "type": "string" }, "itemType": { "type": "string", "enum": [ "file", "folder" ] }, "lastModifyingUser": { "type": [ "object", "null" ] }, "mimeType": { "type": "string" }, "modifiedTime": { "type": [ "string", "null" ] }, "name": { "type": "string" }, "parents": { "type": "array", "items": { "type": "string" } }, "size": { "type": "string" }, "webViewLink": { "type": [ "string", "null" ] } }, "additionalProperties": false, "required": [ "eventType", "itemType", "fileId", "name", "mimeType", "createdTime", "modifiedTime", "parents", "webViewLink", "driveId", "lastModifyingUser" ] } }, "nullable": false, "handle": "events" } ], "outputs": [ { "jsonSchema": { "type": "array", "items": { "type": "object", "properties": { "fileId": { "type": "string", "minLength": 1 }, "name": { "type": "string" } }, "required": [ "fileId", "name" ], "additionalProperties": false } }, "nullable": false, "handle": "files" } ], "name": "Validate the new-file batch", "moduleId": "n_4f9afcffddf7fe96", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_d04da8cc2c54f6a7": { "inputs": { "files": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_cd567ae4afd4d8f0", "output": "files" } ] }, "previousState": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_d04da8cc2c54f6a7", "output": "state" } ] }, "messageId": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_5a0f7f63bb19eac4", "output": "messageId" } ] }, "accepted": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_5a0f7f63bb19eac4", "output": "accepted" } ] }, "rejected": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_5a0f7f63bb19eac4", "output": "rejected" } ] }, "response": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_5a0f7f63bb19eac4", "output": "response" } ] } }, "name": "Prepare the next alert", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "array", "items": { "type": "object", "properties": { "fileId": { "type": "string", "minLength": 1 }, "name": { "type": "string" } }, "required": [ "fileId", "name" ], "additionalProperties": false } }, "nullable": false, "handle": "files" }, { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": true, "handle": "previousState" }, { "jsonSchema": { "type": [ "string", "null" ], "description": "The SMTP Message-ID returned by the mail client." }, "nullable": true, "handle": "messageId" }, { "jsonSchema": { "type": "array", "items": { "type": "string", "minLength": 1, "format": "email", "description": "An email address." }, "description": "Recipient addresses accepted by the SMTP server." }, "nullable": true, "handle": "accepted" }, { "jsonSchema": { "type": "array", "items": { "type": "string", "minLength": 1, "format": "email", "description": "An email address." }, "description": "Recipient addresses rejected by the SMTP server." }, "nullable": true, "handle": "rejected" }, { "jsonSchema": { "type": "string", "description": "The SMTP response text returned by the server." }, "nullable": true, "handle": "response" } ], "outputs": [ { "jsonSchema": { "type": "object", "properties": { "index": { "type": "integer", "minimum": 0 }, "receipts": { "type": "array", "items": { "type": "object", "additionalProperties": true } } }, "required": [ "index", "receipts" ], "additionalProperties": false }, "nullable": false, "handle": "state" }, { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "more" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "message" }, { "jsonSchema": { "type": "integer", "minimum": 0 }, "nullable": false, "handle": "count" } ], "name": "Prepare the next alert", "moduleId": "n_35d79d21f1c49748", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_8b732f0f6ceb2650": { "inputs": {}, "name": "More files to notify", "kind": "condition", "matchMode": "first", "cases": [ { "output": "more", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_d04da8cc2c54f6a7", "output": "more" } }, "operator": "==", "right": { "kind": "value", "value": true } } ] } ] } ] }, "n_5a0f7f63bb19eac4": { "inputs": { "to": { "kind": "value", "value": [ "recipient@example.com" ] }, "subject": { "kind": "value", "value": "File Update" }, "text": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_d04da8cc2c54f6a7", "output": "message" } ] } }, "name": "Email one new-file alert", "kind": "task", "task": { "inputs": [ { "description": "The primary recipient email addresses.", "jsonSchema": { "type": "array", "items": { "type": "string", "minLength": 1, "format": "email", "description": "An email address." }, "minItems": 1, "description": "The primary recipient email addresses." }, "nullable": false, "handle": "to" }, { "description": "The carbon-copy recipient email addresses.", "jsonSchema": { "type": "array", "items": { "type": "string", "minLength": 1, "format": "email", "description": "An email address." }, "minItems": 1, "description": "The carbon-copy recipient email addresses." }, "nullable": true, "handle": "cc", "value": null }, { "description": "The blind-carbon-copy recipient email addresses.", "jsonSchema": { "type": "array", "items": { "type": "string", "minLength": 1, "format": "email", "description": "An email address." }, "minItems": 1, "description": "The blind-carbon-copy recipient email addresses." }, "nullable": true, "handle": "bcc", "value": null }, { "description": "An email address.", "jsonSchema": { "type": "string", "minLength": 1, "format": "email", "description": "An email address." }, "nullable": true, "handle": "replyTo", "value": null }, { "description": "The email subject.", "jsonSchema": { "type": "string", "description": "The email subject." }, "nullable": false, "handle": "subject" }, { "description": "The plain text email body.", "jsonSchema": { "type": "string", "description": "The plain text email body." }, "nullable": true, "handle": "text", "value": null }, { "description": "The HTML email body.", "jsonSchema": { "type": "string", "description": "The HTML email body." }, "nullable": true, "handle": "html", "value": null }, { "description": "Attachments to fetch and include in the outgoing email.", "jsonSchema": { "type": "array", "items": { "type": "object", "properties": { "filename": { "type": "string", "minLength": 1, "description": "The filename to use for the outgoing attachment." }, "contentType": { "type": "string", "minLength": 1, "description": "The MIME content type of the attachment." }, "contentUrl": { "type": "string", "format": "uri", "description": "The public HTTP or HTTPS URL to fetch attachment content from." } }, "required": [ "filename", "contentUrl" ], "additionalProperties": false, "description": "An attachment to fetch and include in an outgoing email." }, "minItems": 1, "maxItems": 10, "description": "Attachments to fetch and include in the outgoing email." }, "nullable": true, "handle": "attachments", "value": null } ], "outputs": [ { "description": "The SMTP Message-ID returned by the mail client.", "jsonSchema": { "type": [ "string", "null" ], "description": "The SMTP Message-ID returned by the mail client." }, "nullable": true, "handle": "messageId" }, { "description": "Recipient addresses accepted by the SMTP server.", "jsonSchema": { "type": "array", "items": { "type": "string", "minLength": 1, "format": "email", "description": "An email address." }, "description": "Recipient addresses accepted by the SMTP server." }, "nullable": false, "handle": "accepted" }, { "description": "Recipient addresses rejected by the SMTP server.", "jsonSchema": { "type": "array", "items": { "type": "string", "minLength": 1, "format": "email", "description": "An email address." }, "description": "Recipient addresses rejected by the SMTP server." }, "nullable": false, "handle": "rejected" }, { "description": "The SMTP response text returned by the server.", "jsonSchema": { "type": "string", "description": "The SMTP response text returned by the server." }, "nullable": false, "handle": "response" } ], "name": "Email one new-file alert", "executor": { "kind": "connector", "action": "generic_imap.send_email" } } }, "n_f59791e527b4ce48": { "name": "File notification receipts", "kind": "outputs", "outputDefs": [ { "jsonSchema": { "type": "array", "items": { "type": "object", "additionalProperties": true } }, "nullable": false, "handle": "receipts" }, { "jsonSchema": { "type": "integer", "minimum": 0 }, "nullable": false, "handle": "count" } ], "outputMappings": { "receipts": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_d04da8cc2c54f6a7", "output": "state", "field": "receipts" } ] }, "count": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_d04da8cc2c54f6a7", "output": "count" } ] } } } }, "edges": [ { "source": "n_f530894643d7b5e1", "target": "n_cd567ae4afd4d8f0" }, { "source": "n_cd567ae4afd4d8f0", "target": "n_d04da8cc2c54f6a7" }, { "source": "n_d04da8cc2c54f6a7", "target": "n_8b732f0f6ceb2650" }, { "source": "n_8b732f0f6ceb2650", "target": "n_5a0f7f63bb19eac4", "sourceHandle": "more" }, { "source": "n_5a0f7f63bb19eac4", "target": "n_d04da8cc2c54f6a7" }, { "source": "n_8b732f0f6ceb2650", "target": "n_f59791e527b4ce48", "sourceHandle": "otherwise" } ] } }, "modules": { "n_4f9afcffddf7fe96": { "name": "Validate the new-file batch", "imports": [], "source": "export default function driveNewFileEvents({ events }) {\n if (!Array.isArray(events)) throw new Error('Expected a Google Drive event batch');\n const seen = new Set();\n const files = events.map(event => {\n if (!event || event.eventType !== 'file_created' || event.itemType !== 'file' || typeof event.fileId !== 'string' || !event.fileId || typeof event.name !== 'string') throw new Error('Expected a complete new-file event');\n if (seen.has(event.fileId)) throw new Error('Duplicate Google Drive file in this batch');\n seen.add(event.fileId);\n return { fileId: event.fileId, name: event.name };\n });\n return { files };\n}\n" }, "n_35d79d21f1c49748": { "name": "Prepare the next alert", "imports": [], "source": "export default function driveFileMailProgress({ files, previousState, messageId, accepted, rejected, response }) {\n if (!Array.isArray(files)) throw new Error('Expected files to notify');\n let state;\n if (previousState == null) state = { index: 0, receipts: [] };\n else {\n if (!Number.isInteger(previousState.index) || previousState.index < 1 || previousState.index > files.length || !Array.isArray(previousState.receipts) || previousState.receipts.length !== previousState.index - 1) throw new Error('Invalid file notification state');\n if (!Array.isArray(accepted) || !accepted.length || accepted.some(value => typeof value !== 'string' || !value.trim()) || !Array.isArray(rejected) || rejected.length || typeof response !== 'string' || (messageId != null && typeof messageId !== 'string')) throw new Error('SMTP did not confirm the file notification');\n state = { index: previousState.index, receipts: [...previousState.receipts, { fileId: files[previousState.index - 1].fileId, messageId: messageId ?? null, accepted, rejected, response }] };\n }\n const file = files[state.index];\n if (file == null) return { state, more: false, message: '', count: state.receipts.length };\n if (typeof file.fileId !== 'string' || !file.fileId || typeof file.name !== 'string') throw new Error('Invalid file notification');\n return { state: { index: state.index + 1, receipts: state.receipts }, more: true, message: 'A file in your Google Drive file folder has been created: ' + file.name, count: state.receipts.length };\n}\n" } } }, "presentation": { "designer": { "version": 1, "flow": { "direction": "vertical" } } } }