{ "kind": "open-flow-workflow", "version": 1, "name": "Save User Registration to Airtable", "content": { "modelVersion": 14, "document": { "bindings": {}, "graph": { "nodes": { "n_dd94a49b70beb9a8": { "name": "Receive registration", "kind": "webhook", "bodyFields": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "Name" }, { "jsonSchema": { "type": "number" }, "nullable": false, "handle": "Age" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "email" }, { "jsonSchema": { "type": "string" }, "nullable": true, "handle": "address" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "You have Subscription ?" } ], "method": "POST" }, "n_f841d978bfbed4e1": { "inputs": { "body": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_dd94a49b70beb9a8", "output": "body" } ] } }, "name": "Prepare registration", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "body" }, { "jsonSchema": { "type": "string" }, "nullable": true, "handle": "submitted" } ], "outputs": [ { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "fields" }, { "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 registration", "moduleId": "n_ab315d4c7a50f42b", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_b5fb7b628716fb0b": { "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_f841d978bfbed4e1", "output": "records" } ] }, "typecast": { "kind": "value", "value": false } }, "name": "Save registration", "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 registration", "executor": { "kind": "connector", "action": "airtable.create_records" } } }, "n_5d2f5e3ef817a123": { "inputs": { "records": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_b5fb7b628716fb0b", "output": "records" } ] }, "fields": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_f841d978bfbed4e1", "output": "fields" } ] } }, "name": "Confirm registration", "kind": "task", "task": { "inputs": [ { "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" }, { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "fields" } ], "outputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "id" } ], "name": "Confirm registration", "moduleId": "n_68117d83a5419ac4", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } } }, "edges": [ { "source": "n_dd94a49b70beb9a8", "target": "n_f841d978bfbed4e1" }, { "source": "n_f841d978bfbed4e1", "target": "n_b5fb7b628716fb0b" }, { "source": "n_b5fb7b628716fb0b", "target": "n_5d2f5e3ef817a123" } ] } }, "modules": { "n_ab315d4c7a50f42b": { "name": "Prepare registration", "imports": [], "source": "export default function main({body,submitted}) {\n if(!body||typeof body.Name!=='string'||!body.Name.trim()||typeof body.Age!=='number'||!Number.isFinite(body.Age)||typeof body.email!=='string'||!/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(body.email)||!['Yes','No'].includes(body['You have Subscription ?'])||(body.address!=null&&typeof body.address!=='string'))throw Error('Provide name, numeric age, email and Yes/No subscription');\n const date=submitted??new Date().toISOString();\n if(typeof date!=='string'||!date)throw Error('Missing submission time');\n const fields={Name:body.Name,Age:String(body.Age),Email:body.email,Address:body.address??'',Subscription:body['You have Subscription ?'],Submitted:date};\n return {fields,records:[{fields}]};\n}\n" }, "n_68117d83a5419ac4": { "name": "Confirm registration", "imports": [], "source": "export default function main({records,fields}) {\n if(!Array.isArray(records)||records.length!==1||typeof records[0]?.id!=='string'||!records[0].id)throw Error('Airtable did not confirm the new record');\n for(const [key,value] of Object.entries(fields)){const actual=records[0].fields?.[key];if(value===''&&(actual===undefined||actual===''))continue;if(actual!==value)throw Error('Airtable record differs from submission');}\n return {id:records[0].id};\n}\n" } } }, "presentation": { "designer": { "version": 1, "flow": { "direction": "vertical" } } } }