How To Integrate Chatbots Into Vue Apps Using AWS Amplify
Tags: javascript, vue, aws, webdev
Published: 2022-01-10 10:46:29

Everyday, new tools are been created or designed to simplify interactions between end-users and computers. On websites like e-commerce websites there is a need to automate interactions using a chatbot as it will serve as a standby employee 24/7.

Throughout this tutorial, we will be looking at how we can practically deploy chatbots to our Vue app with fewer lines of code using the Amazon Lex service through the AWS Amplify CLI (Command Line Interface).


##What is AWS Amplify

AWS Amplify is a set of tools that helps developers create scalable, full-stack mobile and web applications all powered by AWS. Amplify lets you configure backends, connect your apps in minutes, and deploy static web apps in a few minutes. We can also say that Amplify is a faster route to use AWS services.

##Why Chatbots

Chatbot applications streamline interaction between people and services thereby enhancing the customer experience. Furthermore, they offer companies new opportunities to improve customer engagement processes and operational efficiency by reducing the typical cost of customer service.

In this tutorial, we will create a chatbot that we can use to place orders for items and implement them in our Vue app.


##Chatbot Walkthrough

Before we dive deep into our tutorial, here are some terminologies we should familiarize ourselves with as we will use them in later parts of the tutorial.


-  Intent: This is what the user objectives are or what the user wishes to achieve

-  Slots: Slots are the data the user must provide to fulfill the intent, you can create as many slots  as possible. Slots are all features that the bot can have.

-  Lambda Function: This is just functionality that enables the chatbot to work with external API like open weather API.


##Setup AWS Amplify CLI

Just before we set up the Amplify CLI, we need to create our Vue project first and we will be using Vue 2 for this tutorial. There is already a start-up project for you in my repository, so instead of going through all the stress of creating a new one, you can just clone my repository to your local machine but you can begin from scratch if you want to.
Note: You need to install CLI in the project directory.

