Simple Chatbot Application using React.js
Tags: react, api, tutorial
Published: 2021-03-31 23:47:40

"Alexa, play willow by Taylor Swift"
"Siri, what's the weather today?"
...

All of us must have heard these lines at least once if not every day. Artificial Intelligence (AI) has played a big role in making our life easier and beyond that, safer (no more texting while driving!). I have always been curious and intrigued by the logic behind it. In my capstone project at Flatiron School, I built a recipe search called [Hipstew](https://hipstew.herokuapp.com/) | [Demo] (https://youtu.be/A7Hr_E2PJjY) which has a virtual assistant: Stewy. If you're also curious about how I built Stewy (spoiler alert: Stewy talks and understands human voice), please keep reading :). 

In this blog, I'll attempt to re-create my chatbot using React.js, but a simpler version, feel free to use this as a template and add more skill for your chatbot later on ;)!

First of all, create our react app using `create-react-app` package: 
```npx create-react-app chatbot-example```
After that, install `react-bootstrap` package (optional): 
```npm install react-bootstrap bootstrap```
Import script in your src/index.js or App.js:
```import 'bootstrap/dist/css/bootstrap.min.css'```
 

Alright! Let's create our first component `ChatBot.js` and add an input field:
```react
import React, { useState } from 'react'
import Form from 'react-bootstrap/Form'
import InputGroup from 'react-bootstrap/InputGroup'
import '../css/ChatBot.css'

export default function ChatBot(){
    const [userInput, setUserInput] = useState('')

    return (
        <div className='chatbot-card'>
            <div>
                <img 
                    className='bot-cover-photo'
                    src='https://www.userlike.com/api/proxy/resize/do-i-need-a-chatbot/header-chat-box.png?height=720' 
                    alt='chatbot-pic'
                />  
            </div>
                
            <div className='human-input'>
                <InputGroup className="mb-3">

                    <Form.Control
                        className="mb-2"
                        type="text" 
                        placeholder="Ask me something"
                        value={userInput}
                        onChange={handleChange}
                    />

                </InputGroup>
            </div>
            
        </div>
    )}
}
```

We should see a chatbot photo and an input field on DOM like this:

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ebeaf59nmk92dnc3tetf.png)

Adding the logic to handle user's input:

```javascript
  const [userInput, setUserInput] = useState('')
  const [userHistory, setUserHistory] = useState([])
  const [botHistory, setBotHistory] = useState([])
  const handleChange = (e) => setUserInput(e.target.value)
```

We added `userHistory` and `botHistory` state to keep track of user's inputs and bot's replies, in order to display them later on in the conversation.

Here is the most important part, the core of our chatbot:

```react
const matchReply = (userInput) => {
        const trigger = [
            ["hi", "hey", "hello"],
            ["how are you", "how are things", "how you doing"],
            ["what is going on", "what is up"],
            ["happy", "good", "amazing", "fantastic", "cool"],
            ["bad", "bored", "tired", "sad"],
            ["thanks", "thank you"],
            ["bye", "good bye", "goodbye"]
        ];
            
        const reply = [
            ["Hello", "Hi", "It's nice seeing you!"],
            ["I'm doing good... how are you?", "I feel kind of lonely, how are you?", "I feel happy, how are you?"],
            ["Nothing much", "Exciting things!", "I'm happy to see you!"],
            ["Glad to hear it", "Yayyy!! That's the spirit!"],
            ["There is always a rainbow after the rain!"],
            ["You're welcome", "No problem", "It's my pleasure!"],
            ["Goodbye, it was a nice talk"]
        ];
        
        const alternative = ["Same", "Go on...", "Try again please?", "I'm listening..."];

        let botMsg = generateReply(trigger, reply, userInput)

        if(!botMsg){
            botMsg = alternative[Math.floor(Math.random()*alternative.length)]
        }

        setBotHistory([botMsg, ...botHistory])

}
```

This function will help match the user's input with the right bot's response and also save those replies to chat history. You will notice there's a helper function: `generateReply` within this function. Let's implement it:

```react
const generateReply = (trigger, reply, text) => {
        let item;
        let items;
        for (let x = 0; x < trigger.length; x++) {
            for (let y = 0; y < reply.length; y++) {
                if (text.includes(trigger[x][y])) {
                    items = reply[x];
                    item = items[Math.floor(Math.random() * items.length)];
                }
            }
        }
        return item;
}
```

This function takes in 3 arguments: 
* trigger: a trigger array from matchReply function, whenever user input a sentence with one of the trigger keywords, a corresponding reply will be added.
* reply: a reply array corresponding to trigger.
* text: user's input.

Whenever a user enters a phrase contains a trigger keyword, our chatbot will respond with a corresponding reply.

I did a little CSS for this chatbot, feel free to take a look:
```css
.bot-cover-photo {
    width: 100vw;
}

.chatbot-card {
  background-color: rgba(140, 192, 247, 0.735);
}

.human-input {
    padding-left: 30vw;
    padding-right: 30vw;
    margin: 10px;
}

h3 {
    margin-bottom: 0 !important;
}

#user-input {
    background-color: rgba(132, 136, 249, 0.646);
}

#bot-reply {
    background-color: rgba(231, 228, 228, 0.687);
}

#user-input, #bot-reply {
    padding: 0.4rem;
    padding-left: 1rem;
    border-radius: 10px;
    text-align: left;
}

.conversation-box {
    padding-left: 20vw;
    padding-right: 20vw;
}

.chatbox {
    overflow-y: scroll;
    overflow-y: auto;
    height: 230px;
}
```


This would be our end result, creating a simple conversation with a chatbot:
![demo](https://media.giphy.com/media/Bb7ITvzxv9fpZFLwnx/giphy.gif)
 
Next week, I'll release another blog post about how to add more skills for our little Chatbot :). Thank you so much for making it this far! I'll see y'all later.