{ "kind": "open-flow-workflow", "version": 1, "name": "Enrich Sheet Companies with ProspectLens", "content": { "modelVersion": 14, "document": { "bindings": {}, "graph": { "nodes": { "n_2fb9819fb88d8a7a": { "name": "Start manually", "kind": "start", "inputDefs": [] }, "n_6310bc8fe5b0e79c": { "inputs": { "spreadsheetId": { "kind": "value", "value": "YOUR_SPREADSHEET_ID" }, "sheetName": { "kind": "value", "value": "Sheet1" } }, "name": "Choose the sheet", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "spreadsheetId" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "sheetName" } ], "outputs": [ { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "spreadsheetId" }, { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "sheetName" }, { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "range" } ], "name": "Choose the sheet", "moduleId": "n_b8d629e11cafd6c3", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_219711c447b239e2": { "inputs": { "spreadsheetId": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_6310bc8fe5b0e79c", "output": "spreadsheetId" } ] }, "range": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_6310bc8fe5b0e79c", "output": "range" } ] }, "majorDimension": { "kind": "value", "value": "ROWS" }, "valueRenderOption": { "kind": "value", "value": "UNFORMATTED_VALUE" } }, "name": "Read sheet rows", "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 sheet rows", "executor": { "kind": "connector", "action": "googlesheets.values_get" } } }, "n_c930d4d83b867a1b": { "inputs": { "values": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_219711c447b239e2", "output": "values" } ] } }, "name": "Select unprocessed companies", "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" } ], "outputs": [ { "jsonSchema": { "type": "array", "items": { "type": "object", "additionalProperties": true } }, "nullable": false, "handle": "rows" }, { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "columns" } ], "name": "Select unprocessed companies", "moduleId": "n_a0e933393a9b03c8", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_8e443b7a9047c9d8": { "inputs": { "rows": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_c930d4d83b867a1b", "output": "rows" } ] }, "previous": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_8e443b7a9047c9d8", "output": "state" } ] } }, "name": "Choose the next company", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "array", "items": { "type": "object", "additionalProperties": true } }, "nullable": false, "handle": "rows" }, { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": true, "handle": "previous" } ], "outputs": [ { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "state" }, { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "more" }, { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "row" } ], "name": "Choose the next company", "moduleId": "n_37df59d9e9a94aaa", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_1689cf32a25937fa": { "inputs": {}, "name": "More companies?", "kind": "condition", "matchMode": "first", "cases": [ { "output": "yes", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_8e443b7a9047c9d8", "output": "more" } }, "operator": "isTrue" } ] } ] } ] }, "n_a9cb56884e9a3886": { "inputs": { "row": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_8e443b7a9047c9d8", "output": "row" } ] }, "apiKey": { "kind": "unset" } }, "name": "Look up the company", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "row" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "apiKey" } ], "outputs": [ { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "ok" }, { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": true, "handle": "data" } ], "name": "Look up the company", "moduleId": "n_ab433f91b0692b2d", "capabilities": [ { "kind": "http", "hosts": [ "prospectlens.apiroad.net" ] } ] } }, "n_c9b3cca3caf9722c": { "inputs": {}, "name": "Lookup succeeded?", "kind": "condition", "matchMode": "first", "cases": [ { "output": "yes", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_a9cb56884e9a3886", "output": "ok" } }, "operator": "isTrue" } ] } ] } ] }, "n_d815245e0a4021a4": { "inputs": { "row": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_8e443b7a9047c9d8", "output": "row" } ] }, "columns": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_c930d4d83b867a1b", "output": "columns" } ] }, "response": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_a9cb56884e9a3886", "output": "data" } ] }, "sheetName": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_6310bc8fe5b0e79c", "output": "sheetName" } ] } }, "name": "Prepare company fields", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "row" }, { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "columns" }, { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": true, "handle": "response" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "sheetName" } ], "outputs": [ { "jsonSchema": { "type": "array", "items": { "type": "object", "properties": { "range": { "type": "string", "minLength": 1, "description": "The A1 notation of the range to write to." }, "values": { "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 to write into the range." }, "majorDimension": { "type": "string", "enum": [ "ROWS", "COLUMNS" ], "description": "The major dimension of the values array." } }, "required": [ "range", "values" ], "additionalProperties": false, "description": "A batch values update item." }, "minItems": 1, "description": "The list of value ranges to update." }, "nullable": false, "handle": "data" } ], "name": "Prepare company fields", "moduleId": "n_070a0759542d9d4b", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_93cf757b5759facc": { "inputs": { "spreadsheetId": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_6310bc8fe5b0e79c", "output": "spreadsheetId" } ] }, "data": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_d815245e0a4021a4", "output": "data" } ] }, "valueInputOption": { "kind": "value", "value": "RAW" } }, "name": "Update the company row", "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 list of value ranges to update.", "jsonSchema": { "type": "array", "items": { "type": "object", "properties": { "range": { "type": "string", "minLength": 1, "description": "The A1 notation of the range to write to." }, "values": { "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 to write into the range." }, "majorDimension": { "type": "string", "enum": [ "ROWS", "COLUMNS" ], "description": "The major dimension of the values array." } }, "required": [ "range", "values" ], "additionalProperties": false, "description": "A batch values update item." }, "minItems": 1, "description": "The list of value ranges to update." }, "nullable": false, "handle": "data" }, { "description": "How the input data should be interpreted.", "jsonSchema": { "type": "string", "enum": [ "INPUT_VALUE_OPTION_UNSPECIFIED", "RAW", "USER_ENTERED" ], "description": "How the input data should be interpreted." }, "nullable": true, "handle": "valueInputOption", "value": null }, { "description": "Whether to include the written values in the response.", "jsonSchema": { "type": "boolean", "description": "Whether to include the written values in the response." }, "nullable": true, "handle": "includeValuesInResponse", "value": null }, { "description": "How values in the response should be rendered.", "jsonSchema": { "type": "string", "enum": [ "FORMATTED_VALUE", "UNFORMATTED_VALUE", "FORMULA" ], "description": "How values in the response should be rendered." }, "nullable": true, "handle": "responseValueRenderOption", "value": null }, { "description": "How dates in the response should be rendered.", "jsonSchema": { "type": "string", "enum": [ "SERIAL_NUMBER", "FORMATTED_STRING" ], "description": "How dates in the response should be rendered." }, "nullable": true, "handle": "responseDateTimeRenderOption", "value": null } ], "outputs": [ { "description": "The unique ID of the spreadsheet.", "jsonSchema": { "type": "string", "description": "The unique ID of the spreadsheet." }, "nullable": false, "handle": "spreadsheetId" }, { "description": "The total number of rows updated across all ranges.", "jsonSchema": { "type": "integer", "description": "The total number of rows updated across all ranges." }, "nullable": false, "handle": "totalUpdatedRows" }, { "description": "The total number of columns updated across all ranges.", "jsonSchema": { "type": "integer", "description": "The total number of columns updated across all ranges." }, "nullable": false, "handle": "totalUpdatedColumns" }, { "description": "The total number of cells updated across all ranges.", "jsonSchema": { "type": "integer", "description": "The total number of cells updated across all ranges." }, "nullable": false, "handle": "totalUpdatedCells" }, { "description": "The per-range update responses.", "jsonSchema": { "type": "array", "items": { "type": "object", "properties": { "updatedRange": { "type": "string", "description": "The A1 notation of the range that was updated." }, "updatedRows": { "type": "integer", "description": "The number of rows that were updated." }, "updatedColumns": { "type": "integer", "description": "The number of columns that were updated." }, "updatedCells": { "type": "integer", "description": "The number of cells that were updated." }, "updatedData": { "type": "object", "properties": { "range": { "type": "string", "description": "The A1 notation of the range." }, "majorDimension": { "type": "string", "description": "The major dimension of the values (ROWS or COLUMNS)." }, "values": { "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." } }, "required": [ "range", "majorDimension", "values" ], "additionalProperties": false, "description": "The values of the cells after the update." } }, "required": [ "updatedRange", "updatedRows", "updatedColumns", "updatedCells" ], "additionalProperties": false, "description": "The batch update item schema." }, "description": "The per-range update responses." }, "nullable": false, "handle": "responses" } ], "name": "Update the company row", "executor": { "kind": "connector", "action": "googlesheets.update_values_batch" } } }, "n_c8f0a8b722e86b7f": { "inputs": {}, "name": "Continue to the next company", "kind": "task", "task": { "inputs": [], "outputs": [], "name": "Continue to the next company", "moduleId": "n_0269aa9e11876606", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_620ab5d085ffdb94": { "name": "Finished", "kind": "outputs", "outputDefs": [], "outputMappings": {} }, "n_95f3ce5ff8544206": { "inputs": { "spreadsheetId": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_93cf757b5759facc", "output": "spreadsheetId" } ] }, "expectedId": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_6310bc8fe5b0e79c", "output": "spreadsheetId" } ] }, "totalUpdatedCells": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_93cf757b5759facc", "output": "totalUpdatedCells" } ] } }, "name": "Confirm the row update", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string", "description": "The unique ID of the spreadsheet." }, "nullable": false, "handle": "spreadsheetId" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "expectedId" }, { "jsonSchema": { "type": "integer", "description": "The total number of cells updated across all ranges." }, "nullable": false, "handle": "totalUpdatedCells" } ], "outputs": [ { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "ok" } ], "name": "Confirm the row update", "moduleId": "n_f7260d68632ee2c8", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } } }, "edges": [ { "source": "n_2fb9819fb88d8a7a", "target": "n_6310bc8fe5b0e79c" }, { "source": "n_6310bc8fe5b0e79c", "target": "n_219711c447b239e2" }, { "source": "n_219711c447b239e2", "target": "n_c930d4d83b867a1b" }, { "source": "n_c930d4d83b867a1b", "target": "n_8e443b7a9047c9d8" }, { "source": "n_8e443b7a9047c9d8", "target": "n_1689cf32a25937fa" }, { "source": "n_1689cf32a25937fa", "target": "n_620ab5d085ffdb94", "sourceHandle": "otherwise" }, { "source": "n_1689cf32a25937fa", "target": "n_a9cb56884e9a3886", "sourceHandle": "yes" }, { "source": "n_a9cb56884e9a3886", "target": "n_c9b3cca3caf9722c" }, { "source": "n_c9b3cca3caf9722c", "target": "n_d815245e0a4021a4", "sourceHandle": "yes" }, { "source": "n_c9b3cca3caf9722c", "target": "n_c8f0a8b722e86b7f", "sourceHandle": "otherwise" }, { "source": "n_d815245e0a4021a4", "target": "n_93cf757b5759facc" }, { "source": "n_93cf757b5759facc", "target": "n_95f3ce5ff8544206" }, { "source": "n_95f3ce5ff8544206", "target": "n_c8f0a8b722e86b7f" }, { "source": "n_c8f0a8b722e86b7f", "target": "n_8e443b7a9047c9d8" } ] } }, "modules": { "n_b8d629e11cafd6c3": { "name": "Choose the sheet", "imports": [], "source": "export default function config({spreadsheetId,sheetName}){if(!spreadsheetId||spreadsheetId.startsWith('YOUR_')||!sheetName.trim())throw Error('Configure spreadsheet and sheet');return{spreadsheetId,sheetName,range:\"'\"+sheetName.replace(/'/g,\"''\")+\"'!A:Z\"}}" }, "n_a0e933393a9b03c8": { "name": "Select unprocessed companies", "imports": [], "source": "export default function prepare({values}){if(!Array.isArray(values)||!Array.isArray(values[0]))throw Error('Sheet must have a header row');const names=['domain','name','description','processed_at','data','domain_name','traffic','location','funds','year_founded','funding_round','last_funding_at'],header=values[0],columns={};for(const name of names){let indices=header.flatMap((v,i)=>v===name?[i]:[]);if(indices.length!==1)throw Error('Expected one '+name+' column');columns[name]=indices[0]}const rows=[];for(let i=1;irows.length)throw Error('Invalid row progress');return{state:{index},more:indexsetTimeout(resolve,1000));try{const r=await context.fetch(url,{method:'GET',headers:{'x-apiroad-key':apiKey}});if(!r.ok)throw Error('lookup failed');const data=await r.json();if(!data||typeof data!=='object'||Array.isArray(data))throw Error('invalid JSON');return{ok:true,data}}catch{}}return{ok:false,data:null}}\n" }, "n_070a0759542d9d4b": { "name": "Prepare company fields", "imports": [], "source": "export default function map({row,columns,response,sheetName}){if(!response||typeof response!=='object'||!response.data||typeof response.data!=='object')throw Error('ProspectLens response missing data');const d=response.data,need=(path)=>{let v=d;for(const k of path){if(v===null||v===undefined||typeof v!=='object'||!Object.prototype.hasOwnProperty.call(v,k))throw Error('ProspectLens response missing '+path.join('.'));v=v[k]}if(!['string','number','boolean'].includes(typeof v))throw Error('Invalid '+path.join('.'));return v};const vals={domain:row.domain,name:need(['properties','title']),description:need(['properties','short_description']),processed_at:new Date().toISOString(),data:JSON.stringify(d).substr(0,2000),domain_name:need(['info','company_about_fields','website','hostname']),traffic:need(['info','semrush_summary','semrush_visits_latest_month']),location:need(['info','semrush_location_list','0','location_identifiers','0','value']),funds:need(['info','funding_rounds_summary','funding_total','value']),year_founded:need(['info','overview_fields_extended','founded_on','value']),funding_round:need(['info','funding_rounds_summary','last_funding_type']),last_funding_at:need(['info','funding_rounds_summary','last_funding_at'])};if(typeof sheetName!=='string'||!sheetName.trim()||!Number.isInteger(row.row)||row.row<2)throw Error('Invalid sheet location');const name=\"'\"+sheetName.replace(/'/g,\"''\")+\"'\",col=i=>{if(!Number.isInteger(i)||i<0||i>=26)throw Error('Column outside A:Z');return String.fromCharCode(65+i)};const data=Object.entries(vals).map(([key,value])=>({range:`${name}!${col(columns[key])}${row.row}`,majorDimension:'ROWS',values:[[value]]}));return{data}}\n" }, "n_0269aa9e11876606": { "name": "Continue to the next company", "imports": [], "source": "export default function advance(){return {}}" }, "n_f7260d68632ee2c8": { "name": "Confirm the row update", "imports": [], "source": "export default function confirm({spreadsheetId,expectedId,totalUpdatedCells}){if(spreadsheetId!==expectedId||totalUpdatedCells!==12)throw Error('Sheet update not confirmed');return {ok:true}}" } } }, "presentation": { "designer": { "version": 1, "flow": { "direction": "vertical" } } } }