[{"data":1,"prerenderedAt":1462},["ShallowReactive",2],{"blog-\u002Fblog\u002F2024\u002F01\u002Fspeech-driven-chatbot-with-node-red":3},{"id":4,"title":5,"body":6,"description":12,"extension":1450,"meta":1451,"navigation":1253,"path":1458,"seo":1459,"stem":1460,"__hash__":1461},"blog\u002Fblog\u002F2024\u002F01\u002Fspeech-driven-chatbot-with-node-red.md","Speech-Driven Chatbot System with Node-RED",{"type":7,"value":8,"toc":1439},"minimark",[9,13,16,21,24,47,51,60,64,74,83,86,89,263,266,878,882,889,901,908,912,915,926,933,937,940,955,959,962,973,976,1027,1030,1395,1398,1405,1409,1416,1422,1429,1433,1436],[10,11,12],"p",{},"Have you ever wanted to integrate speech recognition and synthesis into your Node-RED project and thought it was too complex? Often it has required external services or APIs. However, in this guide, we show you how you can use speech recognition and synthesis in your Node-RED projects without needing an external service or API.",[10,14,15],{},"In addition, we make things more interesting by building a system that can listen to us and respond like humans using the Chat-GPT API.\nLet's get started!",[17,18,20],"h2",{"id":19},"what-exactly-is-speech-recognition-and-synthesis","What exactly is speech recognition and synthesis?",[10,22,23],{},"Speech recognition is a technology where a device captures spoken words through a microphone, checks against grammar rules and vocabulary, and returns recognized words as text. On the other hand, speech synthesis converts app text into speech and plays it through a device's speaker or audio output. There are many benefits and real-world applications of this technology.",[25,26,27,35,41],"ul",{},[28,29,30,34],"li",{},[31,32,33],"strong",{},"Hands-Free Operation:"," Using speech recognition technology is often used today to perform tasks such as making calls, sending messages, or controlling smart home devices without the need for physical interaction.",[28,36,37,40],{},[31,38,39],{},"Accessibility:"," It allows individuals with visual impairments to access digital content through spoken words and as discussed above, to control devices without physical interaction.",[28,42,43,46],{},[31,44,45],{},"Efficient Content Consumption:"," It allows us to listen to information instead of reading. For example, in the audiobook industry by using speech synthesis technology they create audio versions of books which helps users to be more productive.",[17,48,50],{"id":49},"installing-dashboard-20","Installing Dashboard 2.0",[10,52,53,54,59],{},"Install Dashboard 2.0. Follow these ",[55,56,58],"a",{"href":57},"\u002Fblog\u002F2024\u002F03\u002Fdashboard-getting-started\u002F","instructions"," to get up and running.",[17,61,63],{"id":62},"building-speech-to-text-vue-component","Building Speech-to-Text Vue component",[10,65,66,67,73],{},"In this section, we will build a Vue component that will perform a speech-to-text conversion operation using Web speech API, and display results on the dashboard.  While we did say previously that we won't need any external API for speech recognition, this ",[55,68,72],{"href":69,"rel":70},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FAPI\u002FWeb_Speech_API",[71],"nofollow","Web Speech API"," is not an external API.\nThis will process your speech locally as it is a JavaScript API that allows us to use speech-related functionalities, such as speech recognition and synthesis, in a web browser directly. It is widely present in modern browsers (except Firefox) which eliminates the need for external APIs to implement these features. Let's now start to build that component.",[75,76,77,80],"ol",{},[28,78,79],{},"Drag a ui template widget to canvas and select the created group.",[28,81,82],{},"Paste the below Vue snippets into the template widget step by step.",[10,84,85],{},"If you are unfamiliar with Vue, we have added comments that will help you to understand the code better.",[10,87,88],{},"We are going to start by pasting a user interface’s snippet which will allow us to interact with our system. This snippet adds a button that triggers our system to listen, an Icon, and a paragraph to display speech recognition results on the dashboard.",[90,91,96],"pre",{"className":92,"code":93,"language":94,"meta":95,"style":95},"language-html shiki shiki-themes github-light github-dark","\u003Ctemplate>\n  \u003Cdiv style=\"display: flex; flex-direction: column; justify-content: center; align-items: center;\">\n    \u003C!-- Button triggers recording when clicked -->\n    \u003Cbutton @click=\"startRecording\">\n      \u003C!-- Microphone icon inside the button -->\n      \u003Cimg alt=\"Microphone\" style=\"height: 62px; width: 62px\" :src=\"microphoneIcon\">\n    \u003C\u002Fbutton>\n    \u003C!-- Displaying speech recognition results -->\n    \u003Cp> \u003Cstrong>You:\u003C\u002Fstrong> {{ results }}\u003C\u002Fp>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n","html","",[97,98,99,115,137,144,163,169,203,213,219,243,253],"code",{"__ignoreMap":95},[100,101,104,108,112],"span",{"class":102,"line":103},"line",1,[100,105,107],{"class":106},"sVt8B","\u003C",[100,109,111],{"class":110},"s9eBZ","template",[100,113,114],{"class":106},">\n",[100,116,118,121,124,128,131,135],{"class":102,"line":117},2,[100,119,120],{"class":106},"  \u003C",[100,122,123],{"class":110},"div",[100,125,127],{"class":126},"sScJk"," style",[100,129,130],{"class":106},"=",[100,132,134],{"class":133},"sZZnC","\"display: flex; flex-direction: column; justify-content: center; align-items: center;\"",[100,136,114],{"class":106},[100,138,140],{"class":102,"line":139},3,[100,141,143],{"class":142},"sJ8bj","    \u003C!-- Button triggers recording when clicked -->\n",[100,145,147,150,153,156,158,161],{"class":102,"line":146},4,[100,148,149],{"class":106},"    \u003C",[100,151,152],{"class":110},"button",[100,154,155],{"class":126}," @click",[100,157,130],{"class":106},[100,159,160],{"class":133},"\"startRecording\"",[100,162,114],{"class":106},[100,164,166],{"class":102,"line":165},5,[100,167,168],{"class":142},"      \u003C!-- Microphone icon inside the button -->\n",[100,170,172,175,178,181,183,186,188,190,193,196,198,201],{"class":102,"line":171},6,[100,173,174],{"class":106},"      \u003C",[100,176,177],{"class":110},"img",[100,179,180],{"class":126}," alt",[100,182,130],{"class":106},[100,184,185],{"class":133},"\"Microphone\"",[100,187,127],{"class":126},[100,189,130],{"class":106},[100,191,192],{"class":133},"\"height: 62px; width: 62px\"",[100,194,195],{"class":126}," :src",[100,197,130],{"class":106},[100,199,200],{"class":133},"\"microphoneIcon\"",[100,202,114],{"class":106},[100,204,206,209,211],{"class":102,"line":205},7,[100,207,208],{"class":106},"    \u003C\u002F",[100,210,152],{"class":110},[100,212,114],{"class":106},[100,214,216],{"class":102,"line":215},8,[100,217,218],{"class":142},"    \u003C!-- Displaying speech recognition results -->\n",[100,220,222,224,226,229,231,234,236,239,241],{"class":102,"line":221},9,[100,223,149],{"class":106},[100,225,10],{"class":110},[100,227,228],{"class":106},"> \u003C",[100,230,31],{"class":110},[100,232,233],{"class":106},">You:\u003C\u002F",[100,235,31],{"class":110},[100,237,238],{"class":106},"> {{ results }}\u003C\u002F",[100,240,10],{"class":110},[100,242,114],{"class":106},[100,244,246,249,251],{"class":102,"line":245},10,[100,247,248],{"class":106},"  \u003C\u002F",[100,250,123],{"class":110},[100,252,114],{"class":106},[100,254,256,259,261],{"class":102,"line":255},11,[100,257,258],{"class":106},"\u003C\u002F",[100,260,111],{"class":110},[100,262,114],{"class":106},[10,264,265],{},"Now paste the below script right after the HTML in the template widget, This script adds functionality of speech recognition in our system.",[90,267,269],{"className":92,"code":268,"language":94,"meta":95,"style":95},"\u003Cscript>\nexport default {\n data() {\n   return {\n     \u002F\u002F Initial data properties\n     buttonText: 'Speak',\n     microphoneIcon: 'http:\u002F\u002Ficons.iconarchive.com\u002Ficons\u002Fblackvariant\u002Fbutton-ui-requests-15\u002F512\u002FMicrophone-icon.png',\n     recognition: null,\n     results: '',\n   };\n },\n methods: {\n   \u002F\u002F Method to start recording\n   startRecording() {\n     this.buttonText = 'Recording';\n     this.recognition.stop();\n     this.recognition.start();\n   },\n   \u002F\u002F Method to process the speech recognition results\n   processSpeech(event) {\n     let results = Array.from(event.results).map(result =>   result[0].transcript).join('');\n     this.results = results;\n     this.$emit('speak', results);\n     \u002F\u002FSending result to next node as payload\n     this.send(results);\n   },\n   \u002F\u002F Method to handle the start of recognition\n   handleRecognitionStart() {\n     this.microphoneIcon = 'https:\u002F\u002Fupload.wikimedia.org\u002Fwikipedia\u002Fcommons\u002F0\u002F06\u002FMic-Animation.gif';\n   },\n   \u002F\u002F Method to handle recognition errors\n   handleRecognitionError(event) {\n     this.microphoneIcon = event.error === 'no-speech' || event.error === 'audio-capture'\n       ? 'https:\u002F\u002Fi.ytimg.com\u002Fvi\u002F9YQU797Oy0Y\u002Fhqdefault.jpg'\n       : this.microphoneIcon;\n   },\n   \u002F\u002F Method to handle the end of recognition\n   handleRecognitionEnd() {\n     this.microphoneIcon = 'http:\u002F\u002Ficons.iconarchive.com\u002Ficons\u002Fblackvariant\u002Fbutton-ui-requests-15\u002F512\u002FMicrophone-icon.png';\n   },\n   \u002F\u002F Method to set up the SpeechRecognition object\n   setupRecognition() {\n     this.recognition = new webkitSpeechRecognition();\n     this.recognition.continuous = false;\n     this.recognition.interimResults = false;\n     this.recognition.onresult = this.processSpeech;\n     this.recognition.onstart = this.handleRecognitionStart;\n     this.recognition.onerror = this.handleRecognitionError;\n     this.recognition.onend = this.handleRecognitionEnd;\n   },\n },\n mounted() {\n   \u002F\u002F Initialize SpeechRecognition when the component is mounted\n   this.setupRecognition();\n },\n};\n\u003C\u002Fscript>\n",[97,270,271,280,292,300,307,312,323,333,344,354,359,364,370,376,384,401,415,427,433,439,455,505,518,537,543,556,561,567,575,590,595,601,613,641,650,662,667,673,681,695,700,706,714,732,747,761,776,791,806,821,826,831,839,845,858,863,869],{"__ignoreMap":95},[100,272,273,275,278],{"class":102,"line":103},[100,274,107],{"class":106},[100,276,277],{"class":110},"script",[100,279,114],{"class":106},[100,281,282,286,289],{"class":102,"line":117},[100,283,285],{"class":284},"szBVR","export",[100,287,288],{"class":284}," default",[100,290,291],{"class":106}," {\n",[100,293,294,297],{"class":102,"line":139},[100,295,296],{"class":126}," data",[100,298,299],{"class":106},"() {\n",[100,301,302,305],{"class":102,"line":146},[100,303,304],{"class":284},"   return",[100,306,291],{"class":106},[100,308,309],{"class":102,"line":165},[100,310,311],{"class":142},"     \u002F\u002F Initial data properties\n",[100,313,314,317,320],{"class":102,"line":171},[100,315,316],{"class":106},"     buttonText: ",[100,318,319],{"class":133},"'Speak'",[100,321,322],{"class":106},",\n",[100,324,325,328,331],{"class":102,"line":205},[100,326,327],{"class":106},"     microphoneIcon: ",[100,329,330],{"class":133},"'http:\u002F\u002Ficons.iconarchive.com\u002Ficons\u002Fblackvariant\u002Fbutton-ui-requests-15\u002F512\u002FMicrophone-icon.png'",[100,332,322],{"class":106},[100,334,335,338,342],{"class":102,"line":215},[100,336,337],{"class":106},"     recognition: ",[100,339,341],{"class":340},"sj4cs","null",[100,343,322],{"class":106},[100,345,346,349,352],{"class":102,"line":221},[100,347,348],{"class":106},"     results: ",[100,350,351],{"class":133},"''",[100,353,322],{"class":106},[100,355,356],{"class":102,"line":245},[100,357,358],{"class":106},"   };\n",[100,360,361],{"class":102,"line":255},[100,362,363],{"class":106}," },\n",[100,365,367],{"class":102,"line":366},12,[100,368,369],{"class":106}," methods: {\n",[100,371,373],{"class":102,"line":372},13,[100,374,375],{"class":142},"   \u002F\u002F Method to start recording\n",[100,377,379,382],{"class":102,"line":378},14,[100,380,381],{"class":126},"   startRecording",[100,383,299],{"class":106},[100,385,387,390,393,395,398],{"class":102,"line":386},15,[100,388,389],{"class":340},"     this",[100,391,392],{"class":106},".buttonText ",[100,394,130],{"class":284},[100,396,397],{"class":133}," 'Recording'",[100,399,400],{"class":106},";\n",[100,402,404,406,409,412],{"class":102,"line":403},16,[100,405,389],{"class":340},[100,407,408],{"class":106},".recognition.",[100,410,411],{"class":126},"stop",[100,413,414],{"class":106},"();\n",[100,416,418,420,422,425],{"class":102,"line":417},17,[100,419,389],{"class":340},[100,421,408],{"class":106},[100,423,424],{"class":126},"start",[100,426,414],{"class":106},[100,428,430],{"class":102,"line":429},18,[100,431,432],{"class":106},"   },\n",[100,434,436],{"class":102,"line":435},19,[100,437,438],{"class":142},"   \u002F\u002F Method to process the speech recognition results\n",[100,440,442,445,448,452],{"class":102,"line":441},20,[100,443,444],{"class":126},"   processSpeech",[100,446,447],{"class":106},"(",[100,449,451],{"class":450},"s4XuR","event",[100,453,454],{"class":106},") {\n",[100,456,458,461,464,466,469,472,475,478,480,483,486,489,492,495,498,500,502],{"class":102,"line":457},21,[100,459,460],{"class":284},"     let",[100,462,463],{"class":106}," results ",[100,465,130],{"class":284},[100,467,468],{"class":106}," Array.",[100,470,471],{"class":126},"from",[100,473,474],{"class":106},"(event.results).",[100,476,477],{"class":126},"map",[100,479,447],{"class":106},[100,481,482],{"class":450},"result",[100,484,485],{"class":284}," =>",[100,487,488],{"class":106},"   result[",[100,490,491],{"class":340},"0",[100,493,494],{"class":106},"].transcript).",[100,496,497],{"class":126},"join",[100,499,447],{"class":106},[100,501,351],{"class":133},[100,503,504],{"class":106},");\n",[100,506,508,510,513,515],{"class":102,"line":507},22,[100,509,389],{"class":340},[100,511,512],{"class":106},".results ",[100,514,130],{"class":284},[100,516,517],{"class":106}," results;\n",[100,519,521,523,526,529,531,534],{"class":102,"line":520},23,[100,522,389],{"class":340},[100,524,525],{"class":106},".",[100,527,528],{"class":126},"$emit",[100,530,447],{"class":106},[100,532,533],{"class":133},"'speak'",[100,535,536],{"class":106},", results);\n",[100,538,540],{"class":102,"line":539},24,[100,541,542],{"class":142},"     \u002F\u002FSending result to next node as payload\n",[100,544,546,548,550,553],{"class":102,"line":545},25,[100,547,389],{"class":340},[100,549,525],{"class":106},[100,551,552],{"class":126},"send",[100,554,555],{"class":106},"(results);\n",[100,557,559],{"class":102,"line":558},26,[100,560,432],{"class":106},[100,562,564],{"class":102,"line":563},27,[100,565,566],{"class":142},"   \u002F\u002F Method to handle the start of recognition\n",[100,568,570,573],{"class":102,"line":569},28,[100,571,572],{"class":126},"   handleRecognitionStart",[100,574,299],{"class":106},[100,576,578,580,583,585,588],{"class":102,"line":577},29,[100,579,389],{"class":340},[100,581,582],{"class":106},".microphoneIcon ",[100,584,130],{"class":284},[100,586,587],{"class":133}," 'https:\u002F\u002Fupload.wikimedia.org\u002Fwikipedia\u002Fcommons\u002F0\u002F06\u002FMic-Animation.gif'",[100,589,400],{"class":106},[100,591,593],{"class":102,"line":592},30,[100,594,432],{"class":106},[100,596,598],{"class":102,"line":597},31,[100,599,600],{"class":142},"   \u002F\u002F Method to handle recognition errors\n",[100,602,604,607,609,611],{"class":102,"line":603},32,[100,605,606],{"class":126},"   handleRecognitionError",[100,608,447],{"class":106},[100,610,451],{"class":450},[100,612,454],{"class":106},[100,614,616,618,620,622,625,628,631,634,636,638],{"class":102,"line":615},33,[100,617,389],{"class":340},[100,619,582],{"class":106},[100,621,130],{"class":284},[100,623,624],{"class":106}," event.error ",[100,626,627],{"class":284},"===",[100,629,630],{"class":133}," 'no-speech'",[100,632,633],{"class":284}," ||",[100,635,624],{"class":106},[100,637,627],{"class":284},[100,639,640],{"class":133}," 'audio-capture'\n",[100,642,644,647],{"class":102,"line":643},34,[100,645,646],{"class":284},"       ?",[100,648,649],{"class":133}," 'https:\u002F\u002Fi.ytimg.com\u002Fvi\u002F9YQU797Oy0Y\u002Fhqdefault.jpg'\n",[100,651,653,656,659],{"class":102,"line":652},35,[100,654,655],{"class":284},"       :",[100,657,658],{"class":340}," this",[100,660,661],{"class":106},".microphoneIcon;\n",[100,663,665],{"class":102,"line":664},36,[100,666,432],{"class":106},[100,668,670],{"class":102,"line":669},37,[100,671,672],{"class":142},"   \u002F\u002F Method to handle the end of recognition\n",[100,674,676,679],{"class":102,"line":675},38,[100,677,678],{"class":126},"   handleRecognitionEnd",[100,680,299],{"class":106},[100,682,684,686,688,690,693],{"class":102,"line":683},39,[100,685,389],{"class":340},[100,687,582],{"class":106},[100,689,130],{"class":284},[100,691,692],{"class":133}," 'http:\u002F\u002Ficons.iconarchive.com\u002Ficons\u002Fblackvariant\u002Fbutton-ui-requests-15\u002F512\u002FMicrophone-icon.png'",[100,694,400],{"class":106},[100,696,698],{"class":102,"line":697},40,[100,699,432],{"class":106},[100,701,703],{"class":102,"line":702},41,[100,704,705],{"class":142},"   \u002F\u002F Method to set up the SpeechRecognition object\n",[100,707,709,712],{"class":102,"line":708},42,[100,710,711],{"class":126},"   setupRecognition",[100,713,299],{"class":106},[100,715,717,719,722,724,727,730],{"class":102,"line":716},43,[100,718,389],{"class":340},[100,720,721],{"class":106},".recognition ",[100,723,130],{"class":284},[100,725,726],{"class":284}," new",[100,728,729],{"class":126}," webkitSpeechRecognition",[100,731,414],{"class":106},[100,733,735,737,740,742,745],{"class":102,"line":734},44,[100,736,389],{"class":340},[100,738,739],{"class":106},".recognition.continuous ",[100,741,130],{"class":284},[100,743,744],{"class":340}," false",[100,746,400],{"class":106},[100,748,750,752,755,757,759],{"class":102,"line":749},45,[100,751,389],{"class":340},[100,753,754],{"class":106},".recognition.interimResults ",[100,756,130],{"class":284},[100,758,744],{"class":340},[100,760,400],{"class":106},[100,762,764,766,769,771,773],{"class":102,"line":763},46,[100,765,389],{"class":340},[100,767,768],{"class":106},".recognition.onresult ",[100,770,130],{"class":284},[100,772,658],{"class":340},[100,774,775],{"class":106},".processSpeech;\n",[100,777,779,781,784,786,788],{"class":102,"line":778},47,[100,780,389],{"class":340},[100,782,783],{"class":106},".recognition.onstart ",[100,785,130],{"class":284},[100,787,658],{"class":340},[100,789,790],{"class":106},".handleRecognitionStart;\n",[100,792,794,796,799,801,803],{"class":102,"line":793},48,[100,795,389],{"class":340},[100,797,798],{"class":106},".recognition.onerror ",[100,800,130],{"class":284},[100,802,658],{"class":340},[100,804,805],{"class":106},".handleRecognitionError;\n",[100,807,809,811,814,816,818],{"class":102,"line":808},49,[100,810,389],{"class":340},[100,812,813],{"class":106},".recognition.onend ",[100,815,130],{"class":284},[100,817,658],{"class":340},[100,819,820],{"class":106},".handleRecognitionEnd;\n",[100,822,824],{"class":102,"line":823},50,[100,825,432],{"class":106},[100,827,829],{"class":102,"line":828},51,[100,830,363],{"class":106},[100,832,834,837],{"class":102,"line":833},52,[100,835,836],{"class":126}," mounted",[100,838,299],{"class":106},[100,840,842],{"class":102,"line":841},53,[100,843,844],{"class":142},"   \u002F\u002F Initialize SpeechRecognition when the component is mounted\n",[100,846,848,851,853,856],{"class":102,"line":847},54,[100,849,850],{"class":340},"   this",[100,852,525],{"class":106},[100,854,855],{"class":126},"setupRecognition",[100,857,414],{"class":106},[100,859,861],{"class":102,"line":860},55,[100,862,363],{"class":106},[100,864,866],{"class":102,"line":865},56,[100,867,868],{"class":106},"};\n",[100,870,872,874,876],{"class":102,"line":871},57,[100,873,258],{"class":106},[100,875,277],{"class":110},[100,877,114],{"class":106},[17,879,881],{"id":880},"adding-an-environment-variable","Adding an Environment variable",[10,883,884,885],{},"Why do we need to add an environment variable? In this guide, we will build a speech-driven chatbot that involves integrating the Chat-GPT AI model. For this we need openAi’s API key. An API key is a form of private data that needs to be protected from being exposed. That is why we need the environment variables. It provides a secure way to store and access the API key without revealing it directly in the flow.  For more details see ",[55,886,888],{"href":887},"\u002Fblog\u002F2023\u002F01\u002Fenvironment-variables-in-node-red\u002F","Using Environment Variables in Node-RED",[75,890,891,894],{},[28,892,893],{},"Navigate to the instance's setting and then go to the environment section.",[28,895,896,897,900],{},"Click on the ",[97,898,899],{},"add variable"," button and add a variable for Chat-gpt API.",[10,902,903],{},[177,904],{"alt":905,"src":906,"title":907},"\"Setting environment variable for Chat-gpt token\"","\u002Fblog\u002F2024\u002F01\u002Fimages\u002Fspeech-driven-chatbot-environment-section.png","Setting environment variable for chat-gpt token",[17,909,911],{"id":910},"setting-msg-property","Setting msg property",[10,913,914],{},"Now let’s set that added environment variables as msg's property.",[75,916,917,920,923],{},[28,918,919],{},"Add a change node to canvas.",[28,921,922],{},"Set environment variable to ms.token property.",[28,924,925],{},"Connect the change node’s input to the template widget’s output.",[10,927,928],{},[177,929],{"alt":930,"src":931,"title":932},"\"Setting msg's property for Chat-gpt token\"","\u002Fblog\u002F2024\u002F01\u002Fimages\u002Fspeech-driven-chatbot-change-node.png","Setting msg's property for Chat-gpt token",[17,934,936],{"id":935},"installing-and-configuring-custom-node","Installing and configuring custom node",[10,938,939],{},"In this section, we will install a custom node that will allow us to interact with the Chat-gpt AI model.",[75,941,942,949,952],{},[28,943,944,945,948],{},"Install ",[97,946,947],{},"@sumit_shinde_84\u002Fnode-red-contrib-node-gpt"," by pallet manager, you can use other nodes according to your preference.",[28,950,951],{},"Drag a ChatGPT node to canvas.",[28,953,954],{},"Connect the ChatGPT node’s input to the change node’s output.",[17,956,958],{"id":957},"building-text-to-speech-vue-component","Building Text-to-Speech Vue component",[10,960,961],{},"We will build a Vue component that converts text received from ChatGPT into speech.",[75,963,964,967,970],{},[28,965,966],{},"Drag another template widget to canvas and select the added group, alternatively, you can create a separate group for this component according to your preference.",[28,968,969],{},"Paste the below Vue snippets into the template widget.",[28,971,972],{},"Connect the template widget’s input to the ChatGPT node’s output.",[10,974,975],{},"Paste the below snippet in the template widget which displays chat-gpt response on the dashboard",[90,977,979],{"className":92,"code":978,"language":94,"meta":95,"style":95},"\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cstrong> Chat-gpt: \u003C\u002Fstrong> {{textToSpeech}}\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n",[97,980,981,989,997,1011,1019],{"__ignoreMap":95},[100,982,983,985,987],{"class":102,"line":103},[100,984,107],{"class":106},[100,986,111],{"class":110},[100,988,114],{"class":106},[100,990,991,993,995],{"class":102,"line":117},[100,992,120],{"class":106},[100,994,123],{"class":110},[100,996,114],{"class":106},[100,998,999,1001,1003,1006,1008],{"class":102,"line":139},[100,1000,149],{"class":106},[100,1002,31],{"class":110},[100,1004,1005],{"class":106},"> Chat-gpt: \u003C\u002F",[100,1007,31],{"class":110},[100,1009,1010],{"class":106},"> {{textToSpeech}}\n",[100,1012,1013,1015,1017],{"class":102,"line":146},[100,1014,248],{"class":106},[100,1016,123],{"class":110},[100,1018,114],{"class":106},[100,1020,1021,1023,1025],{"class":102,"line":165},[100,1022,258],{"class":106},[100,1024,111],{"class":110},[100,1026,114],{"class":106},[10,1028,1029],{},"Paste the below snippet right after the HTML, This snippet adds the functionality of text-to-speech into our system, which triggers when msg received by the previous node.",[90,1031,1033],{"className":92,"code":1032,"language":94,"meta":95,"style":95},"\u003Cscript>\n  export default {\n  data() {\n    return {\n      \u002F\u002F Data property to store the text to be spoken\n      textToSpeech: '',\n    };\n  },\n  methods: {\n    \u002F\u002F Method to trigger text-to-speech\n    speakText() {\n      \u002F\u002F Check if there is non-empty text to speech\n      if (this.textToSpeech.trim() !== '') {\n        \u002F\u002F Create a SpeechSynthesisUtterance with the text to be spoken\n        const utterance = new  SpeechSynthesisUtterance(this.textToSpeech);\n        \u002F\u002F Use the SpeechSynthesis API to speak the provided text\n        window.speechSynthesis.speak(utterance);\n      }\n    },\n  },\n  mounted() {\n    \u002F\u002F Event listener for receiving messages    \n  \n     this.$socket.on('msg-input:' + this.id, (msg) => {\n\n      \u002F\u002F Update the textToSpeech property with the received message payload\n      this.textToSpeech = msg.payload;\n     \n      \u002F\u002F Trigger text-to-speech with the received message\n      this.speakText();\n    });\n  },\n};\n\u003C\u002Fscript>\n\n\u003Cstyle scoped>\n  textarea {\n    width: 100%;\n    height: 100px;\n    margin-bottom: 10px;\n  }\n\u003C\u002Fstyle>\n",[97,1034,1035,1043,1052,1059,1066,1071,1080,1085,1090,1095,1100,1107,1112,1140,1145,1168,1173,1184,1189,1194,1198,1205,1210,1215,1249,1255,1260,1273,1278,1283,1294,1299,1303,1307,1315,1319,1331,1338,1354,1368,1382,1387],{"__ignoreMap":95},[100,1036,1037,1039,1041],{"class":102,"line":103},[100,1038,107],{"class":106},[100,1040,277],{"class":110},[100,1042,114],{"class":106},[100,1044,1045,1048,1050],{"class":102,"line":117},[100,1046,1047],{"class":284},"  export",[100,1049,288],{"class":284},[100,1051,291],{"class":106},[100,1053,1054,1057],{"class":102,"line":139},[100,1055,1056],{"class":126},"  data",[100,1058,299],{"class":106},[100,1060,1061,1064],{"class":102,"line":146},[100,1062,1063],{"class":284},"    return",[100,1065,291],{"class":106},[100,1067,1068],{"class":102,"line":165},[100,1069,1070],{"class":142},"      \u002F\u002F Data property to store the text to be spoken\n",[100,1072,1073,1076,1078],{"class":102,"line":171},[100,1074,1075],{"class":106},"      textToSpeech: ",[100,1077,351],{"class":133},[100,1079,322],{"class":106},[100,1081,1082],{"class":102,"line":205},[100,1083,1084],{"class":106},"    };\n",[100,1086,1087],{"class":102,"line":215},[100,1088,1089],{"class":106},"  },\n",[100,1091,1092],{"class":102,"line":221},[100,1093,1094],{"class":106},"  methods: {\n",[100,1096,1097],{"class":102,"line":245},[100,1098,1099],{"class":142},"    \u002F\u002F Method to trigger text-to-speech\n",[100,1101,1102,1105],{"class":102,"line":255},[100,1103,1104],{"class":126},"    speakText",[100,1106,299],{"class":106},[100,1108,1109],{"class":102,"line":366},[100,1110,1111],{"class":142},"      \u002F\u002F Check if there is non-empty text to speech\n",[100,1113,1114,1117,1120,1123,1126,1129,1132,1135,1138],{"class":102,"line":372},[100,1115,1116],{"class":284},"      if",[100,1118,1119],{"class":106}," (",[100,1121,1122],{"class":340},"this",[100,1124,1125],{"class":106},".textToSpeech.",[100,1127,1128],{"class":126},"trim",[100,1130,1131],{"class":106},"() ",[100,1133,1134],{"class":284},"!==",[100,1136,1137],{"class":133}," ''",[100,1139,454],{"class":106},[100,1141,1142],{"class":102,"line":378},[100,1143,1144],{"class":142},"        \u002F\u002F Create a SpeechSynthesisUtterance with the text to be spoken\n",[100,1146,1147,1150,1153,1156,1158,1161,1163,1165],{"class":102,"line":386},[100,1148,1149],{"class":284},"        const",[100,1151,1152],{"class":340}," utterance",[100,1154,1155],{"class":284}," =",[100,1157,726],{"class":284},[100,1159,1160],{"class":126},"  SpeechSynthesisUtterance",[100,1162,447],{"class":106},[100,1164,1122],{"class":340},[100,1166,1167],{"class":106},".textToSpeech);\n",[100,1169,1170],{"class":102,"line":403},[100,1171,1172],{"class":142},"        \u002F\u002F Use the SpeechSynthesis API to speak the provided text\n",[100,1174,1175,1178,1181],{"class":102,"line":417},[100,1176,1177],{"class":106},"        window.speechSynthesis.",[100,1179,1180],{"class":126},"speak",[100,1182,1183],{"class":106},"(utterance);\n",[100,1185,1186],{"class":102,"line":429},[100,1187,1188],{"class":106},"      }\n",[100,1190,1191],{"class":102,"line":435},[100,1192,1193],{"class":106},"    },\n",[100,1195,1196],{"class":102,"line":441},[100,1197,1089],{"class":106},[100,1199,1200,1203],{"class":102,"line":457},[100,1201,1202],{"class":126},"  mounted",[100,1204,299],{"class":106},[100,1206,1207],{"class":102,"line":507},[100,1208,1209],{"class":142},"    \u002F\u002F Event listener for receiving messages    \n",[100,1211,1212],{"class":102,"line":520},[100,1213,1214],{"class":106},"  \n",[100,1216,1217,1219,1222,1225,1227,1230,1233,1235,1238,1241,1244,1247],{"class":102,"line":539},[100,1218,389],{"class":340},[100,1220,1221],{"class":106},".$socket.",[100,1223,1224],{"class":126},"on",[100,1226,447],{"class":106},[100,1228,1229],{"class":133},"'msg-input:'",[100,1231,1232],{"class":284}," +",[100,1234,658],{"class":340},[100,1236,1237],{"class":106},".id, (",[100,1239,1240],{"class":450},"msg",[100,1242,1243],{"class":106},") ",[100,1245,1246],{"class":284},"=>",[100,1248,291],{"class":106},[100,1250,1251],{"class":102,"line":545},[100,1252,1254],{"emptyLinePlaceholder":1253},true,"\n",[100,1256,1257],{"class":102,"line":558},[100,1258,1259],{"class":142},"      \u002F\u002F Update the textToSpeech property with the received message payload\n",[100,1261,1262,1265,1268,1270],{"class":102,"line":563},[100,1263,1264],{"class":340},"      this",[100,1266,1267],{"class":106},".textToSpeech ",[100,1269,130],{"class":284},[100,1271,1272],{"class":106}," msg.payload;\n",[100,1274,1275],{"class":102,"line":569},[100,1276,1277],{"class":106},"     \n",[100,1279,1280],{"class":102,"line":577},[100,1281,1282],{"class":142},"      \u002F\u002F Trigger text-to-speech with the received message\n",[100,1284,1285,1287,1289,1292],{"class":102,"line":592},[100,1286,1264],{"class":340},[100,1288,525],{"class":106},[100,1290,1291],{"class":126},"speakText",[100,1293,414],{"class":106},[100,1295,1296],{"class":102,"line":597},[100,1297,1298],{"class":106},"    });\n",[100,1300,1301],{"class":102,"line":603},[100,1302,1089],{"class":106},[100,1304,1305],{"class":102,"line":615},[100,1306,868],{"class":106},[100,1308,1309,1311,1313],{"class":102,"line":643},[100,1310,258],{"class":106},[100,1312,277],{"class":110},[100,1314,114],{"class":106},[100,1316,1317],{"class":102,"line":652},[100,1318,1254],{"emptyLinePlaceholder":1253},[100,1320,1321,1323,1326,1329],{"class":102,"line":664},[100,1322,107],{"class":106},[100,1324,1325],{"class":110},"style",[100,1327,1328],{"class":126}," scoped",[100,1330,114],{"class":106},[100,1332,1333,1336],{"class":102,"line":669},[100,1334,1335],{"class":110},"  textarea",[100,1337,291],{"class":106},[100,1339,1340,1343,1346,1349,1352],{"class":102,"line":675},[100,1341,1342],{"class":340},"    width",[100,1344,1345],{"class":106},": ",[100,1347,1348],{"class":340},"100",[100,1350,1351],{"class":284},"%",[100,1353,400],{"class":106},[100,1355,1356,1359,1361,1363,1366],{"class":102,"line":683},[100,1357,1358],{"class":340},"    height",[100,1360,1345],{"class":106},[100,1362,1348],{"class":340},[100,1364,1365],{"class":284},"px",[100,1367,400],{"class":106},[100,1369,1370,1373,1375,1378,1380],{"class":102,"line":697},[100,1371,1372],{"class":340},"    margin-bottom",[100,1374,1345],{"class":106},[100,1376,1377],{"class":340},"10",[100,1379,1365],{"class":284},[100,1381,400],{"class":106},[100,1383,1384],{"class":102,"line":702},[100,1385,1386],{"class":106},"  }\n",[100,1388,1389,1391,1393],{"class":102,"line":708},[100,1390,258],{"class":106},[100,1392,1325],{"class":110},[100,1394,114],{"class":106},[10,1396,1397],{},"Your final flow should look like this:",[10,1399,1400],{},[177,1401],{"alt":1402,"src":1403,"title":1404},"\"Speech Driven Chatbot system flow\"","\u002Fblog\u002F2024\u002F01\u002Fimages\u002Fspeech-driven-chatbot-flow.png","Speech Driven Chatbot system flow",[17,1406,1408],{"id":1407},"deploying-the-flow","Deploying the Flow",[10,1410,1411],{},[177,1412],{"alt":1413,"src":1414,"title":1415},"\"Deploying Sentiment analysis Node-RED flow\"","\u002Fblog\u002F2024\u002F01\u002Fimages\u002Fspeech-driven-chatbot-flowfue-editor.png","Deploying Sentiment analysis Node-RED flow",[10,1417,1418,1419],{},"We have successfully built our Speech-Driven Chatbot System. Now it's time to deploy the flow, to do that click on the red deploy button which you can find in the top right corner. After that go to ",[97,1420,1421],{},"https:\u002F\u002F\u003Cyour-instance-name>.flowfuse.cloud\u002Fdashboard",[10,1423,1424],{},[177,1425],{"alt":1426,"src":1427,"title":1428},"\"Speech Driven Chatbot using Node-RED Dashboard 2.0\"","\u002Fblog\u002F2024\u002F01\u002Fimages\u002Fspeech-driven-chatbot-system.gif","Speech Driven Chatbot using Node-RED Dashboard 2.0",[17,1430,1432],{"id":1431},"conclusion","Conclusion",[10,1434,1435],{},"In this guide, we have built a Speech-Driven Chatbot System which allows us to understand how we can add speech recognition and synthesis features into our project without any external API or custom node. It also provides a brief overview of how we can integrate chat-gpt into our system.",[1325,1437,1438],{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}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);}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":95,"searchDepth":117,"depth":117,"links":1440},[1441,1442,1443,1444,1445,1446,1447,1448,1449],{"id":19,"depth":117,"text":20},{"id":49,"depth":117,"text":50},{"id":62,"depth":117,"text":63},{"id":880,"depth":117,"text":881},{"id":910,"depth":117,"text":911},{"id":935,"depth":117,"text":936},{"id":957,"depth":117,"text":958},{"id":1407,"depth":117,"text":1408},{"id":1431,"depth":117,"text":1432},"md",{"navTitle":5,"excerpt":1452},{"type":7,"value":1453},[1454,1456],[10,1455,12],{},[10,1457,15],{},"\u002Fblog\u002F2024\u002F01\u002Fspeech-driven-chatbot-with-node-red",{"title":5,"description":12},"blog\u002F2024\u002F01\u002Fspeech-driven-chatbot-with-node-red","iWpfWnkX9eM1rRtp839cfxAsRIY_rzfoxRx0_UTZDGc",1780070551410]