To install AWS Amplify, first create an AWS account [signup](https://portal.aws.amazon.com/billing/signup?nc2=h_ct&src=header_signup&redirect_url=https%3A%2F%2Faws.amazon.com%2Fregistration-confirmation#/start).

On your terminal, use the command `npm install -g @aws-amplify/cli` to install AWS globally on your local machine. 
This will allow us to access and interface with their services faster, directly on our local machine.


##Configure AWS

Still on your terminal, use the `amplify configure` command. The `amplify configure` command will set up an account that will allow us to interface with AWS services and allow Amplify CLI to create bot services for us.
The `amplify configure` command will prompt us to sign in to your AWS account and sign in as a root. After doing so, it should open a new window on your browser called the “AWS Management Console”.

Once you are signed in, go back to your terminal and hit enter to continue, select a region, we will be using us-east-1, specify a username or you can use the default name by just hitting enter. After that, a new window will open on our browser to continue creating the user, make sure to check programmatic access which will enable access key ID and secret access key which we will need later to initialize amplify. Hit the next permission button and make sure administrator access is checked and should be by default. Hit next, we won’t be adding any tags, hit the create user button and once the user is created, it will provide us with a key ID and secret access key.


##Create a new user

Copy the keys, go back to your terminal and paste the keys and its going to prompt us to create an AWS profile, so we are going to create a profile and all we need to do is give it a name and our profile will be created.


##Initializing AWS Amplify in our Vue.js project

Next, run the command on your terminal amplify init
It will prompt us to enter a name for the project, let us use the default name and it is going to ask us for our environment and we are going to choose Dev, it's going to prompt us to choose the IDE we are using, the language and framework, that is if yours is not detected automatically.
It will ask us if we want to use an AWS profile, we are going to say yes and then we choose the profile we created a few seconds ago. Hit enter and amplify CLI will initialize the project on the cloud.


##Adding chatbot assets to AWS Amplify

Once the initialization is over, we are going to add resources to the project, let us go ahead and run the command amplify add interactions and we are going to hit enter for the default and we are going to choose a sample, we will do “Order Flowers”. We will be asked if we will be targeting children with this bot, say no and the resources will be added successfully.


##Push Interaction in Vue project

We will use another command amplify push to add the interaction to our project in AWS, recall that we created a project name. After that, it will give us a summary of all the resources we have selected that will be added to the cloud and we will say yes and this will provision our chatbot on AWS.


##Amplify console

Next, use the command amplify console which will open a new web page, and on this page is where we will see all bots we have created but unfortunately, we won’t be able to access the bot from this page, we will use the search box to search amazon services. So we will search for Amazon Lex and once that is done, we should see the bot we just created.
So let’s go ahead and play around with it.

![This is our Chatbot Console](https://paper-attachments.dropbox.com/s_DFBD4AC18533C538296C378684504D1C4B9A26808667739F6C34F7483A21930A_1630926344530_aws_chatbot_console.png)


Recall that we have talked about some of these terms above but now let’s practically use them and learn more terms to get us acquainted with using the chatbot console.

 - **OrderFlowers_dev**: Name of bot

 - **Sample Utterances** (purple arrow): These are possible questions the user might ask and it does not have to be the exact word you use, the user could say something close or around that, the chatbot would be able to understand.

 - **Name** (green arrow): These are variables that will store all information provided by the user to process their request.

 - **Slot type** (red arrow): These are the data types that the variables are to store.

 - **Build & Publish**: The build button on the console builds the bot ready for testing.

 - **Prompt** (blue arrow): Prompts are questions asked by the bot after the user has triggered the bot with the first utterance.

 - **Confirmation Prompt** : This prompt collects the information of the user to see if he/she is satisfied.

 - **Fulfillment Prompt**: This is a function or business logic that processes all the data and returns the users intent, the fulfillment prompt has two sub prompts which we will get to understand below.

 - **AWS Lamda function**: This function or logic processes the user's data and gives back a response and it is mostly used when the intent of the user would need to integrate with a third party API to gather information.

 - **Return Parameter to the client**: This function just retrieves all the data inputted by the user and displays it to the user.
    
##Adding our Chatbot to our Vue Project

What we are most interested in is adding our bot to our Vue project, so let’s dive right in
To integrate this chatbot into our app, let's get some dependencies into the project by using the command `npm i AWS-amplify aws-amplify-vue` . The new folder `aws-exports.js` was added to our project.

Let's go ahead and add all necessary library to our Vue app

  
```javascript 
import Vue from 'vue'
    import App from './App.vue'
    // Import Amplify Modules, Plugins, and aws exports file
    import Amplify from "aws-amplify";
    import awsconfig from "./aws-exports";
    // Configure Amplify in project
    Amplify.configure(awsconfig);
    // Configure vue to use plugins and modules
    // Vue.use(AmplifyPlugin, AmplifyModules);
    Vue.config.productionTip = false
    new Vue({
      render: h => h(App),
    }).$mount('#app')
```
    

The code above should go into the `main.js` file

Let's go into our `app.vue` folder and do some configuration.

   ```javascript
 <template>
      <div id="app" style="max-height:300px">
        <ChatComponent :chatbotConfig="chatbotConfig" name="OrderFlowers_dev" :completed="completed"/>
      </div>
    </template>
```

Let us `v-bind` the chatbotconfig to our chat component and pass the name of the chatbot as a parameter and boolean value call completed to our chat component where we will be needing it.


   ```javascript
 import { Interactions } from "aws-amplify";
    import ChatComponent from './components/ChatComponent.vue';
    export default {
      components: { ChatComponent },
      name: "App",
      data: () => ({
        completed: null,
        chatbotConfig: {
          bot: "OrderFlowers_dev",
          clearComplete: false,
          chatBot: Interactions
        },
      }),
```

Here, we create a data entry point with where we define our bots and configs to get our bot working.
Inside the `chatbotConfig`, we call the bot name and you get the name from the AWS console.

The property `clearComplete` is set to false so that the bot does not close on completion of an order, instead it will give a response like “thank you for your order”
We will also register the interactions from the AWS-Amplify library using the ChatBot property which will help us know all the values captured by the bot.


  ```javascript
 mounted() {
        Interactions.onComplete("OrderFlowers_dev", this.handleComplete);
      },
      methods: {
        handleComplete(err, confirmation) {
          if (err) {
            alert("bot conversation failed");
            return;
          }
          this.completed = confirmation
        },
      },
```
  
The code above does error checks incase there is failure communicating with the bot.
We will also create a component that will be a user interface between our bot and the user.
You can find the full source code in my repository on github.


   ```javascript
 <template>
      <div class="hello">
        <div class="messages clearfix">
        <div v-show="messages === []"> Please enter your message </div>
          <div v-for="(msg, _) in messages" :key="_">
            <div :class="{
              'message': true, 
              'sender': msg.sender === 'user', 
              'bot': msg.sender !== 'user' 
              }">
              
              <div v-if="msg.msg.slots">
                <span><strong> FlowerType: </strong> {{msg.msg.slots.FlowerType}}</span><br />
                <span><strong> PickupDate: </strong> {{msg.msg.slots.PickupDate}}</span><br />
                <span><strong> PickupTime: </strong> {{msg.msg.slots.PickupTime}}</span><br />
              </div>
              <div v-else> <strong style="padding-right: 10px">{{date}}:</strong> {{msg.msg}} </div>
            </div>
          </div>
          
        </div>
        <div class="input-container">
          <input type="text" @keypress.enter="sendMessage" v-model="message" />
          <button @click="sendMessage"> Send </button>
        </div>
        <div class="loading" v-show="loading"> loading... </div>
      </div>
    </template>
    <script>
    export default {
      name: 'HelloWorld',
      props: {
        chatbotConfig: Object,
        name: String,
        completed: Object
      },
      computed: {
        date(){
          const d = new Date()
          return `${d.getHours()}: ${d.getMinutes()}: ${d.getSeconds()}`
        }
      },
      data(){
        return {
          message: null,
          messages: [],
          loading: false
        }
      },
      methods: {
        async sendMessage() {
          this.loading = true
          const msg = this.message
          if (!this.message) return
          this.message = ''
          this.messages.push({sender: 'user', msg })
          const response = await this.chatbotConfig.chatBot.send(this.name, msg)
          this.loading = false
          console.log(this.completed)
          if (!response.message) return;
          if (!this.completed) this.messages.push({sender: this.name, msg: response.message })
          else this.messages.push({sender: this.name, msg: this.completed })
        }
      }
    }
```
    

Let’s dive into what is happening up there

First, the chat component is created and is imported into the `app.vue` file.
The data entry point contains all variables to be used in the component.
The Message variable bears the messages that the user will send to the chatbot.
The messages variable contains both the messages of the user and the chatbot.
The loading variable is responsible for showing the loader that displays when a message is being sent to the chatbot.


   ```javascript
  data(){
        return {
          message: null,
          messages: [],
          loading: false
        }
      },
```

**NOTE**: props are used to pass data down a component (from a parent component to a child component) the props which are passed are:

 - ChatbotConfig props containing all configurations of the chatbot (the bot name, the chatbot interaction, and a boolean to show if the chatbot action is completed).

 - the computed property bears a function that returns the present time a message was sent to the chatbot.

 - The method property  bears the send message function which is responsible for sending messages from the user to the chatbot.


    
    ```javascript
 methods: {
        async sendMessage() {
          this.loading = true
          const msg = this.message
          if (!this.message) return
          this.message = ''
          this.messages.push({sender: 'user', msg })
          const response = await this.chatbotConfig.chatBot.send(this.name, msg)
          this.loading = false
          console.log(this.completed)
          if (!response.message) return;
          if (!this.completed) this.messages.push({sender: this.name, msg: response.message })
          else this.messages.push({sender: this.name, msg: this.completed })
        }
      }
```

##The flow of the chat component:

With the messages variable, the message is rendered on the component using a `v-for` directive. (the v-for directive loops through the variables of the message and renders all the messages (both from the user and the chatbot) into the component), when a user sends a message, the `sendMessage()` function is triggered.

**What the send message function does:**

The function sets the loading variable to true (this is to show that a loading indicator is shown  to indicate that the message is being sent to the chatbot). 
An if statement to check if there was a message being passed into the message variable and if there isn’t, it returns thereby stopping the process of sending a message to the chatbot, furthermore the message variable is reinitialized to an empty string to clear the message from the input box on the user interface (to give a semblance that the message has been sent and can enter a new text). 
The user and the message are added to an object which is eventually pushed to the messages variable which contains the messages for both the user and the chatbot, the message is sent to the chatbot.

The loading variable is set to false indicating that the message has been sent and it disables the loading indicator shown previously and an if statement checks if the chatbot returns a response with a message and if it doesn't, it returns and stops the process.
An if statement checks if the chatbot message is completed and pushes the message into the messages variable that holds all messages. If it doesn't, it returns and stops the process.

Furthermore, run your app and get chatting with your bot in your app, this is what your app should look like.

![This is how your conversation should turn out](https://paper-attachments.dropbox.com/s_DFBD4AC18533C538296C378684504D1C4B9A26808667739F6C34F7483A21930A_1632232137428_Screenshot+from+2021-09-21+14.47.14.png)

##Conclusion

In this article, we have looked at simple steps to add fully equipped bots to your web apps, we have also looked at how to configure and use AWS amplify console and if you have not noticed, we have also learnt cloud operations because this bot is  hosted on the cloud.
We started with very basic explanations as to how important bots are to everyday life and how it can ease stress on companies and help improve user experiences.


**Further Resources:**

- [GitHub](https://github.com/Maxiggle/awsChatbot)