{"id":6998,"date":"2019-06-03T22:11:14","date_gmt":"2019-06-04T05:11:14","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=6998"},"modified":"2025-06-13T21:23:08","modified_gmt":"2025-06-14T04:23:08","slug":"build-chatbot-couchbase-amazon-lex-node-js","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/build-chatbot-couchbase-amazon-lex-node-js\/","title":{"rendered":"Building a Chatbot with Couchbase, Amazon Lex, and Node.js"},"content":{"rendered":"<p><em><a href=\"https:\/\/www.thepolyglotdeveloper.com\/\">Nic Raboy<\/a>&nbsp;is an advocate of modern web and mobile development technologies. He has experience in Java, JavaScript, Golang, and a variety of frameworks such as Angular, NativeScript, and Apache Cordova.&nbsp;<a href=\"https:\/\/twitter.com\/nraboy\">Nic<\/a>&nbsp;writes about his development experiences related to making web and mobile development easier to understand.<\/em><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-6316\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2019\/01\/nraboy-here-300x300.jpg\" alt=\"Nic Raboy\" width=\"300\" height=\"300\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/01\/nraboy-here-300x300.jpg 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/01\/nraboy-here.jpg 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/01\/nraboy-here-150x150.jpg 150w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/01\/nraboy-here-768x768.jpg 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/01\/nraboy-here-65x65.jpg 65w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/01\/nraboy-here-50x50.jpg 50w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/01\/nraboy-here-20x20.jpg 20w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>It is no question that the future is going to be automated. We have automated self-driving vehicles, voice assistants, call center and text-based bots, and so much more. However, what does it take to bring automation to your business?<\/p>\n<p>The short answer is that it doesn\u2019t take much more than building standard applications if you\u2019re using the right tools.<\/p>\n<p>In this tutorial we\u2019re going to explore creating a chatbot that can take some of the workload off your human employees by leveraging <a href=\"https:\/\/aws.amazon.com\/lex\/\">Amazon Lex<\/a> for deep learning and conversational interfaces, <a href=\"https:\/\/www.couchbase.com\">Couchbase<\/a> NoSQL as the database, and <a href=\"https:\/\/docs.couchbase.com\/nodejs-sdk\/current\/start-using-sdk.html\">Node.js<\/a> for interacting with the database.<\/p>\n<h2 id=\"the-requirements-for-this-tutorial\">The Requirements for this Tutorial<\/h2>\n<p>There are a few software requirements that must be met in order to be successful with this tutorial and project:<\/p>\n<ol type=\"1\">\n<li>Couchbase Server 5.0+ must be installed and available remotely.<\/li>\n<li>An AWS account.<\/li>\n<li>Docker or a virtual machine software.<\/li>\n<\/ol>\n<p>Because we\u2019ll be using Amazon products such as Lex and Lambda, an AWS account must be available. Both products are pay as you go, so a free tier will likely be more than enough. Since we\u2019ll be using Amazon products, these products need access to Couchbase. For this reason Couchbase cannot be running from localhost, it must be installed somewhere remotely. Finally, since the Couchbase Node.js SDK uses native dependencies, Docker or some other virtual machine software must be available to download the dependencies as Linux, which is what Lambda expects.<\/p>\n<h2 id=\"configuring-amazon-lex-for-user-interaction\">Configuring Amazon Lex for User Interaction<\/h2>\n<p>Before we get into the code, we can spend our time configuring Lex. While Lambda will allow us to make our bot useful, you don\u2019t need any kind of backend to play around with Lex.<\/p>\n<p>Go to <a href=\"https:\/\/console.aws.amazon.com\/lex\">Lex<\/a> in your AWS portal and choose to create a new custom bot.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-7005\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2019\/06\/aws-lex-custom-bot-300x147.jpeg\" alt=\"aws-lex-custom-bot\" width=\"435\" height=\"213\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/aws-lex-custom-bot-300x147.jpeg 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/aws-lex-custom-bot-1024x503.jpeg 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/aws-lex-custom-bot-768x377.jpeg 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/aws-lex-custom-bot-20x10.jpeg 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/aws-lex-custom-bot-1320x649.jpeg 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/aws-lex-custom-bot.jpeg 1500w\" sizes=\"auto, (max-width: 435px) 100vw, 435px\" \/><\/p>\n<p>Since we\u2019re creating a text-based bot, the output voice should be none. Everything else should just be the defaults or whatever you deem to be most appropriate.<\/p>\n<p>With the custom bot created, the first step is to start creating intents. For this example we\u2019re going to create an <code>AboutIntent<\/code>, <code>GetProfileIntent<\/code> and <code>UpgradeServiceIntent<\/code>, two of which will use Couchbase for information.<\/p>\n<p>Let\u2019s start with the <code>AboutIntent<\/code>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-7006\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2019\/06\/aws-lex-aboutintent-300x147.jpg\" alt=\"aws-lex-aboutintent\" width=\"398\" height=\"195\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/aws-lex-aboutintent-300x147.jpg 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/aws-lex-aboutintent-1024x501.jpg 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/aws-lex-aboutintent-768x376.jpg 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/aws-lex-aboutintent-20x10.jpg 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/aws-lex-aboutintent-1320x646.jpg 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/aws-lex-aboutintent.jpg 1500w\" sizes=\"auto, (max-width: 398px) 100vw, 398px\" \/><\/p>\n<p>The idea behind the <code>AboutIntent<\/code> is to just get us started. We won\u2019t be using the database for this intent, but it will eventually connect to our Lambda function. This intent is to give us information about the bot.<\/p>\n<p>To trigger our intent, we need to define some sample utterances which are basically a list of possible phrases. Take the following for example:<\/p>\n<pre><code>who made this chatbot\r\nwhat can you tell me about yourself\r\ngive me information about this bot<\/code><\/pre>\n<p>The above phrases are what a user might ask. The more the better because Lex will learn from the training data and be able to fill in the gaps if someone asks something that isn\u2019t from the list.<\/p>\n<p>For now we\u2019ll leave <strong>Fulfillment<\/strong> as <strong>Return parameters to client<\/strong>, but we\u2019ll eventually switch it to Lambda.<\/p>\n<p>Let\u2019s take a look at <code>GetProfileIntent<\/code> now.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-7007\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2019\/06\/aws-lex-getprofileintent-300x147.jpeg\" alt=\"aws-lex-getprofileintent\" width=\"484\" height=\"237\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/aws-lex-getprofileintent-300x147.jpeg 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/aws-lex-getprofileintent-1024x503.jpeg 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/aws-lex-getprofileintent-768x377.jpeg 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/aws-lex-getprofileintent-20x10.jpeg 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/aws-lex-getprofileintent-1320x649.jpeg 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/aws-lex-getprofileintent.jpeg 1500w\" sizes=\"auto, (max-width: 484px) 100vw, 484px\" \/><\/p>\n<p>This intent is a slightly different because we want to be able to accept dynamic information from the user, something that will change between different users. We can allow dynamic information through slot variables.<\/p>\n<p>Take the following sample utterances which contain slot variables:<\/p>\n<pre><code>i need some information about my account\r\nget me some information about my account {AccountId}<\/code><\/pre>\n<p>Not all sample utterances need to contain slot variables, but notice that the variable is wrapped in curly brackets. Each variable used can be defined within the intent configuration. For example, our <code>AccountId<\/code> is defined as an <code>AMAZON.EmailAddress<\/code> with a default prompt phrase.<\/p>\n<p>So what does this mean?<\/p>\n<p>When Lex determines our slot variable exists, it must be a valid email address. If Lex determines we\u2019re trying to execute the <code>GetProfileInfo<\/code> intent, but the variable doesn\u2019t exist, it will use our prompt phrase to ask the user for that variable information. This makes the conversation fluid, but without omitting any required data.<\/p>\n<p>Finally, let\u2019s look at <code>UpgradeServiceIntent<\/code>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-7008\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2019\/06\/aws-lex-upgradeserviceintent-300x147.jpeg\" alt=\"aws-lex-upgradeserviceintent\" width=\"502\" height=\"246\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/aws-lex-upgradeserviceintent-300x147.jpeg 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/aws-lex-upgradeserviceintent-1024x502.jpeg 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/aws-lex-upgradeserviceintent-768x376.jpeg 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/aws-lex-upgradeserviceintent-20x10.jpeg 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/aws-lex-upgradeserviceintent-1320x647.jpeg 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/aws-lex-upgradeserviceintent.jpeg 1500w\" sizes=\"auto, (max-width: 502px) 100vw, 502px\" \/><\/p>\n<p>The <code>UpgradeServiceIntent<\/code> is similar to our <code>GetProfileIntent<\/code>, but this time we have two possible slot variables. Take the following sample utterances:<\/p>\n<pre><code>i'd like {Service} and my account information is {AccountId}\r\ni'd like to upgrade my service to {Service}<\/code><\/pre>\n<p>Remember, two sample utterances is not nearly enough, but hopefully you get the idea when it comes to how variables can be used. The idea is that you want conversation with this chatbot to be fluid like a real person because then you can replace the real person with the bot.<\/p>\n<p>There is an exception though with the <code>UpgradeServiceIntent<\/code> slot variables. The <code>Service<\/code> variable is a custom slot that we must create.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-7009\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2019\/06\/aws-lex-custom-slot-300x147.jpg\" alt=\"aws-lex-custom-slot\" width=\"480\" height=\"235\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/aws-lex-custom-slot-300x147.jpg 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/aws-lex-custom-slot-1024x502.jpg 1024w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/aws-lex-custom-slot-768x377.jpg 768w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/aws-lex-custom-slot-20x10.jpg 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/aws-lex-custom-slot-1320x648.jpg 1320w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/aws-lex-custom-slot.jpg 1500w\" sizes=\"auto, (max-width: 480px) 100vw, 480px\" \/><\/p>\n<p>In our example we want to create a <code>CustomServiceSlot<\/code> where the name isn\u2019t important, but the data is. We want to define the possible things that can exist within the variable. In our example we are saying that the slot can be any of the following:<\/p>\n<ul>\n<li>Silver<\/li>\n<li>Gold<\/li>\n<li>Ultimate<\/li>\n<\/ul>\n<p>We\u2019re assuming the three items above are possible services. This is just an example and your needs may vary.<\/p>\n<p>At this point in time you can save each of the three intents and build your bot.<\/p>\n<h2 id=\"developing-aws-lambda-logic-with-simple-javascript-and-couchbase\">Developing AWS Lambda Logic with Simple JavaScript and Couchbase<\/h2>\n<p>We have our intents, our sample utterances, and our slot variables. It is time to create logic to respond back to our user when intents are triggered.<\/p>\n<p>You should already have Couchbase installed, configured, and ready to go. The goal of this tutorial is not how to setup Couchbase, but how to use it with Lex.<\/p>\n<p>Within Couchbase, add the following document to your Bucket:<\/p>\n<pre><code>{\r\n    \"email\": \"test@test.com\",\r\n    \"service\": \"Silver\"\r\n}<\/code><\/pre>\n<p>We\u2019re going to assume the above document is a customer and they currently have the \u201cSilver\u201d plan, whatever that might mean. In theory, this example could be useful to any organization that has a call or chat line. For example, think Comcast for internet. If you create a bot, your users could call in or chat in, and request changes to their account. The bot could interpret this and do the changes without a person doing them.<\/p>\n<p>On your computer, create a new directory and execute the following:<\/p>\n<pre><code>npm init -y\r\nnpm install git+https:\/\/github.com\/couchbase\/couchnode.git#v2.5.1 --save\r\ntouch index.js<\/code><\/pre>\n<p>The above commands will create a new <strong>package.json<\/strong> file and install the <a href=\"https:\/\/docs.couchbase.com\/server\/current\/sdk\/overview.html\">Couchbase SDK<\/a>. We are using the GitHub URL for reasons of it having native dependencies that need to be built from source. If you don\u2019t have the <code>touch<\/code> command, create an <strong>index.js<\/strong> file manually.<\/p>\n<p>Within the <strong>index.js<\/strong> file, add the following boilerplate code:<\/p>\n<pre><code>const Couchbase = require(\"couchbase\");\r\n\r\nvar cluster, bucket;\r\n\r\nconst dispatcher = async (event) =&gt; {\r\n    let response = {\r\n        \"dialogAction\": {\r\n            \"type\": \"Close\",\r\n            \"fulfillmentState\": \"\",\r\n            \"message\": {\r\n                \"contentType\": \"PlainText\",\r\n                \"content\": \"\"\r\n            }\r\n        }\r\n    };\r\n    let cbResult;\r\n    switch(event.currentIntent.name) {\r\n        default:\r\n            response.dialogAction.fulfillmentState = \"Failed\";\r\n            response.dialogAction.message.content = \"The request could not be understood.\";\r\n            break;\r\n    }\r\n    return response;\r\n}\r\n\r\nconst handler = (event) =&gt; {\r\n    if(cluster == null || bucket == null) {\r\n        cluster = new Couchbase.Cluster(\"couchbase:\/\/COUCHBASE_HOST_HERE\");\r\n        cluster.authenticate(\"COUCHBASE_USERNAME\", \"COUCHBASE_PASSWORD\");\r\n        bucket = cluster.openBucket(\"COUCHBASE_BUCKET\");\r\n        console.log(bucket);\r\n    }\r\n    return dispatcher(event);\r\n};\r\n\r\nexports.handler = handler;<\/code><\/pre>\n<p>There are a few things to note in the above code. I\u2019ve only added placeholder information for the host, username, password, and Bucket. You\u2019ll need to replace it with that of your actual Couchbase installation.<\/p>\n<p>What\u2019s happening above is we\u2019re creating a Lambda function with a dispatcher function. When Lex receives a chat message, it creates a request object to be sent to Lambda. In our scenario, Lambda takes the request object and feeds it into a dispatcher after establishing a connection to the database. Inside the dispatcher, a response object is created and the intent is analyzed.<\/p>\n<p>As of right now all intents are bad intents as they will only hit the default condition. We\u2019re going to change that.<\/p>\n<p>Let\u2019s start by worrying about our <code>AboutIntent<\/code> since it is the most simple:<\/p>\n<pre><code>switch(event.currentIntent.name) {\r\n    case \"AboutIntent\":\r\n        response.dialogAction.fulfillmentState = \"Fulfilled\";\r\n        response.dialogAction.message.content = \"Created by Nic Raboy, The Polyglot Developer\";\r\n        break;\r\n    default:\r\n        response.dialogAction.fulfillmentState = \"Failed\";\r\n        response.dialogAction.message.content = \"The request could not be understood.\";\r\n        break;\r\n}<\/code><\/pre>\n<p>If Lex determines the user is asking for information and chooses the <code>AboutIntent<\/code> we\u2019re going to respond with a basic, but appropriate message. Otherwise, we\u2019re still going to fail the request.<\/p>\n<p>Now let\u2019s take a look at a more complicated intent, for example, the <code>GetProfileIntent<\/code>:<\/p>\n<pre><code>case \"GetProfileIntent\":\r\n    cbResult = await new Promise((resolve, reject) =&gt; {\r\n        let statement = \"SELECT * FROM lexbot WHERE email = $email\";\r\n        let query = Couchbase.N1qlQuery.fromString(statement);\r\n        bucket.query(query, { email: event.currentIntent.slots.AccountId }, (error, result) =&gt; {\r\n            if(error) {\r\n                return reject({ status: \"Failed\", message: error.message });\r\n            }\r\n            resolve({ status: \"Fulfilled\", message: JSON.stringify(result) });\r\n        });\r\n    });\r\n    response.dialogAction.fulfillmentState = cbResult.status;\r\n    response.dialogAction.message.content = cbResult.message;\r\n    break;<\/code><\/pre>\n<p>The idea behind this intent is when the user asks for information about their profile, the document should be returned. What we\u2019re doing is we\u2019re creating a <a href=\"https:\/\/www.couchbase.com\/products\/n1ql\/\">N1QL query<\/a> with the <code>email<\/code> as the condition. Remember the Lex <code>AccountId<\/code> variable is just an email for our example. The results of that query are then serialized and returned back to Lex to be shown to the user.<\/p>\n<p>Now let\u2019s complicate things a little more. Let\u2019s look at our <code>UpgradeServiceIntent<\/code>:<\/p>\n<pre><code>case \"UpgradeServiceIntent\":\r\n    cbResult = await new Promise((resolve, reject) =&gt; {\r\n        let statement = `\r\n            UPDATE lexbot\r\n            SET service = $service\r\n            WHERE email = $email\r\n        `;\r\n        let query = Couchbase.N1qlQuery.fromString(statement);\r\n        bucket.query(\r\n            query, \r\n            { \r\n                service: event.currentIntent.slots.Service,\r\n                email: event.currentIntent.slots.AccountId\r\n            },\r\n            (error, result) =&gt; {\r\n                if(error) {\r\n                    return reject({\r\n                        status: \"Failed\",\r\n                        message: error.message\r\n                    });\r\n                }\r\n                resolve({\r\n                    status: \"Fulfilled\",\r\n                    message: \"Service has been upgraded to \" + event.currentIntent.slots.Service + \" for \" + event.currentIntent.slots.AccountId\r\n                });\r\n            }\r\n        );\r\n    });\r\n    response.dialogAction.fulfillmentState = cbResult.status;\r\n    response.dialogAction.message.content = cbResult.message;\r\n    break;<\/code><\/pre>\n<p>We\u2019re going to do another N1QL query, but this time an <code>UPDATE<\/code> operation. The idea is that the user wants to upgrade their service. They provide their account information and the service they want, and our Lambda logic handles it without human intervention.<\/p>\n<p>We\u2019re not doing any data sanitization, but we could.<\/p>\n<p>At this point our Lambda function is done. We can respond to three different queries through fluid human chatting with Lex. Now I mentioned that the Couchbase SDK uses native dependencies. Because the focus of this tutorial is not Lambda, I\u2019m going to refer you to a previous tutorial I wrote titled, <a href=\"https:\/\/www.thepolyglotdeveloper.com\/2017\/12\/deploying-native-nodejs-dependencies-aws-lambda\/\">Deploying Native Node.js Dependencies on AWS Lambda<\/a>.<\/p>\n<p>After you upload the Lambda package, you need to go back into the Lex dashboard and for each intent choose <strong>AWS Lambda function<\/strong> as the <strong>Fulfillment<\/strong> option. Once done, rebuild and your chatbot should get its data from your Lambda code, which is getting its data from Couchbase.<\/p>\n<h2 id=\"conclusion\">Conclusion<\/h2>\n<p>You just saw how to create a simple, but potentially useful chatbot with Amazon Lex and <a href=\"https:\/\/www.couchbase.com\">Couchbase<\/a>. Chatbots are very useful and probably the future when it comes to replacing humans in call centers or other support lines.<\/p>\n<p>In a production scenario, you\u2019ll probably want to do data validation on anything that comes in from Lex. For example checking if data exists, or even doing things more securely. In this example I could change the service of anyone just by providing the email address. You\u2019ll probably want to change that in production.<\/p>\n<p><em>This post is brought to you by the Couchbase <a href=\"https:\/\/www.couchbase.com\/community\/community-writers-program\/\">Community Writing Program<\/a><\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Nic Raboy&nbsp;is an advocate of modern web and mobile development technologies. He has experience in Java, JavaScript, Golang, and a variety of frameworks such as Angular, NativeScript, and Apache Cordova.&nbsp;Nic&nbsp;writes about his development experiences related to making web and mobile [&hellip;]<\/p>\n","protected":false},"author":53,"featured_media":7030,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1822,1812],"tags":[],"ppma_author":[9026],"class_list":["post-6998","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-node-js","category-n1ql-query"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.7.1 (Yoast SEO v25.7) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Building a Chatbot with Couchbase, Amazon Lex, and Node.js - The Couchbase Blog<\/title>\n<meta name=\"description\" content=\"Creating a chatbot that can take some of the workload off your human employees by leveraging Amazon Lex for deep learning and conversational interfaces, Couchbase NoSQL as the database, and Node.js for interacting with the database.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/build-chatbot-couchbase-amazon-lex-node-js\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Building a Chatbot with Couchbase, Amazon Lex, and Node.js\" \/>\n<meta property=\"og:description\" content=\"Creating a chatbot that can take some of the workload off your human employees by leveraging Amazon Lex for deep learning and conversational interfaces, Couchbase NoSQL as the database, and Node.js for interacting with the database.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/build-chatbot-couchbase-amazon-lex-node-js\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2019-06-04T05:11:14+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T04:23:08+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/AmazonxCB-Blog-Banner.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"900\" \/>\n\t<meta property=\"og:image:height\" content=\"411\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Laura Czajkowski, Developer Community Manager, Couchbase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Laura Czajkowski, Developer Community Manager, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/build-chatbot-couchbase-amazon-lex-node-js\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/build-chatbot-couchbase-amazon-lex-node-js\/\"},\"author\":{\"name\":\"Laura Czajkowski, Developer Community Manager, Couchbase\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/5f1a0ece4e644bc8c037686fbc8f3220\"},\"headline\":\"Building a Chatbot with Couchbase, Amazon Lex, and Node.js\",\"datePublished\":\"2019-06-04T05:11:14+00:00\",\"dateModified\":\"2025-06-14T04:23:08+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/build-chatbot-couchbase-amazon-lex-node-js\/\"},\"wordCount\":1630,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/build-chatbot-couchbase-amazon-lex-node-js\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/AmazonxCB-Blog-Banner.jpg\",\"articleSection\":[\"Node.js\",\"SQL++ \/ N1QL Query\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/build-chatbot-couchbase-amazon-lex-node-js\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/build-chatbot-couchbase-amazon-lex-node-js\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/build-chatbot-couchbase-amazon-lex-node-js\/\",\"name\":\"Building a Chatbot with Couchbase, Amazon Lex, and Node.js - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/build-chatbot-couchbase-amazon-lex-node-js\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/build-chatbot-couchbase-amazon-lex-node-js\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/AmazonxCB-Blog-Banner.jpg\",\"datePublished\":\"2019-06-04T05:11:14+00:00\",\"dateModified\":\"2025-06-14T04:23:08+00:00\",\"description\":\"Creating a chatbot that can take some of the workload off your human employees by leveraging Amazon Lex for deep learning and conversational interfaces, Couchbase NoSQL as the database, and Node.js for interacting with the database.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/build-chatbot-couchbase-amazon-lex-node-js\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/build-chatbot-couchbase-amazon-lex-node-js\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/build-chatbot-couchbase-amazon-lex-node-js\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/AmazonxCB-Blog-Banner.jpg\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/AmazonxCB-Blog-Banner.jpg\",\"width\":900,\"height\":411,\"caption\":\"AmazonxCB Blog Banner\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/build-chatbot-couchbase-amazon-lex-node-js\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Building a Chatbot with Couchbase, Amazon Lex, and Node.js\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/5f1a0ece4e644bc8c037686fbc8f3220\",\"name\":\"Laura Czajkowski, Developer Community Manager, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/9deb07d5daaa00220534c31768bc4409\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/bc8eebaf25cbe39bc12fd7b1ef92550becc3953ab877a3f0285a59ec2d30b754?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/bc8eebaf25cbe39bc12fd7b1ef92550becc3953ab877a3f0285a59ec2d30b754?s=96&d=mm&r=g\",\"caption\":\"Laura Czajkowski, Developer Community Manager, Couchbase\"},\"description\":\"Laura Czajkowski is the Snr. Developer Community Manager at Couchbase overseeing the community. She\u2019s responsible for our monthly developer newsletter.\",\"url\":\"https:\/\/www.couchbase.com\/blog\/author\/laura-czajkowski\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Building a Chatbot with Couchbase, Amazon Lex, and Node.js - The Couchbase Blog","description":"Creating a chatbot that can take some of the workload off your human employees by leveraging Amazon Lex for deep learning and conversational interfaces, Couchbase NoSQL as the database, and Node.js for interacting with the database.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/build-chatbot-couchbase-amazon-lex-node-js\/","og_locale":"en_US","og_type":"article","og_title":"Building a Chatbot with Couchbase, Amazon Lex, and Node.js","og_description":"Creating a chatbot that can take some of the workload off your human employees by leveraging Amazon Lex for deep learning and conversational interfaces, Couchbase NoSQL as the database, and Node.js for interacting with the database.","og_url":"https:\/\/www.couchbase.com\/blog\/build-chatbot-couchbase-amazon-lex-node-js\/","og_site_name":"The Couchbase Blog","article_published_time":"2019-06-04T05:11:14+00:00","article_modified_time":"2025-06-14T04:23:08+00:00","og_image":[{"width":900,"height":411,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/AmazonxCB-Blog-Banner.jpg","type":"image\/jpeg"}],"author":"Laura Czajkowski, Developer Community Manager, Couchbase","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Laura Czajkowski, Developer Community Manager, Couchbase","Est. reading time":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/build-chatbot-couchbase-amazon-lex-node-js\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/build-chatbot-couchbase-amazon-lex-node-js\/"},"author":{"name":"Laura Czajkowski, Developer Community Manager, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/5f1a0ece4e644bc8c037686fbc8f3220"},"headline":"Building a Chatbot with Couchbase, Amazon Lex, and Node.js","datePublished":"2019-06-04T05:11:14+00:00","dateModified":"2025-06-14T04:23:08+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/build-chatbot-couchbase-amazon-lex-node-js\/"},"wordCount":1630,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/build-chatbot-couchbase-amazon-lex-node-js\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/AmazonxCB-Blog-Banner.jpg","articleSection":["Node.js","SQL++ \/ N1QL Query"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/build-chatbot-couchbase-amazon-lex-node-js\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/build-chatbot-couchbase-amazon-lex-node-js\/","url":"https:\/\/www.couchbase.com\/blog\/build-chatbot-couchbase-amazon-lex-node-js\/","name":"Building a Chatbot with Couchbase, Amazon Lex, and Node.js - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/build-chatbot-couchbase-amazon-lex-node-js\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/build-chatbot-couchbase-amazon-lex-node-js\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/AmazonxCB-Blog-Banner.jpg","datePublished":"2019-06-04T05:11:14+00:00","dateModified":"2025-06-14T04:23:08+00:00","description":"Creating a chatbot that can take some of the workload off your human employees by leveraging Amazon Lex for deep learning and conversational interfaces, Couchbase NoSQL as the database, and Node.js for interacting with the database.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/build-chatbot-couchbase-amazon-lex-node-js\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/build-chatbot-couchbase-amazon-lex-node-js\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/build-chatbot-couchbase-amazon-lex-node-js\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/AmazonxCB-Blog-Banner.jpg","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2019\/06\/AmazonxCB-Blog-Banner.jpg","width":900,"height":411,"caption":"AmazonxCB Blog Banner"},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/build-chatbot-couchbase-amazon-lex-node-js\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Building a Chatbot with Couchbase, Amazon Lex, and Node.js"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"The Couchbase Blog","description":"Couchbase, the NoSQL Database","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"The Couchbase Blog","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/5f1a0ece4e644bc8c037686fbc8f3220","name":"Laura Czajkowski, Developer Community Manager, Couchbase","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/9deb07d5daaa00220534c31768bc4409","url":"https:\/\/secure.gravatar.com\/avatar\/bc8eebaf25cbe39bc12fd7b1ef92550becc3953ab877a3f0285a59ec2d30b754?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/bc8eebaf25cbe39bc12fd7b1ef92550becc3953ab877a3f0285a59ec2d30b754?s=96&d=mm&r=g","caption":"Laura Czajkowski, Developer Community Manager, Couchbase"},"description":"Laura Czajkowski is the Snr. Developer Community Manager at Couchbase overseeing the community. She\u2019s responsible for our monthly developer newsletter.","url":"https:\/\/www.couchbase.com\/blog\/author\/laura-czajkowski\/"}]}},"authors":[{"term_id":9026,"user_id":53,"is_guest":0,"slug":"laura-czajkowski","display_name":"Laura Czajkowski, Developer Community Manager, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/bc8eebaf25cbe39bc12fd7b1ef92550becc3953ab877a3f0285a59ec2d30b754?s=96&d=mm&r=g","author_category":"","last_name":"Czajkowski","first_name":"Laura","job_title":"","user_url":"","description":"Laura Czajkowski is the Snr. Developer Community Manager at Couchbase overseeing the community. She\u2019s responsible for our monthly developer newsletter."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/6998","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/users\/53"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/comments?post=6998"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/6998\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media\/7030"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media?parent=6998"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/categories?post=6998"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/tags?post=6998"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=6998"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}