{ "kind": "open-flow-workflow", "version": 1, "name": "Alert on HTTP Status by SMS", "content": { "modelVersion": 14, "document": { "bindings": {}, "graph": { "nodes": { "n_23bf965089a628ca": { "name": "Every five minutes", "kind": "cron", "cronTimes": [ { "type": "cron", "expression": "*/5 * * * *", "timezone": "UTC" } ] }, "n_a004452aea747d4b": { "inputs": { "initialUrl": { "kind": "value", "value": "YOUR_MONITORED_URL" }, "previousState": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_c57969bfdaea1539", "output": "state" } ] } }, "name": "Prepare the HTTP target", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "initialUrl" }, { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": true, "handle": "previousState" } ], "outputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "url" } ], "name": "Prepare the HTTP target", "moduleId": "n_7e9d20ced39ab10d", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_c43d1d794093d8ed": { "inputs": { "url": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_a004452aea747d4b", "output": "url" } ] } }, "name": "Check the HTTP status", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "url" } ], "outputs": [ { "jsonSchema": { "type": "string" }, "nullable": true, "handle": "body" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "statusCode" }, { "jsonSchema": { "type": "object", "additionalProperties": { "type": "string" } }, "nullable": false, "handle": "headers" } ], "name": "Check the HTTP status", "executor": { "method": "GET", "query": { "mode": "fields", "names": [] }, "headers": { "mode": "fields", "names": [] }, "bodyFormat": "none", "authentication": { "type": "none" }, "responseFormat": "text", "statusPolicy": "all", "kind": "http-request" } } }, "n_c57969bfdaea1539": { "inputs": { "url": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_a004452aea747d4b", "output": "url" } ] }, "statusCode": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_c43d1d794093d8ed", "output": "statusCode" } ] }, "headers": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_c43d1d794093d8ed", "output": "headers" } ] }, "previousState": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_c57969bfdaea1539", "output": "state" } ] } }, "name": "Evaluate the HTTP response", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "url" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "statusCode" }, { "jsonSchema": { "type": "object", "additionalProperties": { "type": "string" } }, "nullable": false, "handle": "headers" }, { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": true, "handle": "previousState" } ], "outputs": [ { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "state" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "phase" } ], "name": "Evaluate the HTTP response", "moduleId": "n_95feb37df67231f1", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_47771c576b4f143d": { "inputs": {}, "name": "Follow or alert?", "kind": "condition", "matchMode": "first", "cases": [ { "output": "follow", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_c57969bfdaea1539", "output": "phase" } }, "operator": "==", "right": { "kind": "value", "value": "follow" } } ] } ] }, { "output": "send", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_c57969bfdaea1539", "output": "phase" } }, "operator": "==", "right": { "kind": "value", "value": "send" } } ] } ] } ] }, "n_f3098476f62add18": { "inputs": { "to": { "kind": "value", "value": "YOUR_RECIPIENT_NUMBER" }, "from": { "kind": "value", "value": "YOUR_TWILIO_NUMBER" }, "body": { "kind": "value", "value": "Service Down" } }, "name": "Send the SMS alert", "kind": "task", "task": { "inputs": [ { "description": "The destination phone number in E.164 format.", "jsonSchema": { "type": "string", "description": "The destination phone number in E.164 format." }, "nullable": false, "handle": "to" }, { "description": "The Twilio phone number sending the message.", "jsonSchema": { "type": "string", "description": "The Twilio phone number sending the message." }, "nullable": false, "handle": "from" }, { "description": "The text body of the outbound message.", "jsonSchema": { "type": "string", "description": "The text body of the outbound message." }, "nullable": false, "handle": "body" } ], "outputs": [ { "description": "The Twilio message SID.", "jsonSchema": { "type": "string", "description": "The Twilio message SID." }, "nullable": false, "handle": "messageSid" }, { "description": "The Twilio account SID that owns the message.", "jsonSchema": { "type": [ "string", "null" ], "description": "The Twilio account SID that owns the message." }, "nullable": true, "handle": "accountSid" }, { "description": "The delivery status of the message.", "jsonSchema": { "type": [ "string", "null" ], "description": "The delivery status of the message." }, "nullable": true, "handle": "status" }, { "description": "The destination phone number.", "jsonSchema": { "type": [ "string", "null" ], "description": "The destination phone number." }, "nullable": true, "handle": "to" }, { "description": "The sender phone number.", "jsonSchema": { "type": [ "string", "null" ], "description": "The sender phone number." }, "nullable": true, "handle": "from" }, { "description": "The text body of the message.", "jsonSchema": { "type": [ "string", "null" ], "description": "The text body of the message." }, "nullable": true, "handle": "body" } ], "name": "Send the SMS alert", "executor": { "kind": "connector", "action": "twilio.send_message" } } } }, "edges": [ { "source": "n_23bf965089a628ca", "target": "n_a004452aea747d4b" }, { "source": "n_a004452aea747d4b", "target": "n_c43d1d794093d8ed" }, { "source": "n_c43d1d794093d8ed", "target": "n_c57969bfdaea1539" }, { "source": "n_c57969bfdaea1539", "target": "n_47771c576b4f143d" }, { "source": "n_47771c576b4f143d", "target": "n_a004452aea747d4b", "sourceHandle": "follow" }, { "source": "n_47771c576b4f143d", "target": "n_f3098476f62add18", "sourceHandle": "send" } ] } }, "modules": { "n_7e9d20ced39ab10d": { "name": "Prepare the HTTP target", "imports": [], "source": "export default function hop({initialUrl,previousState}) {const candidate=previousState?.nextUrl||initialUrl;let url;try{url=new URL(candidate)}catch{throw Error('Configure a valid HTTP or HTTPS target URL')}if(!['http:','https:'].includes(url.protocol)||url.username||url.password)throw Error('Configure an HTTP or HTTPS URL without credentials');return{url:url.toString()};}\n" }, "n_95feb37df67231f1": { "name": "Evaluate the HTTP response", "imports": [], "source": "export default function status({url,statusCode,headers,previousState}){if(!Number.isInteger(statusCode)||statusCode<100||statusCode>599)throw Error('Invalid HTTP status');const hops=previousState?.hops??0;if(!Number.isInteger(hops)||hops<0)throw Error('Invalid redirect state');if(statusCode>=300&&statusCode<400&&typeof headers?.location==='string'&&headers.location){if(hops>=21)throw Error('Too many redirects');let target;try{target=new URL(headers.location,url)}catch{throw Error('Invalid redirect URL')}if(!['http:','https:'].includes(target.protocol)||target.username||target.password)throw Error('Invalid redirect URL');return{state:{hops:hops+1,nextUrl:target.toString()},phase:'follow'};}return{state:{hops,nextUrl:''},phase:statusCode!==200?'send':'ok'};}\n" } } }, "presentation": { "designer": { "version": 1, "flow": { "direction": "vertical" } } } }