{ "kind": "open-flow-workflow", "version": 1, "name": "Save First Gmail Attachments to Drive", "content": { "modelVersion": 14, "document": { "bindings": {}, "graph": { "nodes": { "n_7dad464fc2627b2b": { "name": "Start manually", "kind": "start", "inputDefs": [] }, "n_c2916405b6b8437d": { "inputs": { "maxResults": { "kind": "value", "value": 10 }, "labelIds": { "kind": "value", "value": [ "YOUR_GMAIL_LABEL_ID" ] }, "detail": { "kind": "value", "value": "ids" }, "includeSpamTrash": { "kind": "value", "value": false } }, "name": "Find labeled messages", "kind": "task", "task": { "inputs": [ { "description": "Gmail search query.", "jsonSchema": { "type": "string", "description": "Gmail search query." }, "nullable": true, "handle": "query", "value": null }, { "description": "Maximum number of results to return.", "jsonSchema": { "type": "integer", "minimum": 1, "maximum": 500, "description": "Maximum number of results to return.", "default": 20 }, "nullable": true, "handle": "maxResults", "value": 20 }, { "description": "Label IDs that messages must match.", "jsonSchema": { "type": "array", "items": { "type": "string", "description": "An array item." }, "description": "Label IDs that messages must match." }, "nullable": true, "handle": "labelIds", "value": null }, { "description": "Opaque pagination token returned by a previous Gmail response.", "jsonSchema": { "type": "string", "description": "Opaque pagination token returned by a previous Gmail response." }, "nullable": true, "handle": "pageToken", "value": null }, { "description": "Whether to include messages from Spam and Trash.", "jsonSchema": { "type": "boolean", "description": "Whether to include messages from Spam and Trash." }, "nullable": true, "handle": "includeSpamTrash", "value": null }, { "description": "How much message detail to return: identifiers only, lightweight summaries, or full normalized messages.", "jsonSchema": { "type": "string", "enum": [ "ids", "summary", "full" ], "description": "How much message detail to return: identifiers only, lightweight summaries, or full normalized messages.", "default": "summary" }, "nullable": true, "handle": "detail", "value": "summary" } ], "outputs": [ { "description": "Messages returned by Gmail as lightweight references, lightweight summaries, or full normalized payloads.", "jsonSchema": { "type": "array", "items": { "anyOf": [ { "type": "object", "properties": { "messageId": { "type": "string", "description": "Gmail message ID." }, "threadId": { "type": "string", "description": "Gmail thread ID." } }, "required": [ "messageId", "threadId" ], "additionalProperties": false, "description": "A union variant." }, { "type": "object", "properties": { "historyId": { "type": "string", "description": "The message history ID." }, "internalDate": { "type": "string", "description": "The internal timestamp in milliseconds." }, "sizeEstimate": { "type": "integer", "description": "The estimated message size in bytes." }, "snippet": { "type": "string", "description": "The message snippet." }, "messageId": { "type": "string", "description": "Gmail message ID." }, "threadId": { "type": "string", "description": "Gmail thread ID." }, "labelIds": { "type": "array", "items": { "type": "string", "description": "An array item." }, "description": "Label IDs applied to the message." }, "subject": { "type": "string", "description": "Normalized message subject line." }, "sender": { "type": "string", "description": "Normalized sender value." }, "to": { "type": "string", "description": "Normalized To header value." }, "messageTimestamp": { "type": "string", "description": "Message timestamp returned by Gmail." } }, "required": [ "messageId", "threadId", "labelIds", "subject", "sender", "to", "messageTimestamp" ], "additionalProperties": false, "description": "Schema for gmailMessageSummarySchema." }, { "type": "object", "properties": { "historyId": { "type": "string", "description": "The message history ID." }, "internalDate": { "type": "string", "description": "The internal timestamp in milliseconds." }, "sizeEstimate": { "type": "integer", "description": "The estimated message size in bytes." }, "snippet": { "type": "string", "description": "The message snippet." }, "messageId": { "type": "string", "description": "Gmail message ID." }, "threadId": { "type": "string", "description": "Gmail thread ID." }, "labelIds": { "type": "array", "items": { "type": "string", "description": "An array item." }, "description": "Label IDs applied to the message." }, "subject": { "type": "string", "description": "Normalized message subject line." }, "sender": { "type": "string", "description": "Normalized sender value." }, "to": { "type": "string", "description": "Normalized To header value." }, "preview": { "type": "object", "properties": { "subject": { "type": "string", "description": "Preview subject extracted from the message." }, "body": { "type": "string", "description": "Preview body text extracted from the message." } }, "required": [ "subject", "body" ], "additionalProperties": false, "description": "Short preview of the message subject and body." }, "payload": { "type": [ "object", "null" ], "additionalProperties": { "description": "A record value." }, "description": "Raw Gmail payload object, or null when it was not included." }, "messageText": { "type": "string", "description": "Best-effort plain-text representation of the message body." }, "attachmentList": { "type": "array", "items": { "type": "object", "properties": { "attachmentId": { "type": [ "string", "null" ], "description": "Attachment ID, or null when Gmail inlines the body." }, "filename": { "type": "string", "description": "Attachment filename." }, "mimeType": { "type": "string", "description": "Attachment MIME type." }, "size": { "type": "integer", "description": "Attachment size in bytes." }, "partId": { "type": [ "string", "null" ], "description": "Gmail MIME part ID, when supplied." }, "contentId": { "type": [ "string", "null" ], "description": "Bare Content-ID, when supplied." }, "disposition": { "type": [ "string", "null" ], "enum": [ "inline", "attachment", null ], "description": "Content-Disposition, when supplied." } }, "required": [ "attachmentId", "filename", "mimeType", "size", "partId", "contentId", "disposition" ], "additionalProperties": false, "description": "Schema for gmailAttachmentSchema." }, "description": "Normalized attachment summaries." }, "messageTimestamp": { "type": "string", "description": "Message timestamp returned by Gmail." }, "raw": { "type": "string", "description": "Raw RFC 2822 message content when Gmail returns it." } }, "required": [ "messageId", "threadId", "labelIds", "subject", "sender", "to", "preview", "payload", "messageText", "attachmentList", "messageTimestamp" ], "additionalProperties": false, "description": "Schema for gmailMessageSchema." } ], "description": "An array item." }, "description": "Messages returned by Gmail as lightweight references, lightweight summaries, or full normalized payloads." }, "nullable": false, "handle": "messages" }, { "description": "Opaque token for the next page, or null when there are no more results.", "jsonSchema": { "type": [ "string", "null" ], "description": "Opaque token for the next page, or null when there are no more results." }, "nullable": true, "handle": "nextPageToken" }, { "description": "Approximate number of matching results reported by Gmail.", "jsonSchema": { "type": "integer", "description": "Approximate number of matching results reported by Gmail." }, "nullable": false, "handle": "resultSizeEstimate" } ], "name": "Find labeled messages", "executor": { "kind": "connector", "action": "gmail.fetch_emails" } } }, "n_e921b815c88c3ab6": { "inputs": { "messages": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_c2916405b6b8437d", "output": "messages" } ] }, "previousState": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_e921b815c88c3ab6", "output": "state" } ] }, "attachment": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_ba1dc91fac6dd2a4", "output": "attachment" } ] } }, "name": "Prepare the next email", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "array", "items": { "anyOf": [ { "type": "object", "properties": { "messageId": { "type": "string", "description": "Gmail message ID." }, "threadId": { "type": "string", "description": "Gmail thread ID." } }, "required": [ "messageId", "threadId" ], "additionalProperties": false, "description": "A union variant." }, { "type": "object", "properties": { "historyId": { "type": "string", "description": "The message history ID." }, "internalDate": { "type": "string", "description": "The internal timestamp in milliseconds." }, "sizeEstimate": { "type": "integer", "description": "The estimated message size in bytes." }, "snippet": { "type": "string", "description": "The message snippet." }, "messageId": { "type": "string", "description": "Gmail message ID." }, "threadId": { "type": "string", "description": "Gmail thread ID." }, "labelIds": { "type": "array", "items": { "type": "string", "description": "An array item." }, "description": "Label IDs applied to the message." }, "subject": { "type": "string", "description": "Normalized message subject line." }, "sender": { "type": "string", "description": "Normalized sender value." }, "to": { "type": "string", "description": "Normalized To header value." }, "messageTimestamp": { "type": "string", "description": "Message timestamp returned by Gmail." } }, "required": [ "messageId", "threadId", "labelIds", "subject", "sender", "to", "messageTimestamp" ], "additionalProperties": false, "description": "Schema for gmailMessageSummarySchema." }, { "type": "object", "properties": { "historyId": { "type": "string", "description": "The message history ID." }, "internalDate": { "type": "string", "description": "The internal timestamp in milliseconds." }, "sizeEstimate": { "type": "integer", "description": "The estimated message size in bytes." }, "snippet": { "type": "string", "description": "The message snippet." }, "messageId": { "type": "string", "description": "Gmail message ID." }, "threadId": { "type": "string", "description": "Gmail thread ID." }, "labelIds": { "type": "array", "items": { "type": "string", "description": "An array item." }, "description": "Label IDs applied to the message." }, "subject": { "type": "string", "description": "Normalized message subject line." }, "sender": { "type": "string", "description": "Normalized sender value." }, "to": { "type": "string", "description": "Normalized To header value." }, "preview": { "type": "object", "properties": { "subject": { "type": "string", "description": "Preview subject extracted from the message." }, "body": { "type": "string", "description": "Preview body text extracted from the message." } }, "required": [ "subject", "body" ], "additionalProperties": false, "description": "Short preview of the message subject and body." }, "payload": { "type": [ "object", "null" ], "additionalProperties": { "description": "A record value." }, "description": "Raw Gmail payload object, or null when it was not included." }, "messageText": { "type": "string", "description": "Best-effort plain-text representation of the message body." }, "attachmentList": { "type": "array", "items": { "type": "object", "properties": { "attachmentId": { "type": [ "string", "null" ], "description": "Attachment ID, or null when Gmail inlines the body." }, "filename": { "type": "string", "description": "Attachment filename." }, "mimeType": { "type": "string", "description": "Attachment MIME type." }, "size": { "type": "integer", "description": "Attachment size in bytes." }, "partId": { "type": [ "string", "null" ], "description": "Gmail MIME part ID, when supplied." }, "contentId": { "type": [ "string", "null" ], "description": "Bare Content-ID, when supplied." }, "disposition": { "type": [ "string", "null" ], "enum": [ "inline", "attachment", null ], "description": "Content-Disposition, when supplied." } }, "required": [ "attachmentId", "filename", "mimeType", "size", "partId", "contentId", "disposition" ], "additionalProperties": false, "description": "Schema for gmailAttachmentSchema." }, "description": "Normalized attachment summaries." }, "messageTimestamp": { "type": "string", "description": "Message timestamp returned by Gmail." }, "raw": { "type": "string", "description": "Raw RFC 2822 message content when Gmail returns it." } }, "required": [ "messageId", "threadId", "labelIds", "subject", "sender", "to", "preview", "payload", "messageText", "attachmentList", "messageTimestamp" ], "additionalProperties": false, "description": "Schema for gmailMessageSchema." } ], "description": "An array item." }, "description": "Messages returned by Gmail as lightweight references, lightweight summaries, or full normalized payloads." }, "nullable": false, "handle": "messages" }, { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": true, "handle": "previousState" }, { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": true, "handle": "attachment" } ], "outputs": [ { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "state" }, { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "more" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "messageId" }, { "jsonSchema": { "type": "array", "items": { "type": "object", "additionalProperties": true } }, "nullable": false, "handle": "files" } ], "name": "Prepare the next email", "moduleId": "n_93bb450c7a6c105e", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_a844278c4e42400b": { "inputs": {}, "name": "More emails?", "kind": "condition", "matchMode": "first", "cases": [ { "output": "read", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_e921b815c88c3ab6", "output": "more" } }, "operator": "isTrue" } ] } ] } ] }, "n_9e91b6dc440ed10f": { "inputs": { "messageId": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_e921b815c88c3ab6", "output": "messageId" } ] }, "format": { "kind": "value", "value": "full" } }, "name": "Read the email", "kind": "task", "task": { "inputs": [ { "description": "Gmail message ID.", "jsonSchema": { "type": "string", "description": "Gmail message ID." }, "nullable": false, "handle": "messageId" }, { "description": "Gmail response format to request.", "jsonSchema": { "type": "string", "enum": [ "minimal", "full", "raw", "metadata" ], "description": "Gmail response format to request." }, "nullable": true, "handle": "format", "value": null } ], "outputs": [ { "description": "The message history ID.", "jsonSchema": { "type": "string", "description": "The message history ID." }, "nullable": true, "handle": "historyId" }, { "description": "The internal timestamp in milliseconds.", "jsonSchema": { "type": "string", "description": "The internal timestamp in milliseconds." }, "nullable": true, "handle": "internalDate" }, { "description": "The estimated message size in bytes.", "jsonSchema": { "type": "integer", "description": "The estimated message size in bytes." }, "nullable": true, "handle": "sizeEstimate" }, { "description": "The message snippet.", "jsonSchema": { "type": "string", "description": "The message snippet." }, "nullable": true, "handle": "snippet" }, { "description": "Gmail message ID.", "jsonSchema": { "type": "string", "description": "Gmail message ID." }, "nullable": false, "handle": "messageId" }, { "description": "Gmail thread ID.", "jsonSchema": { "type": "string", "description": "Gmail thread ID." }, "nullable": false, "handle": "threadId" }, { "description": "Label IDs applied to the message.", "jsonSchema": { "type": "array", "items": { "type": "string", "description": "An array item." }, "description": "Label IDs applied to the message." }, "nullable": false, "handle": "labelIds" }, { "description": "Normalized message subject line.", "jsonSchema": { "type": "string", "description": "Normalized message subject line." }, "nullable": false, "handle": "subject" }, { "description": "Normalized sender value.", "jsonSchema": { "type": "string", "description": "Normalized sender value." }, "nullable": false, "handle": "sender" }, { "description": "Normalized To header value.", "jsonSchema": { "type": "string", "description": "Normalized To header value." }, "nullable": false, "handle": "to" }, { "description": "Short preview of the message subject and body.", "jsonSchema": { "type": "object", "properties": { "subject": { "type": "string", "description": "Preview subject extracted from the message." }, "body": { "type": "string", "description": "Preview body text extracted from the message." } }, "required": [ "subject", "body" ], "additionalProperties": false, "description": "Short preview of the message subject and body." }, "nullable": false, "handle": "preview" }, { "description": "Raw Gmail payload object, or null when it was not included.", "jsonSchema": { "type": [ "object", "null" ], "additionalProperties": { "description": "A record value." }, "description": "Raw Gmail payload object, or null when it was not included." }, "nullable": true, "handle": "payload" }, { "description": "Best-effort plain-text representation of the message body.", "jsonSchema": { "type": "string", "description": "Best-effort plain-text representation of the message body." }, "nullable": false, "handle": "messageText" }, { "description": "Normalized attachment summaries.", "jsonSchema": { "type": "array", "items": { "type": "object", "properties": { "attachmentId": { "type": [ "string", "null" ], "description": "Attachment ID, or null when Gmail inlines the body." }, "filename": { "type": "string", "description": "Attachment filename." }, "mimeType": { "type": "string", "description": "Attachment MIME type." }, "size": { "type": "integer", "description": "Attachment size in bytes." }, "partId": { "type": [ "string", "null" ], "description": "Gmail MIME part ID, when supplied." }, "contentId": { "type": [ "string", "null" ], "description": "Bare Content-ID, when supplied." }, "disposition": { "type": [ "string", "null" ], "enum": [ "inline", "attachment", null ], "description": "Content-Disposition, when supplied." } }, "required": [ "attachmentId", "filename", "mimeType", "size", "partId", "contentId", "disposition" ], "additionalProperties": false, "description": "Schema for gmailAttachmentSchema." }, "description": "Normalized attachment summaries." }, "nullable": false, "handle": "attachmentList" }, { "description": "Message timestamp returned by Gmail.", "jsonSchema": { "type": "string", "description": "Message timestamp returned by Gmail." }, "nullable": false, "handle": "messageTimestamp" }, { "description": "Raw RFC 2822 message content when Gmail returns it.", "jsonSchema": { "type": "string", "description": "Raw RFC 2822 message content when Gmail returns it." }, "nullable": true, "handle": "raw" } ], "name": "Read the email", "executor": { "kind": "connector", "action": "gmail.fetch_message_by_message_id" } } }, "n_48d05db2cfed46ac": { "inputs": { "expectedId": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_e921b815c88c3ab6", "output": "messageId" } ] }, "messageId": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_9e91b6dc440ed10f", "output": "messageId" } ] }, "attachmentList": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_9e91b6dc440ed10f", "output": "attachmentList" } ] }, "payload": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_9e91b6dc440ed10f", "output": "payload" } ] } }, "name": "Select the first attachment", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "expectedId" }, { "jsonSchema": { "type": "string", "description": "Gmail message ID." }, "nullable": false, "handle": "messageId" }, { "jsonSchema": { "type": "array", "items": { "type": "object", "properties": { "attachmentId": { "type": [ "string", "null" ], "description": "Attachment ID, or null when Gmail inlines the body." }, "filename": { "type": "string", "description": "Attachment filename." }, "mimeType": { "type": "string", "description": "Attachment MIME type." }, "size": { "type": "integer", "description": "Attachment size in bytes." }, "partId": { "type": [ "string", "null" ], "description": "Gmail MIME part ID, when supplied." }, "contentId": { "type": [ "string", "null" ], "description": "Bare Content-ID, when supplied." }, "disposition": { "type": [ "string", "null" ], "enum": [ "inline", "attachment", null ], "description": "Content-Disposition, when supplied." } }, "required": [ "attachmentId", "filename", "mimeType", "size", "partId", "contentId", "disposition" ], "additionalProperties": false, "description": "Schema for gmailAttachmentSchema." }, "description": "Normalized attachment summaries." }, "nullable": false, "handle": "attachmentList" }, { "jsonSchema": { "type": [ "object", "null" ], "additionalProperties": { "description": "A record value." }, "description": "Raw Gmail payload object, or null when it was not included." }, "nullable": true, "handle": "payload" } ], "outputs": [ { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "missing" }, { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "remote" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "attachmentId" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "filename" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "mimeType" }, { "jsonSchema": { "type": "integer", "minimum": 0, "maximum": 52428800, "description": "Attachment size in bytes returned in message metadata." }, "nullable": false, "handle": "size" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "inline" } ], "name": "Select the first attachment", "moduleId": "n_8d8b0dd6bc37dee2", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_6430a885c3e19e25": { "inputs": {}, "name": "Download attachment?", "kind": "condition", "matchMode": "first", "cases": [ { "output": "download", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_48d05db2cfed46ac", "output": "remote" } }, "operator": "isTrue" } ] } ] } ] }, "n_0e6fc60da9c42d27": { "inputs": { "messageId": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_e921b815c88c3ab6", "output": "messageId" } ] }, "attachmentId": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_48d05db2cfed46ac", "output": "attachmentId" } ] }, "filename": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_48d05db2cfed46ac", "output": "filename" } ] }, "mimeType": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_48d05db2cfed46ac", "output": "mimeType" } ] }, "size": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_48d05db2cfed46ac", "output": "size" } ] } }, "name": "Download the attachment", "kind": "task", "task": { "inputs": [ { "description": "Gmail message ID.", "jsonSchema": { "type": "string", "description": "Gmail message ID." }, "nullable": false, "handle": "messageId" }, { "description": "Gmail attachment ID returned in message attachment metadata.", "jsonSchema": { "type": "string", "description": "Gmail attachment ID returned in message attachment metadata." }, "nullable": false, "handle": "attachmentId" }, { "description": "Attachment filename returned in message metadata.", "jsonSchema": { "type": "string", "description": "Attachment filename returned in message metadata." }, "nullable": false, "handle": "filename" }, { "description": "Attachment MIME type returned in message metadata.", "jsonSchema": { "type": "string", "description": "Attachment MIME type returned in message metadata." }, "nullable": false, "handle": "mimeType" }, { "description": "Attachment size in bytes returned in message metadata.", "jsonSchema": { "type": "integer", "minimum": 0, "maximum": 52428800, "description": "Attachment size in bytes returned in message metadata." }, "nullable": false, "handle": "size" } ], "outputs": [ { "description": "Gmail message ID.", "jsonSchema": { "type": "string", "description": "Gmail message ID." }, "nullable": false, "handle": "messageId" }, { "description": "Gmail attachment ID returned in message attachment metadata.", "jsonSchema": { "type": "string", "description": "Gmail attachment ID returned in message attachment metadata." }, "nullable": false, "handle": "attachmentId" }, { "description": "Attachment filename returned in message metadata.", "jsonSchema": { "type": "string", "description": "Attachment filename returned in message metadata." }, "nullable": false, "handle": "filename" }, { "description": "Attachment MIME type returned in message metadata.", "jsonSchema": { "type": "string", "description": "Attachment MIME type returned in message metadata." }, "nullable": false, "handle": "mimeType" }, { "description": "Downloaded attachment size in bytes.", "jsonSchema": { "type": "integer", "description": "Downloaded attachment size in bytes." }, "nullable": false, "handle": "sizeBytes" }, { "description": "Temporary Connector file transit URL for downloading the attachment.", "jsonSchema": { "type": "string", "format": "uri", "description": "Temporary Connector file transit URL for downloading the attachment." }, "nullable": false, "handle": "transitUrl" } ], "name": "Download the attachment", "executor": { "kind": "connector", "action": "gmail.download_attachment" } } }, "n_ba1dc91fac6dd2a4": { "inputs": { "missing": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_48d05db2cfed46ac", "output": "missing" } ] }, "remote": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_48d05db2cfed46ac", "output": "remote" } ] }, "inline": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_48d05db2cfed46ac", "output": "inline" } ] }, "transitUrl": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_0e6fc60da9c42d27", "output": "transitUrl" } ] }, "size": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_48d05db2cfed46ac", "output": "size" } ] }, "messageId": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_e921b815c88c3ab6", "output": "messageId" } ] }, "attachmentId": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_48d05db2cfed46ac", "output": "attachmentId" } ] }, "downloadedMessageId": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_0e6fc60da9c42d27", "output": "messageId" } ] }, "downloadedAttachmentId": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_0e6fc60da9c42d27", "output": "attachmentId" } ] }, "downloadedSize": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_0e6fc60da9c42d27", "output": "sizeBytes" } ] }, "filename": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_48d05db2cfed46ac", "output": "filename" } ] }, "mimeType": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_48d05db2cfed46ac", "output": "mimeType" } ] } }, "name": "Check attachment bytes", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "missing" }, { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "remote" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "inline" }, { "jsonSchema": { "type": "string", "format": "uri", "description": "Temporary Connector file transit URL for downloading the attachment." }, "nullable": true, "handle": "transitUrl" }, { "jsonSchema": { "type": "integer", "minimum": 0 }, "nullable": false, "handle": "size" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "messageId" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "attachmentId" }, { "jsonSchema": { "type": "string", "description": "Gmail message ID." }, "nullable": true, "handle": "downloadedMessageId" }, { "jsonSchema": { "type": "string", "description": "Gmail attachment ID returned in message attachment metadata." }, "nullable": true, "handle": "downloadedAttachmentId" }, { "jsonSchema": { "type": "integer", "description": "Downloaded attachment size in bytes." }, "nullable": true, "handle": "downloadedSize" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "filename" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "mimeType" } ], "outputs": [ { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "attachment" } ], "name": "Check attachment bytes", "moduleId": "n_c15c1dbbcedbbcaf", "capabilities": [ { "kind": "http", "hosts": [ "example.com" ] } ] } }, "n_60190b97722be119": { "inputs": { "files": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_e921b815c88c3ab6", "output": "files" } ] }, "previousState": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_60190b97722be119", "output": "state" } ] }, "folderId": { "kind": "value", "value": "YOUR_DRIVE_FOLDER_ID" } }, "name": "Prepare the next file", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "array", "items": { "type": "object", "additionalProperties": true } }, "nullable": false, "handle": "files" }, { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": true, "handle": "previousState" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "folderId" } ], "outputs": [ { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "state" }, { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "more" }, { "jsonSchema": { "type": "string", "minLength": 1, "description": "The name of the file." }, "nullable": true, "handle": "name" }, { "jsonSchema": { "type": "string", "minLength": 1, "description": "The MIME type of the file." }, "nullable": true, "handle": "mimeType" }, { "jsonSchema": { "type": "string", "minLength": 1, "description": "Connector media upload content encoded as a Base64 string." }, "nullable": true, "handle": "contentBase64" }, { "jsonSchema": { "type": "array", "items": { "type": "string", "minLength": 1, "description": "Schema for nonEmptyString." }, "minItems": 1, "description": "A list of parent folder IDs to place the file in." }, "nullable": true, "handle": "parents" } ], "name": "Prepare the next file", "moduleId": "n_b9a97179fa14db9f", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_8787dbf4ea34c1cb": { "inputs": {}, "name": "More files?", "kind": "condition", "matchMode": "first", "cases": [ { "output": "upload", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_60190b97722be119", "output": "more" } }, "operator": "isTrue" } ] } ] } ] }, "n_255f78080cb8ad11": { "inputs": { "name": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_60190b97722be119", "output": "name" } ] }, "mimeType": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_60190b97722be119", "output": "mimeType" } ] }, "contentBase64": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_60190b97722be119", "output": "contentBase64" } ] }, "parents": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_60190b97722be119", "output": "parents" } ] } }, "name": "Upload to Google Drive", "kind": "task", "task": { "inputs": [ { "description": "The name of the file.", "jsonSchema": { "type": "string", "minLength": 1, "description": "The name of the file." }, "nullable": true, "handle": "name", "value": null }, { "description": "The MIME type of the file.", "jsonSchema": { "type": "string", "minLength": 1, "description": "The MIME type of the file." }, "nullable": true, "handle": "mimeType", "value": null }, { "description": "A short description of the file.", "jsonSchema": { "type": "string", "minLength": 1, "description": "A short description of the file." }, "nullable": true, "handle": "description", "value": null }, { "description": "A list of parent folder IDs to place the file in.", "jsonSchema": { "type": "array", "items": { "type": "string", "minLength": 1, "description": "Schema for nonEmptyString." }, "minItems": 1, "description": "A list of parent folder IDs to place the file in." }, "nullable": true, "handle": "parents", "value": null }, { "description": "Whether the user has starred the file.", "jsonSchema": { "type": "boolean", "description": "Whether the user has starred the file." }, "nullable": true, "handle": "starred", "value": null }, { "description": "A collection of arbitrary key-value pairs which are private to the requesting app.", "jsonSchema": { "type": "object", "additionalProperties": { "type": "string", "description": "A record value." }, "description": "A collection of arbitrary key-value pairs which are private to the requesting app." }, "nullable": true, "handle": "appProperties", "value": null }, { "description": "A collection of arbitrary key-value pairs which are visible to all apps.", "jsonSchema": { "type": "object", "additionalProperties": { "type": "string", "description": "A record value." }, "description": "A collection of arbitrary key-value pairs which are visible to all apps." }, "nullable": true, "handle": "properties", "value": null }, { "description": "Connector media upload content encoded as a Base64 string.", "jsonSchema": { "type": "string", "minLength": 1, "description": "Connector media upload content encoded as a Base64 string." }, "nullable": true, "handle": "contentBase64", "value": null }, { "description": "Connector text media upload content.", "jsonSchema": { "type": "string", "description": "Connector text media upload content." }, "nullable": true, "handle": "text", "value": null } ], "outputs": [ { "description": "The unique identifier of the file.", "jsonSchema": { "type": "string", "description": "The unique identifier of the file." }, "nullable": false, "handle": "id" }, { "description": "The name of the file.", "jsonSchema": { "type": "string", "description": "The name of the file." }, "nullable": false, "handle": "name" }, { "description": "The MIME type of the file.", "jsonSchema": { "type": "string", "description": "The MIME type of the file." }, "nullable": false, "handle": "mimeType" }, { "description": "A link for opening the file in a relevant Google editor or viewer in a browser.", "jsonSchema": { "type": [ "string", "null" ], "description": "A link for opening the file in a relevant Google editor or viewer in a browser." }, "nullable": true, "handle": "webViewLink" }, { "description": "The time at which the file was created (RFC 3339 date-time).", "jsonSchema": { "type": [ "string", "null" ], "description": "The time at which the file was created (RFC 3339 date-time)." }, "nullable": true, "handle": "createdTime" }, { "description": "The last time the file was modified by anyone (RFC 3339 date-time).", "jsonSchema": { "type": [ "string", "null" ], "description": "The last time the file was modified by anyone (RFC 3339 date-time)." }, "nullable": true, "handle": "modifiedTime" }, { "description": "The size of the file's content in bytes.", "jsonSchema": { "type": [ "integer", "null" ], "description": "The size of the file's content in bytes." }, "nullable": true, "handle": "sizeBytes" }, { "description": "The ID of the shared drive the file belongs to.", "jsonSchema": { "type": [ "string", "null" ], "description": "The ID of the shared drive the file belongs to." }, "nullable": true, "handle": "driveId" }, { "description": "The IDs of the parent folders containing the file.", "jsonSchema": { "type": "array", "items": { "type": "string", "description": "An array item." }, "description": "The IDs of the parent folders containing the file." }, "nullable": true, "handle": "parents" }, { "description": "The owners of the file.", "jsonSchema": { "type": "array", "items": { "type": "object", "properties": { "displayName": { "type": [ "string", "null" ], "description": "The display name of the owner." }, "emailAddress": { "type": [ "string", "null" ], "description": "The email address of the owner." }, "permissionId": { "type": [ "string", "null" ], "description": "The permission ID of the owner." }, "photoLink": { "type": [ "string", "null" ], "description": "A link to the owner's profile photo." } }, "required": [ "displayName", "emailAddress", "permissionId", "photoLink" ], "additionalProperties": false, "description": "Schema for driveOwnerSchema." }, "description": "The owners of the file." }, "nullable": true, "handle": "owners" }, { "description": "Whether the file has been shared.", "jsonSchema": { "type": "boolean", "description": "Whether the file has been shared." }, "nullable": true, "handle": "shared" }, { "description": "Whether the user has starred the file.", "jsonSchema": { "type": "boolean", "description": "Whether the user has starred the file." }, "nullable": true, "handle": "starred" }, { "description": "Whether the file has been trashed.", "jsonSchema": { "type": "boolean", "description": "Whether the file has been trashed." }, "nullable": true, "handle": "trashed" }, { "description": "Whether the authenticated user owns the file.", "jsonSchema": { "type": "boolean", "description": "Whether the authenticated user owns the file." }, "nullable": true, "handle": "ownedByMe" }, { "description": "The projected Drive capabilities for the authenticated user.", "jsonSchema": { "type": "object", "properties": { "canShare": { "type": "boolean", "description": "Whether the authenticated user may modify sharing settings." } }, "required": [ "canShare" ], "additionalProperties": false, "description": "The projected Drive capabilities for the authenticated user." }, "nullable": true, "handle": "capabilities" } ], "name": "Upload to Google Drive", "executor": { "kind": "connector", "action": "googledrive.files.create" } } }, "n_16630f85b8f3c52e": { "inputs": { "id": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_255f78080cb8ad11", "output": "id" } ] }, "webViewLink": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_255f78080cb8ad11", "output": "webViewLink" } ] } }, "name": "Confirm Drive link", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string", "description": "The unique identifier of the file." }, "nullable": false, "handle": "id" }, { "jsonSchema": { "type": [ "string", "null" ], "description": "A link for opening the file in a relevant Google editor or viewer in a browser." }, "nullable": true, "handle": "webViewLink" } ], "outputs": [ { "jsonSchema": { "type": "string" }, "nullable": true, "handle": "link" } ], "name": "Confirm Drive link", "moduleId": "n_03e9a3b0f4f20bc0", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } } }, "edges": [ { "source": "n_7dad464fc2627b2b", "target": "n_c2916405b6b8437d" }, { "source": "n_c2916405b6b8437d", "target": "n_e921b815c88c3ab6" }, { "source": "n_e921b815c88c3ab6", "target": "n_a844278c4e42400b" }, { "source": "n_a844278c4e42400b", "target": "n_9e91b6dc440ed10f", "sourceHandle": "read" }, { "source": "n_9e91b6dc440ed10f", "target": "n_48d05db2cfed46ac" }, { "source": "n_48d05db2cfed46ac", "target": "n_6430a885c3e19e25" }, { "source": "n_6430a885c3e19e25", "target": "n_0e6fc60da9c42d27", "sourceHandle": "download" }, { "source": "n_6430a885c3e19e25", "target": "n_ba1dc91fac6dd2a4", "sourceHandle": "otherwise" }, { "source": "n_0e6fc60da9c42d27", "target": "n_ba1dc91fac6dd2a4" }, { "source": "n_ba1dc91fac6dd2a4", "target": "n_e921b815c88c3ab6" }, { "source": "n_a844278c4e42400b", "target": "n_60190b97722be119", "sourceHandle": "otherwise" }, { "source": "n_60190b97722be119", "target": "n_8787dbf4ea34c1cb" }, { "source": "n_8787dbf4ea34c1cb", "target": "n_255f78080cb8ad11", "sourceHandle": "upload" }, { "source": "n_255f78080cb8ad11", "target": "n_16630f85b8f3c52e" }, { "source": "n_16630f85b8f3c52e", "target": "n_60190b97722be119" } ] } }, "modules": { "n_93bb450c7a6c105e": { "name": "Prepare the next email", "imports": [], "source": "export default function next({messages,previousState,attachment}){if(!Array.isArray(messages)||messages.length>10||messages.some(x=>typeof x?.messageId!=='string'||!x.messageId)||new Set(messages.map(x=>x.messageId)).size!==messages.length)throw Error('Invalid Gmail list');let state=previousState??{index:0,files:[]};if(attachment!==null&&attachment!==undefined){if(state.index>=messages.length||attachment.messageId!==messages[state.index].messageId)throw Error('Message association failed');state={index:state.index+1,files:[...state.files,attachment]};}if(state.index>messages.length||state.files.length!==state.index)throw Error('Invalid progress');return{state,more:state.index52428800||typeof a.filename!=='string')throw Error('Invalid attachment');let inline='';if(!a.attachmentId){const found=[];const walk=p=>{if(!p||typeof p!=='object')return;if(p.partId===a.partId&&typeof p.body?.data==='string')found.push(p.body.data);for(const c of p.parts||[])walk(c)};if(a.partId==null)throw Error('Missing part ID');walk(payload);if(found.length!==1)throw Error('Missing or ambiguous inline part');inline=found[0]}return{missing:false,remote:!!a.attachmentId,attachmentId:a.attachmentId||'',filename:a.filename,mimeType:a.mimeType||'application/octet-stream',size:a.size,inline}}\n" }, "n_c15c1dbbcedbbcaf": { "name": "Check attachment bytes", "imports": [], "source": "import{Buffer}from'node:buffer';\nexport default async function stage({missing,remote,inline,transitUrl,size,messageId,attachmentId,downloadedMessageId,downloadedAttachmentId,downloadedSize,filename,mimeType},context){if(missing)return{attachment:{messageId,missing:true}};let bytes;if(remote){if(downloadedMessageId!==messageId||downloadedAttachmentId!==attachmentId||downloadedSize!==size||typeof transitUrl!=='string'||!/^https:\\/\\//.test(transitUrl))throw Error('Attachment association failed');const r=await context.fetch(transitUrl,{method:'GET'});if(!r.ok)throw Error('Attachment download failed');bytes=Buffer.from(await r.arrayBuffer())}else{if(typeof inline!=='string'||!/^[A-Za-z0-9_-]*={0,2}$/.test(inline))throw Error('Invalid inline content');const s=inline.replace(/-/g,'+').replace(/_/g,'/').replace(/=+$/,'');bytes=Buffer.from(s,'base64');if(bytes.toString('base64').replace(/=+$/,'')!==s)throw Error('Invalid base64')}if(bytes.length!==size)throw Error('Incomplete attachment');return{attachment:{messageId,missing:false,filename,mimeType,contentBase64:bytes.length?bytes.toString('base64'):null}}}\n" }, "n_b9a97179fa14db9f": { "name": "Prepare the next file", "imports": [], "source": "export default function next({files,previousState,folderId}){if(!Array.isArray(files)||files.length>10)throw Error('Configure the Drive folder');const i=previousState===null?0:previousState.index+1;if(!Number.isInteger(i)||i<0||i>files.length)throw Error('Invalid progress');const f=files[i];if(f&&(typeof folderId!=='string'||!folderId.trim()||folderId==='YOUR_DRIVE_FOLDER_ID'))throw Error('Configure the Drive folder');if(f?.missing)throw Error('Message has no first attachment');return{state:{index:i},more:i