{ "kind": "open-flow-workflow", "version": 1, "name": "Email a Random Open Library Book", "content": { "modelVersion": 14, "document": { "bindings": {}, "graph": { "nodes": { "n_0b7e1d48f5ad4e3e": { "name": "Find a book now", "kind": "start", "inputDefs": [] }, "n_b6b3861bb09ea7ad": { "name": "Every Friday at 11:00 UTC", "kind": "cron", "cronTimes": [ { "type": "cron", "expression": "0 11 * * 5", "timezone": "UTC" } ] }, "n_72cd54190c3e6c9a": { "inputs": { "subject": { "kind": "value", "value": "juvenile_literature" } }, "name": "Choose the subject", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "subject" } ], "outputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "url" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "subject" } ], "name": "Choose the subject", "moduleId": "n_0cca178c6d33454d", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_2f4856b09e43083e": { "inputs": { "url": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_72cd54190c3e6c9a", "output": "url" } ] } }, "name": "Count subject works", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "url" } ], "outputs": [ { "jsonSchema": {}, "nullable": true, "handle": "body" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "statusCode" }, { "jsonSchema": { "type": "object", "additionalProperties": { "type": "string" } }, "nullable": false, "handle": "headers" } ], "name": "Count subject works", "executor": { "method": "GET", "query": { "mode": "fields", "names": [] }, "headers": { "mode": "fields", "names": [] }, "bodyFormat": "none", "authentication": { "type": "none" }, "responseFormat": "json", "statusPolicy": "success", "kind": "http-request" } } }, "n_c8237a6223dc4f20": { "inputs": { "body": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_2f4856b09e43083e", "output": "body" } ] }, "subject": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_72cd54190c3e6c9a", "output": "subject" } ] } }, "name": "Choose a random work", "kind": "task", "task": { "inputs": [ { "jsonSchema": {}, "nullable": true, "handle": "body" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "subject" } ], "outputs": [ { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "found" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "url" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "subject" } ], "name": "Choose a random work", "moduleId": "n_6e21ddd46faf752d", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_fb29298bd1b9c263": { "inputs": {}, "name": "Any books?", "kind": "condition", "matchMode": "first", "cases": [ { "output": "yes", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_c8237a6223dc4f20", "output": "found" } }, "operator": "isTrue" } ] } ] } ] }, "n_5fdc22383ba5b15a": { "inputs": { "url": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_c8237a6223dc4f20", "output": "url" } ] } }, "name": "Get the selected work", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "url" } ], "outputs": [ { "jsonSchema": {}, "nullable": true, "handle": "body" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "statusCode" }, { "jsonSchema": { "type": "object", "additionalProperties": { "type": "string" } }, "nullable": false, "handle": "headers" } ], "name": "Get the selected work", "executor": { "method": "GET", "query": { "mode": "fields", "names": [] }, "headers": { "mode": "fields", "names": [] }, "bodyFormat": "none", "authentication": { "type": "none" }, "responseFormat": "json", "statusPolicy": "success", "kind": "http-request" } } }, "n_08a5603419bb741e": { "inputs": { "body": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_5fdc22383ba5b15a", "output": "body" } ] } }, "name": "Prepare the work details URL", "kind": "task", "task": { "inputs": [ { "jsonSchema": {}, "nullable": true, "handle": "body" } ], "outputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "url" }, { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "work" } ], "name": "Prepare the work details URL", "moduleId": "n_e4024938eebc3347", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_2a5087f571f55f8b": { "inputs": { "url": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_08a5603419bb741e", "output": "url" } ] } }, "name": "Get the work details", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "url" } ], "outputs": [ { "jsonSchema": {}, "nullable": true, "handle": "body" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "statusCode" }, { "jsonSchema": { "type": "object", "additionalProperties": { "type": "string" } }, "nullable": false, "handle": "headers" } ], "name": "Get the work details", "executor": { "method": "GET", "query": { "mode": "fields", "names": [] }, "headers": { "mode": "fields", "names": [] }, "bodyFormat": "none", "authentication": { "type": "none" }, "responseFormat": "json", "statusPolicy": "success", "kind": "http-request" } } }, "n_bbfca02c9c3e84e1": { "inputs": { "work": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_08a5603419bb741e", "output": "work" } ] }, "body": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_2a5087f571f55f8b", "output": "body" } ] } }, "name": "Format the recommendation", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "work" }, { "jsonSchema": {}, "nullable": true, "handle": "body" } ], "outputs": [ { "jsonSchema": { "type": "string", "minLength": 1, "description": "The email subject line." }, "nullable": true, "handle": "subject" }, { "jsonSchema": { "type": "string", "description": "The optional HTML body content." }, "nullable": true, "handle": "html" } ], "name": "Format the recommendation", "moduleId": "n_2a6ce5a5ef0c9331", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_4ac1965c5e583fa0": { "inputs": { "from": { "kind": "value", "value": { "email": "sender@example.com" } }, "to": { "kind": "value", "value": [ { "email": "recipient@example.com" } ] }, "subject": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_bbfca02c9c3e84e1", "output": "subject" } ] }, "htmlContent": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_bbfca02c9c3e84e1", "output": "html" } ] } }, "name": "Email the recommendation", "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 recommendation", "executor": { "kind": "connector", "action": "sendgrid.send_email" } } }, "n_aadf3c7aaa99a3db": { "inputs": { "subject": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_c8237a6223dc4f20", "output": "subject" } ] } }, "name": "Format the no-book notice", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "subject" } ], "outputs": [ { "jsonSchema": { "type": "string", "minLength": 1, "description": "The email subject line." }, "nullable": true, "handle": "subject" }, { "jsonSchema": { "type": "string", "description": "The optional HTML body content." }, "nullable": true, "handle": "html" } ], "name": "Format the no-book notice", "moduleId": "n_591e5268e5aa0eba", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_9c2db5e6f1cc7878": { "inputs": { "from": { "kind": "value", "value": { "email": "sender@example.com" } }, "to": { "kind": "value", "value": [ { "email": "recipient@example.com" } ] }, "subject": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_aadf3c7aaa99a3db", "output": "subject" } ] }, "htmlContent": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_aadf3c7aaa99a3db", "output": "html" } ] } }, "name": "Email the no-book notice", "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 no-book notice", "executor": { "kind": "connector", "action": "sendgrid.send_email" } } } }, "edges": [ { "source": "n_0b7e1d48f5ad4e3e", "target": "n_72cd54190c3e6c9a" }, { "source": "n_b6b3861bb09ea7ad", "target": "n_72cd54190c3e6c9a" }, { "source": "n_72cd54190c3e6c9a", "target": "n_2f4856b09e43083e" }, { "source": "n_2f4856b09e43083e", "target": "n_c8237a6223dc4f20" }, { "source": "n_c8237a6223dc4f20", "target": "n_fb29298bd1b9c263" }, { "source": "n_fb29298bd1b9c263", "target": "n_5fdc22383ba5b15a", "sourceHandle": "yes" }, { "source": "n_5fdc22383ba5b15a", "target": "n_08a5603419bb741e" }, { "source": "n_08a5603419bb741e", "target": "n_2a5087f571f55f8b" }, { "source": "n_2a5087f571f55f8b", "target": "n_bbfca02c9c3e84e1" }, { "source": "n_bbfca02c9c3e84e1", "target": "n_4ac1965c5e583fa0" }, { "source": "n_fb29298bd1b9c263", "target": "n_aadf3c7aaa99a3db", "sourceHandle": "otherwise" }, { "source": "n_aadf3c7aaa99a3db", "target": "n_9c2db5e6f1cc7878" } ] } }, "modules": { "n_0cca178c6d33454d": { "name": "Choose the subject", "imports": [], "source": "export default function subject({subject}){if(typeof subject!=='string'||!/^[-a-zA-Z0-9_]+$/.test(subject))throw Error('Enter an Open Library subject slug');return{url:'https://openlibrary.org/subjects/'+encodeURIComponent(subject)+'.json?limit=0',subject}}\n" }, "n_6e21ddd46faf752d": { "name": "Choose a random work", "imports": [], "source": "export default function count({body,subject}){const n=body?.work_count;if(!Number.isSafeInteger(n)||n<0)throw Error('Invalid Open Library work count');return{found:n>0,url:'https://openlibrary.org/subjects/'+encodeURIComponent(subject)+'.json?limit=1&offset='+(n?Math.floor(Math.random()*n):0)+'&details=true',subject}}\n" }, "n_e4024938eebc3347": { "name": "Prepare the work details URL", "imports": [], "source": "export default function basic({body}){const w=body?.works?.[0];if(!w||typeof w.title!=='string'||!/^\\/works\\/OL\\d+W$/.test(w.key)||!Array.isArray(w.authors))throw Error('Invalid Open Library work');return{url:'https://openlibrary.org'+w.key+'.json',work:w}}\n" }, "n_2a6ce5a5ef0c9331": { "name": "Format the recommendation", "imports": [], "source": "export default function format({work,body}){if(body?.key!==work.key)throw Error('Unexpected Open Library work');const esc=x=>String(x??'').replace(/[&<>\"']/g,c=>({'&':'&','<':'<','>':'>','\"':'"',\"'\":'''}[c]));const authors=work.authors.map(a=>{if(!a||typeof a.name!=='string'||!/^\\/authors\\/OL\\d+A$/.test(a.key))throw Error('Invalid author');return ''+esc(a.name)+''}).join(', ');const d=typeof body.description==='string'?body.description:body.description?.value;const title=esc(work.title);return{subject:'Book Recommendation: '+work.title,html:'
By '+authors+'
'+esc(d||'No description available.')+'
Unfortunately, there are no books available for the subject of '+subject+'. Choose another subject.
'}}\n" } } }, "presentation": { "designer": { "version": 1, "flow": { "direction": "vertical" } } } }