{ "kind": "open-flow-workflow", "version": 1, "name": "Airtable Tweet Drafts", "content": { "modelVersion": 14, "document": { "bindings": {}, "graph": { "nodes": { "n_4766b98184e4e0b7": { "name": "Create a draft", "kind": "start", "inputDefs": [] }, "n_6fc85a2a11066968": { "inputs": { "hashtags": { "kind": "value", "value": [ "#techtwitter", "#n8n" ] } }, "name": "Choose hashtag", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "array", "items": { "type": "string" }, "minItems": 1 }, "nullable": false, "handle": "hashtags" } ], "outputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "hashtag" } ], "name": "Choose hashtag", "moduleId": "n_a045b1bf6cff44c7", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_05cf449e74cebcf6": { "inputs": { "hashtag": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_6fc85a2a11066968", "output": "hashtag" } ] } }, "name": "Generate tweet draft", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "items": { "type": "object" }, "type": "array" }, "nullable": true, "handle": "messages", "value": null }, { "jsonSchema": { "items": { "type": "object" }, "minItems": 1, "type": "array" }, "nullable": false, "handle": "template", "value": [ { "role": "user", "content": "Generate a tweet, with under 100 characters, about and including the hashtag {{hashtag}}:" } ] }, { "jsonSchema": { "type": "object" }, "nullable": false, "handle": "model", "value": { "model": "gpt-4o-mini", "temperature": 0.7, "max_tokens": 64, "top_p": 1 } }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "hashtag" } ], "outputs": [ { "description": "Generated response.", "jsonSchema": { "type": "string" }, "nullable": false, "handle": "output" } ], "name": "Generate tweet draft", "executor": { "kind": "llm", "mode": "chat" } } }, "n_231cff514b9e91da": { "inputs": { "hashtag": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_6fc85a2a11066968", "output": "hashtag" } ] }, "content": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_05cf449e74cebcf6", "output": "output" } ] } }, "name": "Prepare Airtable draft", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "hashtag" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "content" } ], "outputs": [ { "jsonSchema": { "type": "array", "items": { "type": "object", "properties": { "fields": { "type": "object", "additionalProperties": { "description": "A record value." }, "description": "Field values for the new Airtable record." } }, "required": [ "fields" ], "additionalProperties": false, "description": "Record payload used when creating Airtable records." }, "minItems": 1, "maxItems": 10, "description": "Records to create in the Airtable table." }, "nullable": false, "handle": "records" } ], "name": "Prepare Airtable draft", "moduleId": "n_83c87dbeee2a663f", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_42a2b1eda81c84ee": { "inputs": { "baseId": { "kind": "value", "value": "YOUR_AIRTABLE_BASE_ID" }, "tableIdOrName": { "kind": "value", "value": "YOUR_AIRTABLE_TABLE_ID" }, "records": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_231cff514b9e91da", "output": "records" } ] } }, "name": "Save draft", "kind": "task", "task": { "inputs": [ { "description": "Base ID in the format appXXXXXXXXXXXXXX.", "jsonSchema": { "type": "string", "minLength": 1, "description": "Base ID in the format appXXXXXXXXXXXXXX." }, "nullable": false, "handle": "baseId" }, { "description": "Table ID or table name accepted by the Airtable path parameter.", "jsonSchema": { "type": "string", "minLength": 1, "description": "Table ID or table name accepted by the Airtable path parameter." }, "nullable": false, "handle": "tableIdOrName" }, { "description": "Records to create in the Airtable table.", "jsonSchema": { "type": "array", "items": { "type": "object", "properties": { "fields": { "type": "object", "additionalProperties": { "description": "A record value." }, "description": "Field values for the new Airtable record." } }, "required": [ "fields" ], "additionalProperties": false, "description": "Record payload used when creating Airtable records." }, "minItems": 1, "maxItems": 10, "description": "Records to create in the Airtable table." }, "nullable": false, "handle": "records" }, { "description": "Whether Airtable should coerce incoming values to compatible field types.", "jsonSchema": { "type": "boolean", "description": "Whether Airtable should coerce incoming values to compatible field types." }, "nullable": true, "handle": "typecast", "value": null }, { "description": "Whether Airtable should return field IDs instead of field names in record objects.", "jsonSchema": { "type": "boolean", "description": "Whether Airtable should return field IDs instead of field names in record objects." }, "nullable": true, "handle": "returnFieldsByFieldId", "value": null } ], "outputs": [ { "description": "Records created by Airtable.", "jsonSchema": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "Record ID." }, "createdTime": { "type": "string", "description": "Record creation timestamp returned by Airtable." }, "fields": { "type": "object", "additionalProperties": { "description": "A record value." }, "description": "Record fields keyed by field name or field ID." }, "commentCount": { "type": "integer", "description": "Comment count returned by Airtable when enabled on the endpoint." } }, "required": [ "id", "fields" ], "additionalProperties": true, "description": "Airtable record." }, "description": "Records created by Airtable." }, "nullable": false, "handle": "records" } ], "name": "Save draft", "executor": { "kind": "connector", "action": "airtable.create_records" } } } }, "edges": [ { "source": "n_4766b98184e4e0b7", "target": "n_6fc85a2a11066968" }, { "source": "n_6fc85a2a11066968", "target": "n_05cf449e74cebcf6" }, { "source": "n_05cf449e74cebcf6", "target": "n_231cff514b9e91da" }, { "source": "n_231cff514b9e91da", "target": "n_42a2b1eda81c84ee" } ] } }, "modules": { "n_a045b1bf6cff44c7": { "name": "Choose hashtag", "imports": [], "source": "export default function chooseHashtag({ hashtags }) {\n if (!Array.isArray(hashtags) || !hashtags.length || !hashtags.every((hashtag) => typeof hashtag === 'string' && /^#\\S+$/.test(hashtag))) {\n throw new Error('hashtags must contain at least one hashtag');\n }\n return { hashtag: hashtags[Math.floor(Math.random() * hashtags.length)] };\n}\n" }, "n_83c87dbeee2a663f": { "name": "Prepare Airtable draft", "imports": [], "source": "export default function airtableDraft({ hashtag, content }) {\n if (typeof content !== 'string' || !content.trim()) throw new Error('The model returned no draft');\n return { records: [{ fields: { Hashtag: hashtag, Content: content } }] };\n}\n" } } }, "presentation": { "designer": { "version": 1, "flow": { "direction": "vertical" } } } }