{ "kind": "open-flow-workflow", "version": 1, "name": "Google Sheet Record Lookup", "content": { "modelVersion": 14, "document": { "bindings": {}, "graph": { "nodes": { "n_e156965d743d9867": { "name": "Sheet lookup request", "kind": "start", "inputDefs": [ { "jsonSchema": { "type": "string", "enum": [ "column_names", "column_values", "row" ] }, "nullable": false, "handle": "operation" }, { "jsonSchema": { "type": "string" }, "nullable": true, "handle": "query" } ] }, "n_9842d6cbef210c6d": { "inputs": { "operation": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_e156965d743d9867", "output": "operation" } ] }, "query": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_e156965d743d9867", "output": "query" } ] }, "spreadsheetId": { "kind": "value", "value": "YOUR_SPREADSHEET_ID" }, "range": { "kind": "value", "value": "'Sheet1'" } }, "name": "Prepare sheet lookup", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string", "enum": [ "column_names", "column_values", "row" ] }, "nullable": false, "handle": "operation" }, { "jsonSchema": { "type": "string" }, "nullable": true, "handle": "query" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "spreadsheetId" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "range" } ], "outputs": [ { "jsonSchema": { "type": "string", "enum": [ "column_names", "column_values", "row" ] }, "nullable": false, "handle": "operation" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "query" }, { "jsonSchema": { "type": "string", "minLength": 1, "description": "The spreadsheet ID." }, "nullable": false, "handle": "spreadsheetId" }, { "jsonSchema": { "type": "string", "minLength": 1, "description": "The A1 notation of the range to retrieve." }, "nullable": false, "handle": "range" } ], "name": "Prepare sheet lookup", "moduleId": "n_98284d5b6e5d883b", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_c18517537478fd03": { "inputs": { "spreadsheetId": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_9842d6cbef210c6d", "output": "spreadsheetId" } ] }, "range": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_9842d6cbef210c6d", "output": "range" } ] }, "majorDimension": { "kind": "value", "value": "ROWS" }, "valueRenderOption": { "kind": "value", "value": "UNFORMATTED_VALUE" }, "dateTimeRenderOption": { "kind": "value", "value": "FORMATTED_STRING" } }, "name": "Read complete sheet tab", "kind": "task", "task": { "inputs": [ { "description": "The spreadsheet ID.", "jsonSchema": { "type": "string", "minLength": 1, "description": "The spreadsheet ID." }, "nullable": true, "handle": "spreadsheetId", "value": null }, { "description": "The A1 notation of the range to retrieve.", "jsonSchema": { "type": "string", "minLength": 1, "description": "The A1 notation of the range to retrieve." }, "nullable": false, "handle": "range" }, { "description": "The major dimension for the returned values.", "jsonSchema": { "type": "string", "enum": [ "DIMENSION_UNSPECIFIED", "ROWS", "COLUMNS" ], "description": "The major dimension for the returned values." }, "nullable": true, "handle": "majorDimension", "value": null }, { "description": "How values should be rendered in the output.", "jsonSchema": { "type": "string", "enum": [ "FORMATTED_VALUE", "UNFORMATTED_VALUE", "FORMULA" ], "description": "How values should be rendered in the output." }, "nullable": true, "handle": "valueRenderOption", "value": null }, { "description": "How dates and times should be rendered in the output.", "jsonSchema": { "type": "string", "enum": [ "SERIAL_NUMBER", "FORMATTED_STRING" ], "description": "How dates and times should be rendered in the output." }, "nullable": true, "handle": "dateTimeRenderOption", "value": null } ], "outputs": [ { "description": "The A1 notation of the range.", "jsonSchema": { "type": "string", "description": "The A1 notation of the range." }, "nullable": false, "handle": "range" }, { "description": "The major dimension of the values (ROWS or COLUMNS).", "jsonSchema": { "type": "string", "description": "The major dimension of the values (ROWS or COLUMNS)." }, "nullable": false, "handle": "majorDimension" }, { "description": "The data values in the range.", "jsonSchema": { "type": "array", "items": { "type": "array", "items": { "anyOf": [ { "type": "string", "description": "A union variant." }, { "type": "number", "description": "A union variant." }, { "type": "boolean", "description": "A union variant." }, { "const": null, "description": "A union variant." } ], "description": "The cell value schema." }, "description": "An array item." }, "description": "The data values in the range." }, "nullable": false, "handle": "values" } ], "name": "Read complete sheet tab", "executor": { "kind": "connector", "action": "googlesheets.values_get" } } }, "n_03898eaabdf7dce7": { "inputs": { "values": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_c18517537478fd03", "output": "values" } ] }, "majorDimension": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_c18517537478fd03", "output": "majorDimension" } ] }, "operation": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_9842d6cbef210c6d", "output": "operation" } ] }, "query": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_9842d6cbef210c6d", "output": "query" } ] } }, "name": "Select sheet records", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "array", "items": { "type": "array", "items": { "anyOf": [ { "type": "string", "description": "A union variant." }, { "type": "number", "description": "A union variant." }, { "type": "boolean", "description": "A union variant." }, { "const": null, "description": "A union variant." } ], "description": "The cell value schema." }, "description": "An array item." }, "description": "The data values in the range." }, "nullable": false, "handle": "values" }, { "jsonSchema": { "type": "string", "description": "The major dimension of the values (ROWS or COLUMNS)." }, "nullable": false, "handle": "majorDimension" }, { "jsonSchema": { "type": "string", "enum": [ "column_names", "column_values", "row" ] }, "nullable": false, "handle": "operation" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "query" } ], "outputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "response" } ], "name": "Select sheet records", "moduleId": "n_bca4cc234f6fbc62", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_61f608331726870e": { "name": "Sheet lookup response", "kind": "outputs", "outputDefs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "response" } ], "outputMappings": { "response": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_03898eaabdf7dce7", "output": "response" } ] } } } }, "edges": [ { "source": "n_e156965d743d9867", "target": "n_9842d6cbef210c6d" }, { "source": "n_9842d6cbef210c6d", "target": "n_c18517537478fd03" }, { "source": "n_c18517537478fd03", "target": "n_03898eaabdf7dce7" }, { "source": "n_03898eaabdf7dce7", "target": "n_61f608331726870e" } ] } }, "modules": { "n_98284d5b6e5d883b": { "name": "Prepare sheet lookup", "imports": [], "source": "export function lookupRequest({ operation, query }) {\n if (!['column_names', 'column_values', 'row'].includes(operation)) throw new Error('Use column_names, column_values, or row.');\n if (query != null && typeof query !== 'string') throw new Error('The lookup query must be text.');\n const text = query ?? '';\n if (operation === 'column_values' && !text.trim()) throw new Error('Supply the exact column name.');\n if (operation === 'row' && (!/^[1-9]\\d*$/.test(text) || !Number.isSafeInteger(Number(text)))) throw new Error('Supply a positive physical row number as text.');\n return { operation, query: text };\n}\n\nexport default function prepareSheetLookup({ operation, query, spreadsheetId, range }) {\n const lookup = lookupRequest({ operation, query });\n if (typeof spreadsheetId !== 'string' || !/^[A-Za-z0-9_-]+$/.test(spreadsheetId) || /YOUR_SPREADSHEET_ID/.test(spreadsheetId)) throw new Error('Configure your Google spreadsheet ID before running.');\n if (typeof range !== 'string' || !/^'(?:[^'\\u0000-\\u001f\\u007f]|'')+'$/.test(range)) throw new Error('Configure the complete tab as a single-quoted A1 sheet name.');\n return { ...lookup, spreadsheetId, range };\n}\n" }, "n_bca4cc234f6fbc62": { "name": "Select sheet records", "imports": [], "source": "export function lookupSheet({ values, majorDimension = 'ROWS', operation, query }) {\n if (majorDimension !== 'ROWS' || !Array.isArray(values) || values.some(row => !Array.isArray(row))) throw new Error('Google Sheets must return row-oriented cell values.');\n const isEmpty = value => value == null || value === '';\n const nonempty = row => row.some(value => !isEmpty(value));\n const headerIndex = values.findIndex(nonempty);\n if (headerIndex < 0) return { response: '[]' };\n const headers = values[headerIndex];\n if (headers.some(name => typeof name !== 'string' || !name.trim() || name === 'row_number') || new Set(headers).size !== headers.length) throw new Error('Use unique nonempty text headers; row_number is reserved.');\n const columns = ['row_number', ...headers];\n const records = [];\n for (let index = headerIndex + 1; index < values.length; index++) {\n const cells = values[index];\n if (!nonempty(cells)) continue;\n if (cells.slice(headers.length).some(value => !isEmpty(value))) throw new Error('Every populated column needs a header.');\n records.push(Object.fromEntries([['row_number', index + 1], ...headers.map((name, column) => [name, cells[column] ?? ''])]));\n }\n let result;\n if (operation === 'column_names') result = columns;\n else if (operation === 'column_values') {\n if (!columns.includes(query)) throw new Error('The requested column does not exist.');\n result = records.map(record => Object.fromEntries([['row_number', record.row_number], [query, record[query]]]));\n } else if (operation === 'row') result = records.filter(record => record.row_number === Number(query));\n else throw new Error('Use column_names, column_values, or row.');\n return { response: JSON.stringify(result) };\n}\n\nexport default function formatSheetLookup(input) {\n return lookupSheet(input);\n}\n" } } }, "presentation": { "designer": { "version": 1, "flow": { "direction": "vertical" } } } }