{ "kind": "open-flow-workflow", "version": 1, "name": "Email a Calendar Invitation", "content": { "modelVersion": 14, "document": { "bindings": {}, "graph": { "nodes": { "n_407465484f19bcd1": { "name": "Start manually", "kind": "start", "inputDefs": [] }, "n_4bd4f87f31e8a969": { "inputs": { "title": { "kind": "value", "value": "YOUR_EVENT_TITLE" }, "start": { "kind": "value", "value": "YOUR_START_UTC" }, "end": { "kind": "value", "value": "YOUR_END_UTC" } }, "name": "Create calendar event file", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "title" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "start" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "end" } ], "outputs": [ { "jsonSchema": { "type": "array", "items": { "type": "object", "properties": { "contentBase64": { "type": "string", "minLength": 1, "description": "The Base64-encoded attachment content." }, "filename": { "type": "string", "minLength": 1, "description": "The attachment file name." }, "type": { "type": "string", "minLength": 1, "description": "The optional attachment MIME type." }, "disposition": { "type": "string", "enum": [ "attachment", "inline" ], "description": "The optional attachment disposition." }, "contentId": { "type": "string", "minLength": 1, "description": "The optional content ID used for inline attachments." } }, "required": [ "contentBase64", "filename" ], "additionalProperties": false, "description": "One attachment accepted by the SendGrid Mail Send API." }, "description": "The optional attachments included with this email." }, "nullable": false, "handle": "attachments" }, { "jsonSchema": { "type": "string", "minLength": 1, "description": "The email subject line." }, "nullable": true, "handle": "subject" } ], "name": "Create calendar event file", "moduleId": "n_a96d3ee4355489ae", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_c606489f7e54a920": { "inputs": { "from": { "kind": "value", "value": { "email": "YOUR_VERIFIED_SENDER" } }, "to": { "kind": "value", "value": [ { "email": "YOUR_RECIPIENT_EMAIL" } ] }, "subject": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_4bd4f87f31e8a969", "output": "subject" } ] }, "textContent": { "kind": "value", "value": "Please find the calendar event attached." }, "attachments": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_4bd4f87f31e8a969", "output": "attachments" } ] } }, "name": "Email the invitation", "kind": "task", "task": { "inputs": [ { "description": "The verified sender used for this email.", "jsonSchema": { "type": "object", "properties": { "email": { "type": "string", "format": "email", "description": "The sender email address." }, "name": { "type": "string", "minLength": 1, "description": "The optional sender display name." } }, "required": [ "email" ], "additionalProperties": false, "description": "The verified sender used for this email." }, "nullable": false, "handle": "from" }, { "description": "The primary recipients for this email.", "jsonSchema": { "type": "array", "items": { "type": "object", "properties": { "email": { "type": "string", "format": "email", "description": "The recipient email address." }, "name": { "type": "string", "minLength": 1, "description": "The optional recipient display name." } }, "required": [ "email" ], "additionalProperties": false, "description": "One SendGrid email recipient." }, "minItems": 1, "description": "The primary recipients for this email." }, "nullable": false, "handle": "to" }, { "description": "The optional Cc recipients.", "jsonSchema": { "type": "array", "items": { "type": "object", "properties": { "email": { "type": "string", "format": "email", "description": "The recipient email address." }, "name": { "type": "string", "minLength": 1, "description": "The optional recipient display name." } }, "required": [ "email" ], "additionalProperties": false, "description": "One SendGrid email recipient." }, "minItems": 1, "description": "The optional Cc recipients." }, "nullable": true, "handle": "cc", "value": null }, { "description": "The optional Bcc recipients.", "jsonSchema": { "type": "array", "items": { "type": "object", "properties": { "email": { "type": "string", "format": "email", "description": "The recipient email address." }, "name": { "type": "string", "minLength": 1, "description": "The optional recipient display name." } }, "required": [ "email" ], "additionalProperties": false, "description": "One SendGrid email recipient." }, "minItems": 1, "description": "The optional Bcc recipients." }, "nullable": true, "handle": "bcc", "value": null }, { "description": "The optional Reply-To override.", "jsonSchema": { "type": "object", "properties": { "email": { "type": "string", "format": "email", "description": "The sender email address." }, "name": { "type": "string", "minLength": 1, "description": "The optional sender display name." } }, "required": [ "email" ], "additionalProperties": false, "description": "The optional Reply-To override." }, "nullable": true, "handle": "replyTo", "value": null }, { "description": "The email subject line.", "jsonSchema": { "type": "string", "minLength": 1, "description": "The email subject line." }, "nullable": true, "handle": "subject", "value": null }, { "description": "The optional HTML body content.", "jsonSchema": { "type": "string", "description": "The optional HTML body content." }, "nullable": true, "handle": "htmlContent", "value": null }, { "description": "The optional plain-text body content.", "jsonSchema": { "type": "string", "description": "The optional plain-text body content." }, "nullable": true, "handle": "textContent", "value": null }, { "description": "The optional SendGrid template ID.", "jsonSchema": { "type": "string", "minLength": 1, "description": "The optional SendGrid template ID." }, "nullable": true, "handle": "templateId", "value": null }, { "description": "The optional dynamic template data sent with the email.", "jsonSchema": { "type": "object", "properties": {}, "additionalProperties": true, "description": "The optional dynamic template data sent with the email." }, "nullable": true, "handle": "dynamicTemplateData", "value": null }, { "description": "The optional SendGrid categories attached to this email.", "jsonSchema": { "type": "array", "items": { "type": "string", "minLength": 1, "description": "One SendGrid category name." }, "maxItems": 10, "description": "The optional SendGrid categories attached to this email." }, "nullable": true, "handle": "categories", "value": null }, { "description": "The optional custom arguments attached to this email.", "jsonSchema": { "type": "object", "additionalProperties": { "type": "string", "description": "A record value." }, "description": "The optional custom arguments attached to this email." }, "nullable": true, "handle": "customArgs", "value": null }, { "description": "The optional Unix timestamp that schedules this email.", "jsonSchema": { "type": "integer", "exclusiveMinimum": 0, "description": "The optional Unix timestamp that schedules this email." }, "nullable": true, "handle": "sendAt", "value": null }, { "description": "The optional attachments included with this email.", "jsonSchema": { "type": "array", "items": { "type": "object", "properties": { "contentBase64": { "type": "string", "minLength": 1, "description": "The Base64-encoded attachment content." }, "filename": { "type": "string", "minLength": 1, "description": "The attachment file name." }, "type": { "type": "string", "minLength": 1, "description": "The optional attachment MIME type." }, "disposition": { "type": "string", "enum": [ "attachment", "inline" ], "description": "The optional attachment disposition." }, "contentId": { "type": "string", "minLength": 1, "description": "The optional content ID used for inline attachments." } }, "required": [ "contentBase64", "filename" ], "additionalProperties": false, "description": "One attachment accepted by the SendGrid Mail Send API." }, "description": "The optional attachments included with this email." }, "nullable": true, "handle": "attachments", "value": null } ], "outputs": [ { "description": "Whether SendGrid accepted the email for delivery.", "jsonSchema": { "type": "boolean", "description": "Whether SendGrid accepted the email for delivery." }, "nullable": false, "handle": "accepted" }, { "description": "The optional SendGrid message ID response header.", "jsonSchema": { "type": [ "string", "null" ], "description": "The optional SendGrid message ID response header." }, "nullable": true, "handle": "messageId" } ], "name": "Email the invitation", "executor": { "kind": "connector", "action": "sendgrid.send_email" } } } }, "edges": [ { "source": "n_407465484f19bcd1", "target": "n_4bd4f87f31e8a969" }, { "source": "n_4bd4f87f31e8a969", "target": "n_c606489f7e54a920" } ] } }, "modules": { "n_a96d3ee4355489ae": { "name": "Create calendar event file", "imports": [], "source": "export default function invitation({title,start,end}){\n if(typeof title!=='string'||!title.trim())throw Error('Set an event title');\n const date=x=>{if(typeof x!=='string'||!/^\\d{4}-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\dZ$/.test(x)||!Number.isFinite(Date.parse(x))||new Date(x).toISOString().replace('.000Z','Z')!==x)throw Error('Use valid UTC event dates like 2030-06-11T15:30:00Z');return new Date(x)};\n const a=date(start),b=date(end);if(b<=a)throw Error('End must follow start');const stamp=d=>d.toISOString().replace(/[-:]/g,'').replace(/\\.\\d{3}Z$/,'Z'),escape=s=>s.replace(/\\\\/g,'\\\\\\\\').replace(/\\r\\n|\\r|\\n/g,'\\\\n').replace(/,/g,'\\\\,').replace(/;/g,'\\\\;');\n const fold=s=>{let out='',line='';for(const c of s){if(Buffer.from(line+c,'utf8').length>75){out+=line+'\\r\\n';line=' '+c}else line+=c}return out+line};\n const uid=Date.now().toString(36)+'-'+Math.random().toString(36).slice(2)+'@openflow.local';const data=['BEGIN:VCALENDAR','VERSION:2.0','PRODID:-//Open Flow//Calendar Invitation//EN','CALSCALE:GREGORIAN','METHOD:PUBLISH','BEGIN:VEVENT','UID:'+uid,'DTSTAMP:'+stamp(new Date()),'DTSTART:'+stamp(a),'DTEND:'+stamp(b),'SUMMARY:'+escape(title),'END:VEVENT','END:VCALENDAR'].map(fold).join('\\r\\n')+'\\r\\n';return {attachments:[{filename:'invite.ics',type:'text/calendar',contentBase64:Buffer.from(data,'utf8').toString('base64')}],subject:title.replace(/[\\r\\n]+/g,' ')};\n}\n" } } }, "presentation": { "designer": { "version": 1, "flow": { "direction": "vertical" } } } }