{ "kind": "open-flow-workflow", "version": 1, "name": "Watch Competitor Hiring in Slack", "content": { "modelVersion": 14, "document": { "bindings": {}, "graph": { "nodes": { "n_7dbe58312033a42f": { "name": "Every day at 08:00 UTC", "kind": "cron", "cronTimes": [ { "type": "cron", "expression": "0 8 * * *", "timezone": "UTC" } ] }, "n_f9eba88e2af1378e": { "inputs": { "actorId": { "kind": "value", "value": "gubidonius~company-jobs-scraper" }, "input": { "kind": "value", "value": { "companies": [ "https://boards.greenhouse.io/stripe", "lever:leverdemo", "ramp" ], "includeDescription": false, "onlyRemote": false, "maxJobsPerCompany": 1000 } }, "timeoutSecs": { "kind": "value", "value": 900 }, "memoryMbytes": { "kind": "value", "value": 1024 } }, "name": "Start the job board search", "kind": "task", "task": { "inputs": [ { "description": "The Apify actor identifier, such as apify~web-scraper or apify/web-scraper.", "jsonSchema": { "type": "string", "minLength": 1, "description": "The Apify actor identifier, such as apify~web-scraper or apify/web-scraper." }, "nullable": false, "handle": "actorId" }, { "description": "The JSON input object passed to the actor run.", "jsonSchema": { "type": "object", "additionalProperties": { "description": "A JSON-compatible Apify value." }, "description": "The JSON input object passed to the actor run." }, "nullable": true, "handle": "input", "value": null }, { "description": "The actor build tag or number to run.", "jsonSchema": { "type": "string", "minLength": 1, "description": "The actor build tag or number to run." }, "nullable": true, "handle": "build", "value": null }, { "description": "The memory limit for the run in megabytes.", "jsonSchema": { "type": "integer", "exclusiveMinimum": 0, "description": "The memory limit for the run in megabytes." }, "nullable": true, "handle": "memoryMbytes", "value": null }, { "description": "The maximum runtime for the run in seconds.", "jsonSchema": { "type": "integer", "exclusiveMinimum": 0, "description": "The maximum runtime for the run in seconds." }, "nullable": true, "handle": "timeoutSecs", "value": null } ], "outputs": [ { "description": "An Apify actor run.", "jsonSchema": { "type": "object", "properties": { "id": { "type": "string", "description": "The Apify run identifier." }, "actId": { "type": "string", "description": "The actor identifier associated with the run." }, "status": { "type": "string", "description": "The current run status." }, "startedAt": { "type": "string", "description": "When the run started." }, "finishedAt": { "type": "string", "description": "When the run finished." }, "defaultDatasetId": { "type": "string", "description": "The default dataset identifier created for the run." }, "defaultKeyValueStoreId": { "type": "string", "description": "The default key-value store identifier created for the run." }, "defaultRequestQueueId": { "type": "string", "description": "The default request queue identifier created for the run." }, "stats": { "type": "object", "properties": {}, "additionalProperties": true, "description": "The run statistics object." }, "options": { "type": "object", "properties": {}, "additionalProperties": true, "description": "The run options object." }, "usage": { "type": "object", "properties": {}, "additionalProperties": true, "description": "The run usage summary object." } }, "required": [ "id", "actId", "status" ], "additionalProperties": true, "description": "An Apify actor run." }, "nullable": false, "handle": "run" } ], "name": "Start the job board search", "executor": { "kind": "connector", "action": "apify.run_actor" } } }, "n_4d928acb2d26bb31": { "inputs": { "initial": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_f9eba88e2af1378e", "output": "run" } ] }, "previous": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_4d928acb2d26bb31", "output": "state" } ] }, "current": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_f3fa611447986acb", "output": "run" } ] } }, "name": "Check the search run", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "object", "properties": { "id": { "type": "string", "description": "The Apify run identifier." }, "actId": { "type": "string", "description": "The actor identifier associated with the run." }, "status": { "type": "string", "description": "The current run status." }, "startedAt": { "type": "string", "description": "When the run started." }, "finishedAt": { "type": "string", "description": "When the run finished." }, "defaultDatasetId": { "type": "string", "description": "The default dataset identifier created for the run." }, "defaultKeyValueStoreId": { "type": "string", "description": "The default key-value store identifier created for the run." }, "defaultRequestQueueId": { "type": "string", "description": "The default request queue identifier created for the run." }, "stats": { "type": "object", "properties": {}, "additionalProperties": true, "description": "The run statistics object." }, "options": { "type": "object", "properties": {}, "additionalProperties": true, "description": "The run options object." }, "usage": { "type": "object", "properties": {}, "additionalProperties": true, "description": "The run usage summary object." } }, "required": [ "id", "actId", "status" ], "additionalProperties": true, "description": "An Apify actor run." }, "nullable": false, "handle": "initial" }, { "jsonSchema": { "type": "object", "properties": { "id": { "type": "string", "description": "The Apify run identifier." }, "actId": { "type": "string", "description": "The actor identifier associated with the run." }, "status": { "type": "string", "description": "The current run status." }, "startedAt": { "type": "string", "description": "When the run started." }, "finishedAt": { "type": "string", "description": "When the run finished." }, "defaultDatasetId": { "type": "string", "description": "The default dataset identifier created for the run." }, "defaultKeyValueStoreId": { "type": "string", "description": "The default key-value store identifier created for the run." }, "defaultRequestQueueId": { "type": "string", "description": "The default request queue identifier created for the run." }, "stats": { "type": "object", "properties": {}, "additionalProperties": true, "description": "The run statistics object." }, "options": { "type": "object", "properties": {}, "additionalProperties": true, "description": "The run options object." }, "usage": { "type": "object", "properties": {}, "additionalProperties": true, "description": "The run usage summary object." } }, "required": [ "id", "actId", "status" ], "additionalProperties": true, "description": "An Apify actor run." }, "nullable": true, "handle": "current" }, { "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": "done" }, { "jsonSchema": { "type": "string", "minLength": 1, "description": "The Apify actor run identifier." }, "nullable": false, "handle": "runId" }, { "jsonSchema": { "type": "string", "minLength": 1, "description": "The Apify dataset identifier." }, "nullable": false, "handle": "datasetId" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "storeId" } ], "name": "Check the search run", "moduleId": "n_cf0d0109e678e5f6", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_347b4b927b8239e3": { "inputs": {}, "name": "Search complete?", "kind": "condition", "matchMode": "first", "cases": [ { "output": "yes", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_4d928acb2d26bb31", "output": "done" } }, "operator": "isTrue" } ] } ] } ] }, "n_5d5f5f966acab591": { "inputs": {}, "name": "Wait for the search", "kind": "wait", "inputDefinitions": [], "prompt": "Wait for the search", "autoContinue": { "kind": "after", "durationMs": 15000 } }, "n_f3fa611447986acb": { "inputs": { "runId": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_4d928acb2d26bb31", "output": "runId" } ] }, "waitForFinishSeconds": { "kind": "value", "value": 0 } }, "name": "Read search status", "kind": "task", "task": { "inputs": [ { "description": "The Apify actor run identifier.", "jsonSchema": { "type": "string", "minLength": 1, "description": "The Apify actor run identifier." }, "nullable": false, "handle": "runId" }, { "description": "How many seconds to wait for run completion before returning.", "jsonSchema": { "type": "integer", "minimum": 0, "description": "How many seconds to wait for run completion before returning." }, "nullable": true, "handle": "waitForFinishSeconds", "value": null } ], "outputs": [ { "description": "An Apify actor run.", "jsonSchema": { "type": "object", "properties": { "id": { "type": "string", "description": "The Apify run identifier." }, "actId": { "type": "string", "description": "The actor identifier associated with the run." }, "status": { "type": "string", "description": "The current run status." }, "startedAt": { "type": "string", "description": "When the run started." }, "finishedAt": { "type": "string", "description": "When the run finished." }, "defaultDatasetId": { "type": "string", "description": "The default dataset identifier created for the run." }, "defaultKeyValueStoreId": { "type": "string", "description": "The default key-value store identifier created for the run." }, "defaultRequestQueueId": { "type": "string", "description": "The default request queue identifier created for the run." }, "stats": { "type": "object", "properties": {}, "additionalProperties": true, "description": "The run statistics object." }, "options": { "type": "object", "properties": {}, "additionalProperties": true, "description": "The run options object." }, "usage": { "type": "object", "properties": {}, "additionalProperties": true, "description": "The run usage summary object." } }, "required": [ "id", "actId", "status" ], "additionalProperties": true, "description": "An Apify actor run." }, "nullable": false, "handle": "run" } ], "name": "Read search status", "executor": { "kind": "connector", "action": "apify.get_run" } } }, "n_721f1906e67fd529": { "inputs": { "previous": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_721f1906e67fd529", "output": "state" } ] }, "items": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_d1c4f5e3aa398fce", "output": "items" } ] } }, "name": "Read and process every page", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": true, "handle": "previous" }, { "jsonSchema": { "type": "array", "items": { "type": "object", "additionalProperties": { "description": "A JSON-compatible Apify value." }, "description": "A single item returned from an Apify dataset." }, "description": "The ordered list of Apify dataset items." }, "nullable": true, "handle": "items" } ], "outputs": [ { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "state" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "action" }, { "jsonSchema": { "type": "integer", "minimum": 0 }, "nullable": false, "handle": "offset" }, { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "item" } ], "name": "Read and process every page", "moduleId": "n_c19ae8030c229bb2", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_1a8f29f265b6a0fc": { "inputs": {}, "name": "Next search step", "kind": "condition", "matchMode": "first", "cases": [ { "output": "page", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_721f1906e67fd529", "output": "action" } }, "operator": "==", "right": { "kind": "value", "value": "page" } } ] } ] }, { "output": "item", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_721f1906e67fd529", "output": "action" } }, "operator": "==", "right": { "kind": "value", "value": "item" } } ] } ] } ] }, "n_d1c4f5e3aa398fce": { "inputs": { "datasetId": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_4d928acb2d26bb31", "output": "datasetId" } ] }, "limit": { "kind": "value", "value": 100 }, "offset": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_721f1906e67fd529", "output": "offset" } ] }, "clean": { "kind": "value", "value": false }, "skipHidden": { "kind": "value", "value": false } }, "name": "Read a job page", "kind": "task", "task": { "inputs": [ { "description": "The Apify dataset identifier.", "jsonSchema": { "type": "string", "minLength": 1, "description": "The Apify dataset identifier." }, "nullable": false, "handle": "datasetId" }, { "description": "The maximum number of items to return.", "jsonSchema": { "type": "integer", "minimum": 1, "description": "The maximum number of items to return." }, "nullable": true, "handle": "limit", "value": null }, { "description": "How many items to skip before returning results.", "jsonSchema": { "type": "integer", "minimum": 0, "description": "How many items to skip before returning results." }, "nullable": true, "handle": "offset", "value": null }, { "description": "Whether hidden fields and empty values should be removed from each item.", "jsonSchema": { "type": "boolean", "description": "Whether hidden fields and empty values should be removed from each item." }, "nullable": true, "handle": "clean", "value": null }, { "description": "Whether fields starting with a hash sign should be skipped.", "jsonSchema": { "type": "boolean", "description": "Whether fields starting with a hash sign should be skipped." }, "nullable": true, "handle": "skipHidden", "value": null } ], "outputs": [ { "description": "The ordered list of Apify dataset items.", "jsonSchema": { "type": "array", "items": { "type": "object", "additionalProperties": { "description": "A JSON-compatible Apify value." }, "description": "A single item returned from an Apify dataset." }, "description": "The ordered list of Apify dataset items." }, "nullable": false, "handle": "items" } ], "name": "Read a job page", "executor": { "kind": "connector", "action": "apify.get_dataset_items" } } }, "n_0bc3a00a94b0c2b9": { "inputs": { "item": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_721f1906e67fd529", "output": "item" } ] } }, "name": "Prepare the history lookup", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "item" } ], "outputs": [ { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "formula" }, { "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 the history lookup", "moduleId": "n_419a50ed8cd1381c", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_7242f2ebf800b7a5": { "inputs": {}, "name": "Pace history reads", "kind": "wait", "inputDefinitions": [], "prompt": "Pace history reads", "autoContinue": { "kind": "after", "durationMs": 250 } }, "n_de1db3cc4b7f4ad9": { "inputs": {}, "name": "Pace history writes", "kind": "wait", "inputDefinitions": [], "prompt": "Pace history writes", "autoContinue": { "kind": "after", "durationMs": 250 } }, "n_cc214255a725a739": { "inputs": { "baseId": { "kind": "value", "value": "YOUR_AIRTABLE_BASE_ID" }, "tableIdOrName": { "kind": "value", "value": "Hiring history" }, "filterByFormula": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_0bc3a00a94b0c2b9", "output": "formula" } ] }, "maxRecords": { "kind": "value", "value": 1 } }, "name": "Check job history", "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": "View name or view ID used by Airtable to filter and sort results.", "jsonSchema": { "type": "string", "minLength": 1, "description": "View name or view ID used by Airtable to filter and sort results." }, "nullable": true, "handle": "view", "value": null }, { "description": "Field names or field IDs to include in the Airtable response.", "jsonSchema": { "type": "array", "items": { "type": "string", "minLength": 1, "description": "An array item." }, "minItems": 1, "description": "Field names or field IDs to include in the Airtable response." }, "nullable": true, "handle": "fields", "value": null }, { "description": "Sort rules applied by Airtable in order.", "jsonSchema": { "type": "array", "items": { "type": "object", "properties": { "field": { "type": "string", "minLength": 1, "description": "Field name or field ID used by Airtable for sorting." }, "direction": { "type": "string", "enum": [ "asc", "desc" ], "description": "Sort direction accepted by Airtable." } }, "required": [ "field" ], "additionalProperties": false, "description": "Sort rule accepted by the Airtable list records endpoint." }, "minItems": 1, "description": "Sort rules applied by Airtable in order." }, "nullable": true, "handle": "sort", "value": null }, { "description": "Formula string evaluated by Airtable to filter matching records.", "jsonSchema": { "type": "string", "minLength": 1, "description": "Formula string evaluated by Airtable to filter matching records." }, "nullable": true, "handle": "filterByFormula", "value": null }, { "description": "Maximum total number of records to return before Airtable stops pagination.", "jsonSchema": { "type": "integer", "minimum": 1, "description": "Maximum total number of records to return before Airtable stops pagination." }, "nullable": true, "handle": "maxRecords", "value": null }, { "description": "Number of records to return per page.", "jsonSchema": { "type": "integer", "minimum": 1, "maximum": 100, "description": "Number of records to return per page." }, "nullable": true, "handle": "pageSize", "value": null }, { "description": "Opaque pagination cursor returned by a previous Airtable response.", "jsonSchema": { "type": "string", "minLength": 1, "description": "Opaque pagination cursor returned by a previous Airtable response." }, "nullable": true, "handle": "offset", "value": null }, { "description": "Cell format accepted by Airtable for read operations.", "jsonSchema": { "type": "string", "enum": [ "json", "string" ], "description": "Cell format accepted by Airtable for read operations." }, "nullable": true, "handle": "cellFormat", "value": null }, { "description": "Timezone string sent to Airtable when cellFormat is string.", "jsonSchema": { "type": "string", "minLength": 1, "description": "Timezone string sent to Airtable when cellFormat is string." }, "nullable": true, "handle": "timeZone", "value": null }, { "description": "User locale sent to Airtable when cellFormat is string.", "jsonSchema": { "type": "string", "minLength": 1, "description": "User locale sent to Airtable when cellFormat is string." }, "nullable": true, "handle": "userLocale", "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 }, { "description": "Whether Airtable should return date dependency metadata for linked record fields.", "jsonSchema": { "type": "boolean", "description": "Whether Airtable should return date dependency metadata for linked record fields." }, "nullable": true, "handle": "includeDateDependencyMetadata", "value": null }, { "description": "Record metadata fields to include in Airtable list records responses.", "jsonSchema": { "type": "array", "items": { "const": "commentCount", "description": "An array item." }, "minItems": 1, "description": "Record metadata fields to include in Airtable list records responses." }, "nullable": true, "handle": "recordMetadata", "value": null } ], "outputs": [ { "description": "Records returned 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 returned by Airtable." }, "nullable": false, "handle": "records" }, { "description": "Pagination cursor for the next page of records, or null when unavailable.", "jsonSchema": { "type": [ "string", "null" ], "description": "Pagination cursor for the next page of records, or null when unavailable." }, "nullable": true, "handle": "offset" } ], "name": "Check job history", "executor": { "kind": "connector", "action": "airtable.list_records" } } }, "n_683f630a34e67287": { "inputs": { "records": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_cc214255a725a739", "output": "records" } ] } }, "name": "Check for a prior alert", "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 returned by Airtable." }, "nullable": false, "handle": "records" } ], "outputs": [ { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "seen" } ], "name": "Check for a prior alert", "moduleId": "n_b9af90f3154d79f8", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_a4e937117d76e101": { "inputs": {}, "name": "Already observed?", "kind": "condition", "matchMode": "first", "cases": [ { "output": "yes", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_683f630a34e67287", "output": "seen" } }, "operator": "isTrue" } ] } ] } ] }, "n_5dc4d27cb02da2fa": { "inputs": { "baseId": { "kind": "value", "value": "YOUR_AIRTABLE_BASE_ID" }, "tableIdOrName": { "kind": "value", "value": "Hiring history" }, "records": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_0bc3a00a94b0c2b9", "output": "records" } ] } }, "name": "Record the job key", "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": "Record the job key", "executor": { "kind": "connector", "action": "airtable.create_records" } } }, "n_4e3791fb6d66c1c5": { "inputs": { "records": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_5dc4d27cb02da2fa", "output": "records" } ] } }, "name": "Confirm the history record", "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" } ], "outputs": [ { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "ok" } ], "name": "Confirm the history record", "moduleId": "n_03586c81877f78bf", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_1ff1bfd9d40deed8": { "inputs": { "item": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_721f1906e67fd529", "output": "item" } ] } }, "name": "Prepare the job alert", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "item" } ], "outputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "text" } ], "name": "Prepare the job alert", "moduleId": "n_9b5a38292243ee3a", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_7aa47ec30ca2ace8": { "inputs": { "channelId": { "kind": "value", "value": "YOUR_SLACK_CHANNEL_ID" }, "text": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_1ff1bfd9d40deed8", "output": "text" } ] } }, "name": "Post the job to Slack", "kind": "task", "task": { "inputs": [ { "description": "The Slack conversation or channel ID.", "jsonSchema": { "type": "string", "minLength": 1, "description": "The Slack conversation or channel ID." }, "nullable": false, "handle": "channelId" }, { "description": "Plain text message content. When blocks are provided, Slack uses this as notification and accessibility fallback text.", "jsonSchema": { "type": "string", "description": "Plain text message content. When blocks are provided, Slack uses this as notification and accessibility fallback text." }, "nullable": true, "handle": "text", "value": null }, { "description": "Slack Block Kit blocks to render in the message.", "jsonSchema": { "type": "array", "items": { "type": "object", "properties": {}, "additionalProperties": true, "description": "A Slack Block Kit block object. Pass the block exactly as Slack documents it." }, "minItems": 1, "description": "Slack Block Kit blocks to render in the message." }, "nullable": true, "handle": "blocks", "value": null }, { "description": "Slack legacy attachments to include in the message.", "jsonSchema": { "type": "array", "items": { "type": "object", "properties": {}, "additionalProperties": true, "description": "A Slack legacy attachment object. Prefer blocks for new messages when possible." }, "minItems": 1, "description": "Slack legacy attachments to include in the message." }, "nullable": true, "handle": "attachments", "value": null }, { "description": "Whether Slack should unfurl links in the message.", "jsonSchema": { "type": "boolean", "description": "Whether Slack should unfurl links in the message." }, "nullable": true, "handle": "unfurlLinks", "value": null }, { "description": "Whether Slack should unfurl media in the message.", "jsonSchema": { "type": "boolean", "description": "Whether Slack should unfurl media in the message." }, "nullable": true, "handle": "unfurlMedia", "value": null }, { "description": "Slack message metadata to attach to the message.", "jsonSchema": { "type": "object", "properties": {}, "additionalProperties": true, "description": "Slack message metadata to attach to the message." }, "nullable": true, "handle": "metadata", "value": null } ], "outputs": [ { "description": "The timestamp identifier of the posted message.", "jsonSchema": { "type": "string", "description": "The timestamp identifier of the posted message." }, "nullable": false, "handle": "ts" }, { "description": "The channel ID where the message was posted.", "jsonSchema": { "type": "string", "description": "The channel ID where the message was posted." }, "nullable": false, "handle": "channelId" } ], "name": "Post the job to Slack", "executor": { "kind": "connector", "action": "slack.post_message" } } } }, "edges": [ { "source": "n_7dbe58312033a42f", "target": "n_f9eba88e2af1378e" }, { "source": "n_f9eba88e2af1378e", "target": "n_4d928acb2d26bb31" }, { "source": "n_4d928acb2d26bb31", "target": "n_347b4b927b8239e3" }, { "source": "n_347b4b927b8239e3", "target": "n_721f1906e67fd529", "sourceHandle": "yes" }, { "source": "n_347b4b927b8239e3", "target": "n_5d5f5f966acab591", "sourceHandle": "otherwise" }, { "source": "n_5d5f5f966acab591", "target": "n_f3fa611447986acb", "sourceHandle": "continue" }, { "source": "n_f3fa611447986acb", "target": "n_4d928acb2d26bb31" }, { "source": "n_721f1906e67fd529", "target": "n_1a8f29f265b6a0fc" }, { "source": "n_1a8f29f265b6a0fc", "target": "n_d1c4f5e3aa398fce", "sourceHandle": "page" }, { "source": "n_d1c4f5e3aa398fce", "target": "n_721f1906e67fd529" }, { "source": "n_1a8f29f265b6a0fc", "target": "n_0bc3a00a94b0c2b9", "sourceHandle": "item" }, { "source": "n_0bc3a00a94b0c2b9", "target": "n_7242f2ebf800b7a5" }, { "source": "n_7242f2ebf800b7a5", "target": "n_cc214255a725a739", "sourceHandle": "continue" }, { "source": "n_cc214255a725a739", "target": "n_683f630a34e67287" }, { "source": "n_683f630a34e67287", "target": "n_a4e937117d76e101" }, { "source": "n_a4e937117d76e101", "target": "n_721f1906e67fd529", "sourceHandle": "yes" }, { "source": "n_a4e937117d76e101", "target": "n_de1db3cc4b7f4ad9", "sourceHandle": "otherwise" }, { "source": "n_de1db3cc4b7f4ad9", "target": "n_5dc4d27cb02da2fa", "sourceHandle": "continue" }, { "source": "n_5dc4d27cb02da2fa", "target": "n_4e3791fb6d66c1c5" }, { "source": "n_4e3791fb6d66c1c5", "target": "n_1ff1bfd9d40deed8" }, { "source": "n_1ff1bfd9d40deed8", "target": "n_7aa47ec30ca2ace8" }, { "source": "n_7aa47ec30ca2ace8", "target": "n_721f1906e67fd529" } ] } }, "modules": { "n_cf0d0109e678e5f6": { "name": "Check the search run", "imports": [], "source": "export default function run({initial,current,previous}){const x=current??initial;if(!x||typeof x.id!=='string'||!x.id||typeof x.status!=='string')throw Error('Invalid Actor run');if(previous?.id&&previous.id!==x.id)throw Error('Actor run changed');if(['FAILED','ABORTED','TIMED-OUT'].includes(x.status))throw Error('Actor failed');const done=x.status==='SUCCEEDED',count=(previous?.count??0)+1;if(!done&&count>80)throw Error('Actor wait exceeded');if(done&&(!x.defaultDatasetId||!x.defaultKeyValueStoreId))throw Error('Actor output IDs missing');return{state:{id:x.id,count},done,runId:x.id,datasetId:x.defaultDatasetId??'pending',storeId:x.defaultKeyValueStoreId??'pending'};}\n" }, "n_c19ae8030c229bb2": { "name": "Read and process every page", "imports": [], "source": "export default function pages({previous,items}){const s=previous??{phase:'preflight',offset:0,awaiting:false};if(s.awaiting){if(!Array.isArray(items)||items.length>100)throw Error('Invalid dataset page');if(s.phase==='preflight'){if(items.length===100)s.offset+=100;else{s.phase='process';s.offset=0}}else{if(items.length===0){s.phase='done'}else{s.page=items.map(x=>{if(!x||typeof x.platform!=='string'||typeof x.companySlug!=='string'||typeof x.jobId!=='string'||!x.platform||!x.companySlug||!x.jobId)throw Error('Job identity missing');return{key:x.platform+':'+x.companySlug+':'+x.jobId,company:x.company||x.companySlug,title:x.title??'',location:x.location??'',url:x.applyUrl??''}});s.last=items.length<100;s.index=0;s.phase='items'}}s.awaiting=false}if(s.phase==='items'){if(s.index0};}\n" }, "n_03586c81877f78bf": { "name": "Confirm the history record", "imports": [], "source": "export default function confirm({records}){if(!Array.isArray(records)||records.length!==1||!records[0]?.id)throw Error('History write not confirmed');return{ok:true};}\n" }, "n_9b5a38292243ee3a": { "name": "Prepare the job alert", "imports": [], "source": "export default function message({item}){const esc=x=>String(x??'').replaceAll('&','&').replaceAll('<','<').replaceAll('>','>');return{text:`${esc(item.company)} is hiring: ${esc(item.title)} (${esc(item.location)}) ${esc(item.url)}`};}\n" } } }, "presentation": { "designer": { "version": 1, "flow": { "direction": "vertical" } } } }