[{"data":1,"prerenderedAt":394},["ShallowReactive",2],{"blog-\u002Fblog\u002F2023\u002F05\u002Fchatgpt-nodered-fcn-node":3,"blog-all-for-related":393},{"id":4,"title":5,"authors":6,"body":9,"cta":359,"date":360,"description":361,"extension":362,"image":363,"lastUpdated":364,"meta":365,"navigation":377,"path":378,"seo":379,"sitemap":380,"stem":383,"subtitle":384,"tags":385,"tldr":359,"video":359,"__hash__":392},"blog\u002Fblog\u002F2023\u002F05\u002Fchatgpt-nodered-fcn-node.md","Chat GPT in Node-RED Function Nodes",[7,8],"joe-pavitt","stephen-mclaughlin",{"type":10,"value":11,"toc":354},"minimark",[12,35,40,60,75,78,81,183,189,192,246,249,255,263,267,274,312,316,324,327,347,350],[13,14,15,16,23,24,29,30,34],"p",{},"Recently we ",[17,18,22],"a",{"href":19,"rel":20},"https:\u002F\u002Fwww.linkedin.com\u002Fposts\u002Fflowforge_chatgpt-with-node-red-function-nodes-activity-7052725869684953088-2yOA?utm_source=share&utm_medium=member_desktop",[21],"nofollow","posted a demo of ChatGPT integration in a Node-RED function node","\nonto our social media accounts. We have now ",[17,25,28],{"href":26,"target":27},"https:\u002F\u002Fgithub.com\u002FFlowFuse\u002Fnode-red-function-gpt","_blank","open-sourced"," this for all to play with, and ",[31,32,33],"strong",{},"welcome any and all contributions",".",[36,37,39],"h2",{"id":38},"how-it-works-prompt-engineering","How it Works - Prompt Engineering",[13,41,42,43,48,49,54,55,59],{},"OpenAI make a collection of their ",[17,44,47],{"href":45,"rel":46},"https:\u002F\u002Fplatform.openai.com\u002Fdocs\u002Fmodels",[21],"Generative AI models"," available\nvia an API. We are wrapping OpenAI's ",[17,50,53],{"href":51,"rel":52},"https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Fopenai",[21],"node.js module",", and in particular\nusing the ",[56,57,58],"code",{},"openai.createChatCompletion()"," functionality. For this API, you provide a chat history, and ChatGPT will\nrespond with the next entry in that conversation.",[13,61,62,63,67,68,71,72,34],{},"In order to \"train\" ChatGPT for our use case of populating Node-RED function nodes, we first tried a collection of prompts, defining specific\nrequirements for the contents, e.g. ",[64,65,66],"em",{},"\"Always write Javascript\"",", ",[64,69,70],{},"\"Never include the wrapping function definition\"",",\n",[64,73,74],{},"\"Assume the input is always msg\"",[13,76,77],{},"It turns out though, that we were over-engineering it, we were not getting reliable results and ended up\nrealising that ChatGPT's existing knowledge of Node-RED was sufficient such that we could use that as a prompt:",[13,79,80],{},"Here's what we settled on:",[82,83,88],"pre",{"className":84,"code":85,"language":86,"meta":87,"style":87},"language-javascript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","messages: [\n    {role: \"system\", content: \"always respond with content for a Node-RED function node, and don't add any commentary, always use const or let instead of var. Always return msg, unless told otherwise.\"},\n    {role: \"user\", content: prompt}\n],\n","javascript","",[56,89,90,107,147,175],{"__ignoreMap":87},[91,92,95,99,103],"span",{"class":93,"line":94},"line",1,[91,96,98],{"class":97},"sBMFI","messages",[91,100,102],{"class":101},"sMK4o",":",[91,104,106],{"class":105},"sTEyZ"," [\n",[91,108,110,113,117,119,122,126,129,132,135,137,139,142,144],{"class":93,"line":109},2,[91,111,112],{"class":101},"    {",[91,114,116],{"class":115},"swJcz","role",[91,118,102],{"class":101},[91,120,121],{"class":101}," \"",[91,123,125],{"class":124},"sfazB","system",[91,127,128],{"class":101},"\"",[91,130,131],{"class":101},",",[91,133,134],{"class":115}," content",[91,136,102],{"class":101},[91,138,121],{"class":101},[91,140,141],{"class":124},"always respond with content for a Node-RED function node, and don't add any commentary, always use const or let instead of var. Always return msg, unless told otherwise.",[91,143,128],{"class":101},[91,145,146],{"class":101},"},\n",[91,148,150,152,154,156,158,161,163,165,167,169,172],{"class":93,"line":149},3,[91,151,112],{"class":101},[91,153,116],{"class":115},[91,155,102],{"class":101},[91,157,121],{"class":101},[91,159,160],{"class":124},"user",[91,162,128],{"class":101},[91,164,131],{"class":101},[91,166,134],{"class":115},[91,168,102],{"class":101},[91,170,171],{"class":105}," prompt",[91,173,174],{"class":101},"}\n",[91,176,178,181],{"class":93,"line":177},4,[91,179,180],{"class":105},"]",[91,182,71],{"class":101},[13,184,185,186,188],{},"Here we send a ",[56,187,125],{}," prompt in order to setup ChatGPT, and then follow that immediately with whatever the user has typed.\nFrom our (limited) testing, this has given us fairly reliable results.",[13,190,191],{},"Breaking this prompt down:",[193,194,195,216,224,232],"ul",{},[196,197,198,203,204,207,208,211,212,215],"li",{},[64,199,200],{},[31,201,202],{},"\"Always respond with content for a Node-RED function node\"",": Ensured no surrounding ",[56,205,206],{},"function () {}"," definition and set expectations that the function would deal with a ",[56,209,210],{},"msg"," and likely ",[56,213,214],{},"msg.payload"," object.",[196,217,218,223],{},[64,219,220],{},[31,221,222],{},"\"Don't add any commentary\"",": ChatGPT likes to, well, chat. It would always return raw text justifying decisions, etc. Here, we just wanted the code.",[196,225,226,231],{},[64,227,228],{},[31,229,230],{},"\"Always use const or let instead of var\"",": This was Steve being picky.",[196,233,234,239,240,242,243,245],{},[64,235,236],{},[31,237,238],{},"\"Always return msg, unless told otherwise\"",": We found this wasn't mostly required, but occasionally it would try to return a different variable, and we'd lose context of ",[56,241,214],{},", or other data stored in ",[56,244,210],{},". So this just made sure we had the consistency.",[13,247,248],{},"The response from this API call is then populated into the contents of the active tab in the function node:",[250,251],"img",{"width":252,"alt":253,"src":254},1728,"Screenshot 2023-04-21 at 16 08 47","https:\u002F\u002Fuser-images.githubusercontent.com\u002F99246719\u002F233671631-fefa36c1-6db4-4392-a057-314c16fd91b7.png",[13,256,257,258,34],{},"In order to use it yourself, you will need a ",[17,259,262],{"href":260,"rel":261},"https:\u002F\u002Fplatform.openai.com\u002Faccount\u002Fapi-keys",[21],"valid API Key from OpenAI",[36,264,266],{"id":265},"additional-features","Additional Features",[13,268,269,270,273],{},"This was built in about a day by Steve and Joe, and we had plenty of ideas on what we'd like to add to it. We've\n",[17,271,28],{"href":26,"rel":272},[21]," it, and will add these as issues to the repo, but if anyone want so take a stab at contributing - that'd be most welcome!",[193,275,276,292,302],{},[196,277,278,287,288,291],{},[31,279,280,281,286],{},"Insert at Cursor (",[17,282,285],{"href":283,"rel":284},"https:\u002F\u002Fgithub.com\u002FFlowFuse\u002Fnode-red-function-gpt\u002Fissues\u002F11",[21],"issue","):"," Currently, the Ask GPT call will replace ",[64,289,290],{},"all"," of the content of that tab. Would be great\nto have the code insert wherever the cursor last was in order to add to existing code.",[196,293,294,301],{},[31,295,296,297,286],{},"Retain Conversation History (",[17,298,285],{"href":299,"rel":300},"https:\u002F\u002Fgithub.com\u002FFlowFuse\u002Fnode-red-function-gpt\u002Fissues\u002F12",[21]," Each time a new prompt is provided by the Node-RED user, we send a fresh conversation to OpenAI,\nmeaning that knowledge of previously asked questions are not retained.",[196,303,304,311],{},[31,305,306,307,286],{},"Client side ChatGPT Config (",[17,308,285],{"href":309,"rel":310},"https:\u002F\u002Fgithub.com\u002FFlowFuse\u002Fnode-red-function-gpt\u002Fissues\u002F13",[21]," Currently, when you add a new \"function-gpt\" node you need to select the ChatGTP\nConfig node and click \"Deploy\" before you can ask it a question. Our ChatGPT interaction operates server-side (to\nprotect your API key), so Node-RED needs that in the runtime first, before a call to ChatGPT can be made. Ideally,\nwe'd be smarter here and pass client-side creds along with the call such that we can use any changes made by the\nuser at the time of the call.",[36,313,315],{"id":314},"flowfuse-assistant-no-api-keys-required","FlowFuse Assistant - No API Keys Required!",[13,317,318,319,323],{},"Great news! You no longer need to manage OpenAI API keys or configure ChatGPT nodes. The ",[17,320,322],{"href":321},"\u002Fdocs\u002Fuser\u002Fexpert\u002F","FlowFuse Assistant"," is now built directly into Node-RED on FlowFuse Cloud, making AI-powered development even easier.",[13,325,326],{},"Available on FlowFuse Cloud, the Assistant offers:",[193,328,329,335,341],{},[196,330,331,334],{},[31,332,333],{},"Quick Function Node Creation",": Add function nodes to your flow without dragging from the palette",[196,336,337,340],{},[31,338,339],{},"In-line Code Generation",": Generate JavaScript code for function nodes, JSON for JSON editors, and Vue.js for FlowFuse Dashboard ui-template widgets",[196,342,343,346],{},[31,344,345],{},"Flow Explainer",": Select nodes and click \"Explain Flows\" to understand what they do",[13,348,349],{},"FlowFuse Assistant helps developers work faster and smarter with Node-RED. [Start your free trial]({% include \"sign-up-url.njk\" %}) to experience AI-powered Node-RED development on FlowFuse Cloud.",[351,352,353],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":87,"searchDepth":177,"depth":177,"links":355},[356,357,358],{"id":38,"depth":109,"text":39},{"id":265,"depth":109,"text":266},{"id":314,"depth":109,"text":315},null,"2023-05-02","Discover how ChatGPT integrates with Node-RED function nodes, enabling automated code generation. Explore the prompt engineering process and additional features.","md","\u002Fimages\u002Fblog\u002Ftile-chatgpt-fcn-node.jpg","2025-07-23",{"excerpt":366},{"type":10,"value":367},[368],[13,369,15,370,23,373,29,375,34],{},[17,371,22],{"href":19,"rel":372},[21],[17,374,28],{"href":26,"target":27},[31,376,33],{},true,"\u002Fblog\u002F2023\u002F05\u002Fchatgpt-nodered-fcn-node",{"title":5,"description":361},{"loc":378,"images":381},[382],{"loc":254},"blog\u002F2023\u002F05\u002Fchatgpt-nodered-fcn-node","New Node-RED function with embedded ChatGPT is now open-sourced and available to use!",[386,387,388,389,390,391],"posts","node-red","community","how-to","chatgpt","ai","Yu5S1tx3B1sfZdRnsMPUdMZVRQ1TuP3iVWY1HoBI-bU",[],1785528685335]