{ "kind": "open-flow-workflow", "version": 1, "name": "Email the Latest GitHub Release Notes", "content": { "modelVersion": 14, "document": { "bindings": {}, "graph": { "nodes": { "n_7ced6a6d6789d59a": { "name": "Every day at 00:00 UTC", "kind": "cron", "cronTimes": [ { "type": "cron", "expression": "0 0 * * *", "timezone": "UTC" } ] }, "n_d23520a8e9cecaa6": { "inputs": { "owner": { "kind": "value", "value": "n8n-io" }, "repo": { "kind": "value", "value": "n8n" } }, "name": "Get the latest release", "kind": "task", "task": { "inputs": [ { "description": "The repository owner.", "jsonSchema": { "type": "string", "minLength": 1, "description": "The repository owner." }, "nullable": false, "handle": "owner" }, { "description": "The repository name.", "jsonSchema": { "type": "string", "minLength": 1, "description": "The repository name." }, "nullable": false, "handle": "repo" } ], "outputs": [ { "description": "A GitHub release record.", "jsonSchema": { "type": "object", "properties": { "id": { "type": "integer", "description": "The release ID." }, "tag_name": { "type": "string", "description": "The release tag name." }, "name": { "type": [ "string", "null" ], "description": "The release name." }, "body": { "type": [ "string", "null" ], "description": "The release body." }, "draft": { "type": "boolean", "description": "Whether the release is a draft." }, "prerelease": { "type": "boolean", "description": "Whether the release is a prerelease." }, "html_url": { "type": "string", "description": "The release URL." }, "assets_url": { "type": "string", "description": "The assets API URL." }, "tarball_url": { "type": [ "string", "null" ], "description": "The tarball download URL." }, "zipball_url": { "type": [ "string", "null" ], "description": "The zipball download URL." }, "target_commitish": { "type": "string", "description": "The target branch or commit SHA." }, "author": { "type": "object", "properties": { "id": { "type": "integer", "description": "The user ID." }, "login": { "type": "string", "description": "The username." }, "avatar_url": { "type": "string", "description": "The avatar URL." }, "html_url": { "type": "string", "description": "The profile URL." }, "type": { "type": "string", "description": "The account type." } }, "required": [ "id", "login" ], "additionalProperties": true, "description": "The release author." }, "created_at": { "type": "string", "description": "The creation timestamp." }, "published_at": { "type": [ "string", "null" ], "description": "The publication timestamp." } }, "required": [ "id", "tag_name" ], "additionalProperties": true, "description": "A GitHub release record." }, "nullable": false, "handle": "output" } ], "name": "Get the latest release", "executor": { "kind": "connector", "action": "github.get_latest_release", "outputMode": "value" } } }, "n_4b6d79e2a56cce08": { "inputs": { "release": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_d23520a8e9cecaa6", "output": "output" } ] } }, "name": "Prepare release notes", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "object", "properties": { "id": { "type": "integer", "description": "The release ID." }, "tag_name": { "type": "string", "description": "The release tag name." }, "name": { "type": [ "string", "null" ], "description": "The release name." }, "body": { "type": [ "string", "null" ], "description": "The release body." }, "draft": { "type": "boolean", "description": "Whether the release is a draft." }, "prerelease": { "type": "boolean", "description": "Whether the release is a prerelease." }, "html_url": { "type": "string", "description": "The release URL." }, "assets_url": { "type": "string", "description": "The assets API URL." }, "tarball_url": { "type": [ "string", "null" ], "description": "The tarball download URL." }, "zipball_url": { "type": [ "string", "null" ], "description": "The zipball download URL." }, "target_commitish": { "type": "string", "description": "The target branch or commit SHA." }, "author": { "type": "object", "properties": { "id": { "type": "integer", "description": "The user ID." }, "login": { "type": "string", "description": "The username." }, "avatar_url": { "type": "string", "description": "The avatar URL." }, "html_url": { "type": "string", "description": "The profile URL." }, "type": { "type": "string", "description": "The account type." } }, "required": [ "id", "login" ], "additionalProperties": true, "description": "The release author." }, "created_at": { "type": "string", "description": "The creation timestamp." }, "published_at": { "type": [ "string", "null" ], "description": "The publication timestamp." } }, "required": [ "id", "tag_name" ], "additionalProperties": true, "description": "A GitHub release record." }, "nullable": false, "handle": "release" } ], "outputs": [ { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "body" }, { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "hasBody" } ], "name": "Prepare release notes", "moduleId": "n_e97a5a11559e27a6", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_ab0ba5527ff8091e": { "inputs": {}, "name": "Release body present?", "kind": "condition", "matchMode": "first", "cases": [ { "output": "render", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_4b6d79e2a56cce08", "output": "hasBody" } }, "operator": "isTrue" } ] } ] } ] }, "n_6c77d296c63907e3": { "inputs": { "endpoint": { "kind": "value", "value": "/markdown" }, "body": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_4b6d79e2a56cce08", "output": "body" } ] } }, "name": "Render Markdown", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "endpoint" }, { "jsonSchema": {}, "nullable": true, "handle": "body" } ], "outputs": [ { "jsonSchema": {}, "nullable": true, "handle": "body" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "statusCode" }, { "jsonSchema": { "type": "object", "additionalProperties": { "type": "string" } }, "nullable": false, "handle": "headers" }, { "jsonSchema": { "const": "base64" }, "nullable": true, "handle": "bodyEncoding" } ], "name": "Render Markdown", "executor": { "providerId": "github", "method": "POST", "query": { "mode": "fields", "names": [] }, "headers": { "mode": "fields", "names": [] }, "bodyFormat": "json", "kind": "connector-proxy" } } }, "n_4b8a1d569c2f8e22": { "inputs": { "body": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_6c77d296c63907e3", "output": "body" } ] }, "statusCode": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_6c77d296c63907e3", "output": "statusCode" } ] }, "bodyEncoding": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_6c77d296c63907e3", "output": "bodyEncoding" } ] } }, "name": "Check rendered HTML", "kind": "task", "task": { "inputs": [ { "jsonSchema": {}, "nullable": true, "handle": "body" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "statusCode" }, { "jsonSchema": { "const": "base64" }, "nullable": true, "handle": "bodyEncoding" } ], "outputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "html" } ], "name": "Check rendered HTML", "moduleId": "n_3203793362b61023", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_33d6e115eeb5409c": { "inputs": { "to": { "kind": "value", "value": "recipient@example.com" }, "subject": { "kind": "value", "value": "Latest GitHub release notes" }, "body": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_4b8a1d569c2f8e22", "output": "html" } ] }, "isHtml": { "kind": "value", "value": true } }, "name": "Email the release notes", "kind": "task", "task": { "inputs": [ { "description": "Primary recipient email address.", "jsonSchema": { "type": "string", "description": "Primary recipient email address." }, "nullable": true, "handle": "to", "value": null }, { "description": "Additional To recipients.", "jsonSchema": { "type": "array", "items": { "type": "string", "description": "An array item." }, "description": "Additional To recipients." }, "nullable": true, "handle": "extraRecipients", "value": null }, { "description": "Cc recipients.", "jsonSchema": { "anyOf": [ { "type": "string", "description": "A union variant." }, { "type": "array", "items": { "type": "string", "description": "An array item." }, "description": "A union variant." } ], "description": "Cc recipients." }, "nullable": true, "handle": "cc", "value": null }, { "description": "Bcc recipients.", "jsonSchema": { "anyOf": [ { "type": "string", "description": "A union variant." }, { "type": "array", "items": { "type": "string", "description": "An array item." }, "description": "A union variant." } ], "description": "Bcc recipients." }, "nullable": true, "handle": "bcc", "value": null }, { "description": "Email subject line.", "jsonSchema": { "type": "string", "description": "Email subject line." }, "nullable": true, "handle": "subject", "value": null }, { "description": "Email body content.", "jsonSchema": { "type": "string", "description": "Email body content." }, "nullable": true, "handle": "body", "value": null }, { "description": "Set to true when the body content is already HTML.", "jsonSchema": { "type": "boolean", "description": "Set to true when the body content is already HTML." }, "nullable": true, "handle": "isHtml", "value": null }, { "description": "Attachments and CID inline images. Up to 25,000,000 decoded bytes in total and 35,000,000 MIME bytes.", "jsonSchema": { "type": "array", "items": { "type": "object", "properties": { "filename": { "type": "string", "description": "Attachment filename; omit for an unnamed attachment." }, "mimeType": { "type": "string", "description": "MIME type without parameters; defaults to application/octet-stream." }, "contentBase64": { "type": "string", "description": "Standard padded Base64 content. Empty string represents a zero-byte file. Supply this or fileUrl." }, "fileUrl": { "type": "string", "format": "uri", "description": "Public URL to download the attachment. Supply this or contentBase64." }, "contentId": { "type": "string", "minLength": 1, "description": "Bare Content-ID without cid: or angle brackets; reference it as cid: in HTML." }, "disposition": { "type": "string", "enum": [ "inline", "attachment" ], "description": "Defaults to inline when contentId is set, otherwise attachment. Inline requires contentId." } }, "additionalProperties": false, "description": "An attachment or CID inline resource.", "oneOf": [ { "required": [ "contentBase64" ] }, { "required": [ "fileUrl" ] } ] }, "maxItems": 100, "description": "Attachments and CID inline images. Up to 25,000,000 decoded bytes in total and 35,000,000 MIME bytes." }, "nullable": true, "handle": "attachments", "value": null }, { "description": "Verified Gmail send-as alias to use in the From header.", "jsonSchema": { "type": "string", "description": "Verified Gmail send-as alias to use in the From header." }, "nullable": true, "handle": "fromEmail", "value": null } ], "outputs": [ { "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": true, "handle": "threadId" } ], "name": "Email the release notes", "executor": { "kind": "connector", "action": "gmail.send_email" } } } }, "edges": [ { "source": "n_7ced6a6d6789d59a", "target": "n_d23520a8e9cecaa6" }, { "source": "n_d23520a8e9cecaa6", "target": "n_4b6d79e2a56cce08" }, { "source": "n_4b6d79e2a56cce08", "target": "n_ab0ba5527ff8091e" }, { "source": "n_ab0ba5527ff8091e", "target": "n_6c77d296c63907e3", "sourceHandle": "render" }, { "source": "n_6c77d296c63907e3", "target": "n_4b8a1d569c2f8e22" }, { "source": "n_4b8a1d569c2f8e22", "target": "n_33d6e115eeb5409c" } ] } }, "modules": { "n_e97a5a11559e27a6": { "name": "Prepare release notes", "imports": [], "source": "export default function prepare({release}) {if(!release||typeof release!=='object'||!(typeof release.body==='string'||release.body==null))throw Error('Invalid release notes');return {hasBody:Object.hasOwn(release,'body'),body:{text:release.body??'',mode:'markdown'}};}\n" }, "n_3203793362b61023": { "name": "Check rendered HTML", "imports": [], "source": "export default function html({body,statusCode,bodyEncoding}) {if(statusCode<200||statusCode>=300||bodyEncoding!==null)throw Error('Markdown rendering failed');if(body===null)return {html:''};if(typeof body!=='string')throw Error('Markdown rendering did not return HTML');return {html:body};}\n" } } }, "presentation": { "designer": { "version": 1, "flow": { "direction": "vertical" } } } }