Octopus Energy GraphQL
This flow makes it easier to run Octopus Energy GraphQL queries. It deals with obtaining an authentication token and getting a new one once it expires.
Enter your Account Number and API Key, found here, into the node properties or the subflow's environment variables.
Pass in the GraphQL query via the msg.query parameter and store any variables in msg.variables. The account number is automatically added as a variable.
Theres more details about Octopus' GraphQL API here and the schema is here.
For an example of how to use it see this flow.
Requires: node-red-contrib-graphql
If you haven't already joined Octopus Energy, seize the opportunity through my referral link https://share.octopus.energy/blue-beach-240. By using this link, both of us will receive a £50 credit. Already an Octopus Energy Customer? You can still add the referral code by contacting them, as long as you signed up directly without any referral code. Let's both enjoy a £50 credit!
[{"id":"8c10a679bfd2386e","type":"subflow","name":"Octopus Energy GraphQL","info":"","category":"","in":[{"x":80,"y":140,"wires":[{"id":"ab8b6368f466dd5a"}]}],"out":[{"x":770,"y":140,"wires":[{"id":"799223ca9ce61160","port":0}]},{"x":480,"y":580,"wires":[{"id":"4c8b3548cc35074b","port":0}]}],"env":[{"name":"ACCOUNTNUMBER","type":"str","value":"","ui":{"icon":"font-awesome/fa-address-card-o","label":{"en-US":"Account Number"},"type":"input","opts":{"types":["str"]}}},{"name":"APIKEY","type":"cred","ui":{"icon":"font-awesome/fa-key","label":{"en-US":"API Key"},"type":"input","opts":{"types":["str","cred"]}}}],"meta":{},"credentials":{"APIKEY":""},"color":"#D8BFD8","inputLabels":["GraphQL query"],"outputLabels":["GraphQL output","GraphQL error"],"status":{"x":440,"y":840,"wires":[{"id":"6c5a11d5aa1aa28e","port":0}]}},{"id":"89c2bb38024725e7","type":"graphql","z":"8c10a679bfd2386e","name":"obtainKrakenToken","graphql":"920ed6a5c25f475c","format":"text","template":"mutation krakenTokenAuthentication($apikey: String!) {\n obtainKrakenToken(input: {APIKey: $apikey}) {\n token\n }\n}","syntax":"plain","token":"","showDebug":false,"x":480,"y":400,"wires":[["9e176a124108b191"],["178a5d28b4fe2aab"]]},{"id":"45fc3f5515b6658b","type":"function","z":"8c10a679bfd2386e","name":"Set API Key","func":"if (!msg.variables) {\n msg.variables = {};\n}\n\nmsg.variables.apikey = env.get(\"APIKEY\")\n\nmsg.payload={}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":230,"y":400,"wires":[["89c2bb38024725e7"]]},{"id":"9e176a124108b191","type":"function","z":"8c10a679bfd2386e","name":"Set krakenToken flow variable","func":"flow.set(\"octopus.graphql.krakenToken\", msg.payload.graphql.obtainKrakenToken.token)\n\nif(msg.refreshToken) {\n delete msg.refreshToken\n}\n\ndelete msg.payload.graphql\n\nvar status = { fill: \"yellow\", text: \"Token obtained\" }\n\nreturn [msg, status]","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":790,"y":400,"wires":[["b22be99526d4a842"],["b5f209b32c478859"]],"outputLabels":["Query","Status"]},{"id":"799223ca9ce61160","type":"graphql","z":"8c10a679bfd2386e","name":"Run GraphQL","graphql":"920ed6a5c25f475c","format":"handlebars","template":"{{query}}","syntax":"mustache","token":"","showDebug":false,"credentials":{},"x":520,"y":140,"wires":[["beb4a5a15a77d3df"],["07b8cede1bb55008"]]},{"id":"ab8b6368f466dd5a","type":"function","z":"8c10a679bfd2386e","name":"Prepare for GraphQL","func":"var status\n\nif (!flow.get(\"octopus.graphql.krakenToken\")) {\n var newMsg = {}\n newMsg.refreshToken = true\n newMsg.oldMsg = msg\n\n status = { fill: \"purple\", text: \"Obtaining token\" }\n\n return [null, newMsg, status]\n}\n\nif(msg.oldMsg) {\n msg = msg.oldMsg\n}\n\nmsg.customHeaders = {}\nmsg.customHeaders.Authorization = flow.get(\"octopus.graphql.krakenToken\")\n\nif (!msg.variables) {\n msg.variables = {};\n}\n\nmsg.variables.accountNumber = env.get(\"ACCOUNTNUMBER\")\n\nif(!msg.payload) {\n msg.payload = {}\n}\nmsg.payload.graphql={}\n\nstatus = { fill: \"yellow\", text: \"Running query\" }\n\nreturn [msg, null, status];","outputs":3,"noerr":0,"initialize":"","finalize":"","libs":[],"x":260,"y":140,"wires":[["799223ca9ce61160"],["da8e4250054dc797"],["bad44dd40a123091"]],"inputLabels":["Query"],"outputLabels":["GraphQL","Get Token","Status"]},{"id":"be9497eea5625c3f","type":"link in","z":"8c10a679bfd2386e","name":"Obtain Token","links":["436150eaf14baa43","da8e4250054dc797"],"x":75,"y":400,"wires":[["45fc3f5515b6658b"]]},{"id":"da8e4250054dc797","type":"link out","z":"8c10a679bfd2386e","name":"Get Token","mode":"link","links":["be9497eea5625c3f"],"x":455,"y":200,"wires":[]},{"id":"b22be99526d4a842","type":"link out","z":"8c10a679bfd2386e","name":"Run query","mode":"link","links":["d9312dbf0a913258"],"x":1005,"y":400,"wires":[]},{"id":"d9312dbf0a913258","type":"link in","z":"8c10a679bfd2386e","name":"Run query","links":["b22be99526d4a842"],"x":75,"y":200,"wires":[["ab8b6368f466dd5a"]]},{"id":"4c8b3548cc35074b","type":"function","z":"8c10a679bfd2386e","name":"Handle errors","func":"var status\n\nif (msg.payload.graphql[0].extensions) {\n if (msg.payload.graphql[0].extensions.errorCode == \"KT-CT-1124\") {\n // token expired\n var newMsg = {}\n newMsg.refreshToken = true\n newMsg.oldMsg = msg\n status = { fill: \"yellow\", text: \"Obtaining new token\" }\n return [null, newMsg, status]\n }\n else {\n // other octopus error\n node.warn(msg.payload.graphql[0].extensions)\n status = { fill: \"red\", text: msg.payload.graphql[0].extensions.errorCode }\n }\n}\nelse {\n // general graphql error\n node.warn(msg.payload.graphql.error)\n status = { fill: \"red\", text: msg.payload.graphql.error.message}\n}\n\nreturn [msg, null, status];","outputs":3,"noerr":0,"initialize":"","finalize":"","libs":[],"x":240,"y":580,"wires":[[],["436150eaf14baa43"],["b53b2d031b1bac91"]],"outputLabels":["GraphQL Error","Refresh token","Status"]},{"id":"436150eaf14baa43","type":"link out","z":"8c10a679bfd2386e","name":"Token expired","mode":"link","links":["be9497eea5625c3f"],"x":425,"y":640,"wires":[]},{"id":"35bd2d5bcfdc2443","type":"link in","z":"8c10a679bfd2386e","name":"Status","links":["57e7f83e79d3234d","a2a109ed52baf28c","b53b2d031b1bac91","b5f209b32c478859","bad44dd40a123091"],"x":75,"y":840,"wires":[["6c5a11d5aa1aa28e"]]},{"id":"178a5d28b4fe2aab","type":"link out","z":"8c10a679bfd2386e","name":"GraphQL error","mode":"link","links":["fefc9c5225e27ee3"],"x":675,"y":460,"wires":[]},{"id":"fefc9c5225e27ee3","type":"link in","z":"8c10a679bfd2386e","name":"Handle errors","links":["07b8cede1bb55008","178a5d28b4fe2aab"],"x":75,"y":580,"wires":[["4c8b3548cc35074b"]]},{"id":"07b8cede1bb55008","type":"link out","z":"8c10a679bfd2386e","name":"GraphQL error","mode":"link","links":["fefc9c5225e27ee3"],"x":695,"y":260,"wires":[]},{"id":"9076d5177c29523e","type":"comment","z":"8c10a679bfd2386e","name":"Run GraphQL query","info":"","x":160,"y":80,"wires":[]},{"id":"f9d2645c6b0a51be","type":"comment","z":"8c10a679bfd2386e","name":"Obtain Kraken Token","info":"","x":160,"y":340,"wires":[]},{"id":"7a7f7676f803a447","type":"comment","z":"8c10a679bfd2386e","name":"Error handling","info":"","x":140,"y":520,"wires":[]},{"id":"b53b2d031b1bac91","type":"link out","z":"8c10a679bfd2386e","name":"Set Status 4","mode":"link","links":["35bd2d5bcfdc2443"],"x":425,"y":700,"wires":[]},{"id":"b5f209b32c478859","type":"link out","z":"8c10a679bfd2386e","name":"Set Status 3","mode":"link","links":["35bd2d5bcfdc2443"],"x":1005,"y":460,"wires":[]},{"id":"bad44dd40a123091","type":"link out","z":"8c10a679bfd2386e","name":"Set Status 1","mode":"link","links":["35bd2d5bcfdc2443"],"x":455,"y":260,"wires":[]},{"id":"beb4a5a15a77d3df","type":"function","z":"8c10a679bfd2386e","name":"Success status","func":"var status = { fill: \"green\", text: \"Success\" }\n\nreturn status;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":760,"y":200,"wires":[["a2a109ed52baf28c"]]},{"id":"a2a109ed52baf28c","type":"link out","z":"8c10a679bfd2386e","name":"Set Status 2","mode":"link","links":["35bd2d5bcfdc2443"],"x":905,"y":200,"wires":[]},{"id":"60e116b69cbdd166","type":"inject","z":"8c10a679bfd2386e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":130,"y":900,"wires":[["f28df1509b4cbacc"]]},{"id":"f28df1509b4cbacc","type":"function","z":"8c10a679bfd2386e","name":"Initial status","func":"\nreturn ({fill: \"blue\", text: \"Ready\"});","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":310,"y":900,"wires":[["57e7f83e79d3234d"]]},{"id":"57e7f83e79d3234d","type":"link out","z":"8c10a679bfd2386e","name":"Set Status 5","mode":"link","links":["35bd2d5bcfdc2443"],"x":445,"y":900,"wires":[]},{"id":"6c5a11d5aa1aa28e","type":"function","z":"8c10a679bfd2386e","name":"Send status","func":"return {payload: msg};","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":310,"y":840,"wires":[[]]},{"id":"5046bcad1a0540e3","type":"comment","z":"8c10a679bfd2386e","name":"Status","info":"","x":110,"y":780,"wires":[]},{"id":"920ed6a5c25f475c","type":"graphql-server","name":"Octopus API","endpoint":"https://api.octopus.energy/v1/graphql/","token":""},{"id":"0ef9d2a796587240","type":"subflow:8c10a679bfd2386e","z":"b6cc83b14d19c472","name":"","x":140,"y":140,"wires":[["1fceaf2a7c77d904"],["e380f452f723b672"]]}]