UNPKG

node-red-contrib-chatbot

Version:

REDBot a Chat bot for a full featured chat bot for Telegram, Facebook Messenger and Slack. Almost no coding skills required

232 lines (223 loc) 12.5 kB
<script type="text/javascript"> $.RedBot.registerType('chatbot-alexa-node', { category: 'config', defaults: { botname: { value: '', required: true }, usernames: { value: '', required: false }, store: { value: '', type: 'chatbot-context-store', required: false }, log: { value: null }, debug: { value: false } }, oneditprepare: function() { var node = this; var nodeRedUrl = $.RedBot.getNodeRedUrl(); // fetch available context providers $.get(nodeRedUrl + 'redbot/globals') .done(function(response) { if (response != null && response.alexa != null && response.alexa[node.botname] != null) { $('#node-config-input-botname').prop('readonly', true); $('.form-editable').hide(); $('.form-warning').show(); $('.form-warning .bot-name').html('"' + node.botname + '"'); } }); }, paletteName: 'Alexa Bot', credentials: { token: { type: 'text' } }, label: function () { return this.botname; } }); </script> <script type="text/x-red" data-template-name="chatbot-alexa-node"> <div class="form-row"> <label for="node-config-input-botname"><i class="icon-bookmark"></i> Bot Name</label> <input type="text" id="node-config-input-botname"> </div> <div class="form-editable"> <div class="form-row"> <label for="node-config-input-usernames">Users</label> <input type="text" id="node-config-input-usernames"> <div style="max-width: 460px;font-size: 12px;color: #999999;line-height: 14px;margin-top:5px;"> Comma separated list of userId authorized to use the chatBot </div> </div> <div class="form-row"> <label for="node-config-input-log">Log file</label> <input type="text" id="node-config-input-log"> <div style="max-width: 460px;font-size: 12px;color: #999999;line-height: 14px;margin-top:5px;"> Store inbound and outbound messages to file </div> </div> <div class="form-row"> <label for="node-input-bot">Context</label> <input type="text" id="node-config-input-store" placeholder="Select storage for chat context"> <div style="max-width: 460px;font-size: 12px;color: #999999;line-height: 14px;margin-top:5px;"> Select the chat context provider to use with this bot, if none is selected then non-persistent "memory" will be used.<br> To extend <strong>RedBot</strong> with a new chat context provider see <a href="https://github.com/guidone/node-red-contrib-chatbot/wiki/Creating-a-Chat-Context-Provider" target="_blank">this tutorial</a>. </div> </div> <div class="form-row"> <label for="node-config-input-debug">Debug</label> <input type="checkbox" value="true" id="node-config-input-debug"> <span class="redbot-form-hint"> Show debug information on send/receive </span> </div> </div> <div class="form-warning" style="display:none;"> This bot configuration is stored in <b>Node-RED</b> <em>settings.js</em> and cannot be modified from the UI, check the section <code>functionGlobalContext</code> near the key <em class="bot-name">""</em> </div> </script> <script type="text/x-red" data-help-name="chatbot-alexa-node"><p>Open the <a href="https://developer.amazon.com/alexa/console/ask">Alexa Developer Console</a> and create a new <strong>skill</strong>:</p> <p><img src="https://s3.us-west-2.amazonaws.com/secure.notion-static.com/34cacc3a-3d2b-46be-883e-9da288a01ae3/example-alexa-1.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45EIPT3X45%2F20230218%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20230218T124917Z&X-Amz-Expires=3600&X-Amz-Signature=f969bae38ffd017dc01ea792aa843fcffabed3899d04d2e361b6d73979b09313&X-Amz-SignedHeaders=host&x-id=GetObject" alt="Example 1"></p> <p>Be sure to select the <em>custom</em> model and <em>Start from scratch</em> in the following step.</p> <p>Then you have to pickup the invocation name, it the name of your chatbot that will answer to sentences like <em>“Alexa, ask my-chatbot-name to …”</em>.</p> <p><strong>Alexa</strong> needs a callback to send the requests to: it must be a https endpoint (a self signed certificate it’s not enough). For testing we’ll use <strong>ngrok</strong> to create a https tunnel for our local <strong>Node-RED</strong> instance. Install it, then open a shell window and run</p> <pre><code class="language-bash">ngrok http 127.0.0.1:1880 </code></pre> <p>You should get something like</p> <p><img src="https://s3.us-west-2.amazonaws.com/secure.notion-static.com/58f7c691-68c9-4b1e-a781-5195cc281f0b/facebook-1.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45EIPT3X45%2F20230218%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20230218T124917Z&X-Amz-Expires=3600&X-Amz-Signature=75c10b05b87ccf4d2f29fe420a2e3693c69b6c084810ab8faf27c43aa6e35989&X-Amz-SignedHeaders=host&x-id=GetObject" alt=""></p> <p>Grab the https address you get, something like <em><a href="https://123123.ngrok.io">https://123123.ngrok.io</a></em>, this is the base url that points back to your <strong>Node-RED</strong> instance.</p> <p>The callback is</p> <pre><code class="language-plain">http://youraddress.ngrok.io/redbot/alexa </code></pre> <p>This callback should fill the field <em>Default region</em> in the <em>Endpoint</em> session</p> <p><img src="https://s3.us-west-2.amazonaws.com/secure.notion-static.com/1faafaf8-a853-4701-8af6-6dab18f9732b/example-alexa-2.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45EIPT3X45%2F20230218%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20230218T124917Z&X-Amz-Expires=3600&X-Amz-Signature=cf5fcffb35bd0e4caca6045c6c1e2ed8a51243cd5c88b2d037edce67e6e147ee&X-Amz-SignedHeaders=host&x-id=GetObject" alt="Example 2"></p> <p>We’re ready to create the first simple flow:</p> <p><img src="https://s3.us-west-2.amazonaws.com/secure.notion-static.com/1b2f58a1-7809-4d64-89cd-4b8451db57de/example-alexa-3.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45EIPT3X45%2F20230218%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20230218T124917Z&X-Amz-Expires=3600&X-Amz-Signature=bda2b6eff339a87b12b01e36f84dcc0c13a8da381ff8e07750b6daa996181baf&X-Amz-SignedHeaders=host&x-id=GetObject" alt="Example 3"></p> <p><em>Note:</em> the <code>Alexa Receiver</code> node configuration doesn’t need any particular configuration (no tokens or secret key like other chatbots), for testing the default one is ok.</p> <p>Now switch to the test page from the menu and type</p> <pre><code class="language-plain">start my-chatbot-name </code></pre> <p>you should hear the answer defined in the <a href="https://www.notion.so/08bc9f05559a47819fd07a4bacc28c73">Alexa Speech node</a> and see in the console the <a href="https://www.notion.so/4a49f90897d8444fa8a780ea40d6b26e">Events</a> of type <em>start</em></p> <p><img src="https://s3.us-west-2.amazonaws.com/secure.notion-static.com/7d1e7ac5-b4f8-4bc9-b3c4-fc5eac7d5ebe/example-alexa-4.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45EIPT3X45%2F20230218%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20230218T124917Z&X-Amz-Expires=3600&X-Amz-Signature=ac24b263b292af82436d2b8302fe1165059f6b84b9d4ba648d855f5abf52a361&X-Amz-SignedHeaders=host&x-id=GetObject" alt="Example 4"></p> <p><strong>Important:</strong> <strong>Alexa</strong> chatbots works differently compared to other chatbot APIs like <strong>Telegram</strong> or <strong>Facebook</strong>: calls are synchronous, when <strong>Alexa</strong> calls the <strong>RedBot</strong>’s endpoint it expects an immediate response. Internally <strong>RedBot</strong> will store the <em>response</em> object in the <strong>Node-RED</strong> message and will use it in the final <code>Alexa Sender node</code>. For this reason the flow (nodes between the receiver to the sender nodes) cannot last more than the <strong>Alexa</strong> timeout (<strong>3000 ms</strong>).</p> </script> <script type="text/javascript"> $.RedBot.registerType('chatbot-alexa-receive', { category: $.RedBot.config.name + ' Platforms', color: '#FFCC66', defaults: { bot: { value: '', type: 'chatbot-alexa-node', required: true }, botProduction: { value: "", type: 'chatbot-alexa-node', required: false }, }, inputs: 0, outputs: 1, icon: 'alexa.svg', paletteLabel: 'Alexa Receiver', label: function () { return "Alexa Receiver"; } }); </script> <script type="text/x-red" data-template-name="chatbot-alexa-receive"> <div class="form-row"> <label for="node-input-bot" style="display:block;width:100%;">Bot configuration <span class="redbot-environment">(development)</span></label> <input type="text" id="node-input-bot" placeholder="Bot"> </div> <div class="form-row" style="margin-top:25px;"> <label for="node-input-botProduction" style="display:block;width:100%;">Bot configuration <span class="redbot-environment">(production)</span></label> <input type="text" id="node-input-botProduction" placeholder="Bot"> </div> <div class="redbot-form-hint"> Bot for <strong>production</strong> will be launched only if the global variable <em>"environment"</em> in <em>settings.js</em> is set to <em>"production"</em>, otherwise will be used the configuration for <strong>development</strong>. </div> </script> <script type="text/x-red" data-help-name="chatbot-alexa-receive"> <p>Input node for Alexa.</p> </script> <script type="text/javascript"> $.RedBot.registerType('chatbot-alexa-send', { category: $.RedBot.config.name + ' Platforms', color: '#FFCC66', defaults: { bot: { value: '', type: 'chatbot-alexa-node', required: true }, botProduction: { value: "", type: 'chatbot-alexa-node', required: false }, track: { value: false }, passThrough: { value: false }, outputs: { value: 0 } }, inputs: 1, outputs: 1, icon: 'alexa.svg', paletteLabel: 'Alexa Sender', label: function () { return 'Alexa Sender'; }, oneditsave: function() { var track = $('#node-input-track').is(':checked'); var passThrough = $('#node-input-passThrough').is(':checked'); this.outputs = track || passThrough ? 1 : 0; } }); </script> <script type="text/x-red" data-template-name="chatbot-alexa-send"> <div class="form-row"> <label for="node-input-bot" style="display:block;width:100%;">Bot configuration <span class="redbot-environment">(development)</span></label> <input type="text" id="node-input-bot" placeholder="Bot"> </div> <div class="form-row" style="margin-top:25px;"> <label for="node-input-botProduction" style="display:block;width:100%;">Bot configuration <span class="redbot-environment">(production)</span></label> <input type="text" id="node-input-botProduction" placeholder="Bot"> </div> <div class="redbot-form-hint"> Bot for <strong>production</strong> will be launched only if the global variable <em>"environment"</em> in <em>settings.js</em> is set to <em>"production"</em>, otherwise will be used the configuration for <strong>development</strong>. </div> <div class="form-row" style="margin-top:25px;"> <label for="node-input-track" style="margin-bottom:0px;">Track</label> <input type="checkbox" value="true" id="node-input-track" style="margin-top:0px;"> <div class="redbot-form-hint"> Track response of the user for this message: any further answer will be redirect to the output pin. </div> <label for="node-input-track" style="margin-bottom:0px;margin-top:15px;">Pass Through</label> <input type="checkbox" value="true" id="node-input-passThrough" style="margin-top:0px;"> <div class="redbot-form-hint"> Forward the message to the output pin after sending (useful to chain messages and keep the right order) </div> </div> </script> <script type="text/x-red" data-help-name="chatbot-alexa-send"> <p>Output node for Alexa.</p> </script>