{ "kind": "open-flow-workflow", "version": 1, "name": "Mark HubSpot Deals Paid from Stripe Invoices", "content": { "modelVersion": 14, "document": { "bindings": {}, "graph": { "nodes": { "n_e99982b7299e1229": { "name": "Receive paid invoice", "kind": "integration", "config": { "apiVersion": { "kind": "value", "value": "" }, "events": { "kind": "value", "value": [ "invoice.payment_succeeded" ] }, "includeConnectedAccounts": { "kind": "value", "value": false } }, "definition": { "configInputs": [ { "jsonSchema": { "type": "string", "maxLength": 40 }, "nullable": false, "handle": "apiVersion", "value": "" }, { "jsonSchema": { "type": "array", "items": { "type": "string", "maxLength": 120, "pattern": "^(\\*|[a-z0-9_]+(?:\\.[a-z0-9_]+)+)$" }, "minItems": 1, "uniqueItems": true }, "nullable": false, "handle": "events" }, { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "includeConnectedAccounts", "value": false } ], "definitionVersion": 2, "description": "Triggers when selected Stripe events happen on the connected account.", "displayName": "Account Event", "key": "stripe.on_event", "name": "on_event", "outputs": [ { "jsonSchema": { "type": "object" }, "nullable": false, "handle": "body" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "event" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "eventId" }, { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "livemode" } ], "provider": "stripe", "type": "integration", "endpoint": { "body": { "allowArray": false, "allowEmpty": false, "formats": [ "json" ] }, "methods": [ "POST" ], "successStatus": 202 } } }, "n_3ef0cfd1cf1315dc": { "inputs": { "body": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_e99982b7299e1229", "output": "body" } ] }, "eventId": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_e99982b7299e1229", "output": "eventId" } ] }, "channelId": { "kind": "value", "value": "YOUR_SLACK_CHANNEL_ID" } }, "name": "Prepare the invoice alert", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "body" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "eventId" }, { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "channelId" } ], "outputs": [ { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "hasPo" }, { "jsonSchema": { "type": "array", "items": { "type": "object", "properties": {}, "additionalProperties": true, "description": "HubSpot CRM search filter group." }, "maxItems": 5, "description": "HubSpot filter groups used to narrow the search." }, "nullable": false, "handle": "filterGroups" }, { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "channelId" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "paidText" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "noPoText" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "missingText" } ], "name": "Prepare the invoice alert", "moduleId": "n_e13515b5ca1f4d05", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_5070afa053c024be": { "inputs": {}, "name": "Has a purchase order?", "kind": "condition", "matchMode": "first", "cases": [ { "output": "yes", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_3ef0cfd1cf1315dc", "output": "hasPo" } }, "operator": "==", "right": { "kind": "value", "value": true } } ] } ] } ] }, "n_2ee5dc6896f67d93": { "inputs": { "channelId": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_3ef0cfd1cf1315dc", "output": "channelId" } ] }, "text": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_3ef0cfd1cf1315dc", "output": "noPoText" } ] } }, "name": "Alert missing purchase order", "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": "Alert missing purchase order", "executor": { "kind": "connector", "action": "slack.post_message" } } }, "n_fd69167f26cdf1e3": { "inputs": { "filterGroups": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_3ef0cfd1cf1315dc", "output": "filterGroups" } ] }, "sorts": { "kind": "value", "value": [ "-createdate" ] }, "limit": { "kind": "value", "value": 100 } }, "name": "Find matching HubSpot deals", "kind": "task", "task": { "inputs": [ { "description": "Full-text query applied to the HubSpot CRM search.", "jsonSchema": { "type": "string", "description": "Full-text query applied to the HubSpot CRM search." }, "nullable": true, "handle": "query", "value": null }, { "description": "HubSpot filter groups used to narrow the search.", "jsonSchema": { "type": "array", "items": { "type": "object", "properties": {}, "additionalProperties": true, "description": "HubSpot CRM search filter group." }, "maxItems": 5, "description": "HubSpot filter groups used to narrow the search." }, "nullable": true, "handle": "filterGroups", "value": null }, { "description": "HubSpot sort expressions.", "jsonSchema": { "type": "array", "items": { "type": "string", "minLength": 1, "description": "HubSpot sort expression." }, "description": "HubSpot sort expressions." }, "nullable": true, "handle": "sorts", "value": null }, { "description": "Property names to include in the returned record payload.", "jsonSchema": { "type": "array", "items": { "type": "string", "minLength": 1, "description": "HubSpot property name." }, "description": "Property names to include in the returned record payload." }, "nullable": true, "handle": "properties", "value": null }, { "description": "Property names to include with their value history.", "jsonSchema": { "type": "array", "items": { "type": "string", "minLength": 1, "description": "HubSpot property name." }, "description": "Property names to include with their value history." }, "nullable": true, "handle": "propertiesWithHistory", "value": null }, { "description": "Associated object types to include in the response.", "jsonSchema": { "type": "array", "items": { "type": "string", "minLength": 1, "description": "HubSpot associated object type." }, "description": "Associated object types to include in the response." }, "nullable": true, "handle": "associations", "value": null }, { "description": "Maximum number of records to return.", "jsonSchema": { "type": "integer", "minimum": 1, "maximum": 200, "description": "Maximum number of records to return." }, "nullable": true, "handle": "limit", "value": null }, { "description": "Paging cursor returned by a previous search request.", "jsonSchema": { "type": "string", "minLength": 1, "description": "Paging cursor returned by a previous search request." }, "nullable": true, "handle": "after", "value": null } ], "outputs": [ { "description": "Records returned by the search request.", "jsonSchema": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "HubSpot record identifier." }, "archived": { "type": "boolean", "description": "Whether the record is archived." }, "createdAt": { "type": "string", "description": "Timestamp when the record was created." }, "updatedAt": { "type": "string", "description": "Timestamp when the record was last updated." }, "properties": { "type": "object", "additionalProperties": { "description": "Property value." }, "description": "HubSpot properties keyed by property name." }, "propertiesWithHistory": { "type": "object", "additionalProperties": { "description": "Property history payload." }, "description": "HubSpot property histories keyed by property name." }, "associations": { "type": "object", "properties": {}, "additionalProperties": true, "description": "Associations returned by HubSpot when requested." } }, "additionalProperties": true, "description": "HubSpot CRM record returned by the MCP server." }, "description": "Records returned by the search request." }, "nullable": false, "handle": "results" }, { "description": "Paging information returned by HubSpot.", "jsonSchema": { "type": "object", "properties": { "nextAfter": { "type": "string", "description": "Cursor for the next search request when another page is available." } }, "additionalProperties": true, "description": "Paging information returned by HubSpot." }, "nullable": true, "handle": "paging" }, { "description": "Raw MCP response payload.", "jsonSchema": { "description": "Raw MCP response payload." }, "nullable": true, "handle": "raw" } ], "name": "Find matching HubSpot deals", "executor": { "kind": "connector", "action": "hubspot.search_deals" } } }, "n_72222fb77f4c195f": { "inputs": { "results": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_fd69167f26cdf1e3", "output": "results" } ] }, "paging": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_fd69167f26cdf1e3", "output": "paging" } ] }, "previousState": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_72222fb77f4c195f", "output": "state" } ] }, "updatedRecord": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_616454a9cf5f97d2", "output": "record" } ] }, "slackTs": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_43e7381c49451668", "output": "ts" } ] } }, "name": "Process the matching deals", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "HubSpot record identifier." }, "archived": { "type": "boolean", "description": "Whether the record is archived." }, "createdAt": { "type": "string", "description": "Timestamp when the record was created." }, "updatedAt": { "type": "string", "description": "Timestamp when the record was last updated." }, "properties": { "type": "object", "additionalProperties": { "description": "Property value." }, "description": "HubSpot properties keyed by property name." }, "propertiesWithHistory": { "type": "object", "additionalProperties": { "description": "Property history payload." }, "description": "HubSpot property histories keyed by property name." }, "associations": { "type": "object", "properties": {}, "additionalProperties": true, "description": "Associations returned by HubSpot when requested." } }, "additionalProperties": true, "description": "HubSpot CRM record returned by the MCP server." }, "description": "Records returned by the search request." }, "nullable": false, "handle": "results" }, { "jsonSchema": { "type": "object", "properties": { "nextAfter": { "type": "string", "description": "Cursor for the next search request when another page is available." } }, "additionalProperties": true, "description": "Paging information returned by HubSpot." }, "nullable": true, "handle": "paging" }, { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": true, "handle": "previousState" }, { "jsonSchema": { "type": "object", "properties": { "id": { "type": "string", "description": "HubSpot record identifier." }, "archived": { "type": "boolean", "description": "Whether the record is archived." }, "createdAt": { "type": "string", "description": "Timestamp when the record was created." }, "updatedAt": { "type": "string", "description": "Timestamp when the record was last updated." }, "properties": { "type": "object", "additionalProperties": { "description": "Property value." }, "description": "HubSpot properties keyed by property name." }, "propertiesWithHistory": { "type": "object", "additionalProperties": { "description": "Property history payload." }, "description": "HubSpot property histories keyed by property name." }, "associations": { "type": "object", "properties": {}, "additionalProperties": true, "description": "Associations returned by HubSpot when requested." } }, "additionalProperties": true, "description": "HubSpot CRM record returned by the MCP server." }, "nullable": true, "handle": "updatedRecord" }, { "jsonSchema": { "type": "string", "description": "The timestamp identifier of the posted message." }, "nullable": true, "handle": "slackTs" } ], "outputs": [ { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "state" }, { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "more" }, { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "updating" }, { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "empty" }, { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "recordId" } ], "name": "Process the matching deals", "moduleId": "n_9e894efffe36a5f5", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_19254f0015fac999": { "inputs": {}, "name": "Any deal work remaining?", "kind": "condition", "matchMode": "first", "cases": [ { "output": "more", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_72222fb77f4c195f", "output": "more" } }, "operator": "==", "right": { "kind": "value", "value": true } } ] } ] } ] }, "n_d75882b0a5fc9d98": { "inputs": {}, "name": "Update or notify?", "kind": "condition", "matchMode": "first", "cases": [ { "output": "update", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_72222fb77f4c195f", "output": "updating" } }, "operator": "==", "right": { "kind": "value", "value": true } } ] } ] } ] }, "n_616454a9cf5f97d2": { "inputs": { "recordId": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_72222fb77f4c195f", "output": "recordId" } ] }, "properties": { "kind": "value", "value": { "paid": "Yes" } } }, "name": "Mark the deal paid", "kind": "task", "task": { "inputs": [ { "description": "HubSpot record identifier.", "jsonSchema": { "type": "string", "minLength": 1, "description": "HubSpot record identifier." }, "nullable": false, "handle": "recordId" }, { "description": "Alternate unique property name that should resolve recordId.", "jsonSchema": { "type": "string", "minLength": 1, "description": "Alternate unique property name that should resolve recordId." }, "nullable": true, "handle": "idProperty", "value": null }, { "description": "HubSpot properties keyed by property name.", "jsonSchema": { "type": "object", "additionalProperties": { "description": "HubSpot property value." }, "description": "HubSpot properties keyed by property name." }, "nullable": false, "handle": "properties" } ], "outputs": [ { "description": "HubSpot CRM record returned by the MCP server.", "jsonSchema": { "type": "object", "properties": { "id": { "type": "string", "description": "HubSpot record identifier." }, "archived": { "type": "boolean", "description": "Whether the record is archived." }, "createdAt": { "type": "string", "description": "Timestamp when the record was created." }, "updatedAt": { "type": "string", "description": "Timestamp when the record was last updated." }, "properties": { "type": "object", "additionalProperties": { "description": "Property value." }, "description": "HubSpot properties keyed by property name." }, "propertiesWithHistory": { "type": "object", "additionalProperties": { "description": "Property history payload." }, "description": "HubSpot property histories keyed by property name." }, "associations": { "type": "object", "properties": {}, "additionalProperties": true, "description": "Associations returned by HubSpot when requested." } }, "additionalProperties": true, "description": "HubSpot CRM record returned by the MCP server." }, "nullable": false, "handle": "record" } ], "name": "Mark the deal paid", "executor": { "kind": "connector", "action": "hubspot.update_deal" } } }, "n_43e7381c49451668": { "inputs": { "channelId": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_3ef0cfd1cf1315dc", "output": "channelId" } ] }, "text": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_3ef0cfd1cf1315dc", "output": "paidText" } ] } }, "name": "Notify paid invoice", "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": "Notify paid invoice", "executor": { "kind": "connector", "action": "slack.post_message" } } }, "n_4463b2675edc0adf": { "inputs": {}, "name": "No matching deal?", "kind": "condition", "matchMode": "first", "cases": [ { "output": "empty", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_72222fb77f4c195f", "output": "empty" } }, "operator": "==", "right": { "kind": "value", "value": true } } ] } ] } ] }, "n_ea7be8135991c9ea": { "inputs": { "channelId": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_3ef0cfd1cf1315dc", "output": "channelId" } ] }, "text": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_3ef0cfd1cf1315dc", "output": "missingText" } ] } }, "name": "Alert deal not found", "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": "Alert deal not found", "executor": { "kind": "connector", "action": "slack.post_message" } } } }, "edges": [ { "source": "n_e99982b7299e1229", "target": "n_3ef0cfd1cf1315dc" }, { "source": "n_3ef0cfd1cf1315dc", "target": "n_5070afa053c024be" }, { "source": "n_5070afa053c024be", "target": "n_2ee5dc6896f67d93", "sourceHandle": "otherwise" }, { "source": "n_5070afa053c024be", "target": "n_fd69167f26cdf1e3", "sourceHandle": "yes" }, { "source": "n_fd69167f26cdf1e3", "target": "n_72222fb77f4c195f" }, { "source": "n_72222fb77f4c195f", "target": "n_19254f0015fac999" }, { "source": "n_19254f0015fac999", "target": "n_d75882b0a5fc9d98", "sourceHandle": "more" }, { "source": "n_d75882b0a5fc9d98", "target": "n_616454a9cf5f97d2", "sourceHandle": "update" }, { "source": "n_616454a9cf5f97d2", "target": "n_72222fb77f4c195f" }, { "source": "n_d75882b0a5fc9d98", "target": "n_43e7381c49451668", "sourceHandle": "otherwise" }, { "source": "n_43e7381c49451668", "target": "n_72222fb77f4c195f" }, { "source": "n_19254f0015fac999", "target": "n_4463b2675edc0adf", "sourceHandle": "otherwise" }, { "source": "n_4463b2675edc0adf", "target": "n_ea7be8135991c9ea", "sourceHandle": "empty" } ] } }, "modules": { "n_e13515b5ca1f4d05": { "name": "Prepare the invoice alert", "imports": [], "source": "export default function paidInvoice({body,eventId,channelId}) {\n if(!body||body.type!=='invoice.payment_succeeded'||body.id!==eventId||typeof eventId!=='string'||!eventId)throw Error('Invalid Stripe event');const x=body.data?.object;\n if(!x||!Number.isSafeInteger(x.amount_paid)||x.amount_paid<0||typeof x.currency!=='string'||!/^[A-Za-z]{3}$/.test(x.currency))throw Error('Invalid invoice amount or currency');if(typeof channelId!=='string'||!channelId.trim()||channelId==='YOUR_SLACK_CHANNEL_ID')throw Error('Configure Slack channel');\n const po=Array.isArray(x.custom_fields)&&typeof x.custom_fields[0]?.value==='string'?x.custom_fields[0].value.trim():'';const safe=v=>String(v??'').replace(/&/g,'&').replace(//g,'>').replace(/[\\r\\n]+/g,' ');const details='Amount (minor units): '+x.amount_paid+' '+x.currency.toUpperCase()+'\\nCustomer: '+safe(x.customer_name)+'\\nEmail: '+safe(x.customer_email)+'\\nStripe event: '+safe(eventId);return{hasPo:!!po,filterGroups:[{filters:[{propertyName:'po_number',operator:'EQ',value:po}]}],channelId,paidText:':sparkles: An invoice has been paid :sparkles:\\n'+details+'\\nPO Number: '+safe(po),noPoText:':x: Stripe payment with no PO Number :x:\\n'+details,missingText:':x: Unable to find deal for the payment :x:\\n'+details+'\\nPO Number: '+safe(po)};\n}\n" }, "n_9e894efffe36a5f5": { "name": "Process the matching deals", "imports": [], "source": "export default function nextPaidDeal({results,paging,previousState,updatedRecord,slackTs}) {\n if(!Array.isArray(results)||results.length>100)throw Error('Invalid HubSpot search result');if(paging?.nextAfter)throw Error('More than 100 matching deals; inspect HubSpot before updating');const deals=[...results];for(const d of deals)if(!d||typeof d.id!=='string'||!d.id||typeof d.createdAt!=='string'||!Number.isFinite(Date.parse(d.createdAt)))throw Error('Invalid deal or creation date');deals.sort((a,b)=>Date.parse(b.createdAt)-Date.parse(a.createdAt));if(new Set(deals.map(x=>x.id)).size!==deals.length)throw Error('Duplicate deal IDs');let phase='update',index=0;\n if(previousState!==null){if(!Number.isInteger(previousState.index)||previousState.index<0||previousState.index>=deals.length)throw Error('Invalid deal progress');if(previousState.phase==='update'){if(updatedRecord?.id!==deals[previousState.index].id)throw Error('Deal update not confirmed');}else if(previousState.phase==='notify'){if(typeof slackTs!=='string'||!slackTs)throw Error('Slack delivery not confirmed');}else throw Error('Invalid phase');phase=previousState.phase;index=previousState.index+1;if(index===deals.length){phase=phase==='update'?'notify':'done';index=0;}}\n if(!deals.length)phase='done';return{state:{phase,index},more:phase!=='done',updating:phase==='update',empty:deals.length===0,recordId:phase!=='done'?deals[index].id:'-'};\n}\n" } } }, "presentation": { "designer": { "version": 1, "flow": { "direction": "vertical" } } } }