Simple Chatbot Application using React.js

kimmese

Kim Nguyen

Posted on March 31, 2021

Simple Chatbot Application using React.js

"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 | Demo 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:

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>
    )}
}
Enter fullscreen mode Exit fullscreen mode

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

image

Adding the logic to handle user's input:

  const [userInput, setUserInput] = useState('')
  const [userHistory, setUserHistory] = useState([])
  const [botHistory, setBotHistory] = useState([])
  const handleChange = (e) => setUserInput(e.target.value)
Enter fullscreen mode Exit fullscreen mode

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:

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])

}
Enter fullscreen mode Exit fullscreen mode

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:

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;
}
Enter fullscreen mode Exit fullscreen mode

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:

.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;
}
Enter fullscreen mode Exit fullscreen mode

This would be our end result, creating a simple conversation with a chatbot:
demo

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.

💖 💪 🙅 🚩
kimmese
Kim Nguyen

Posted on March 31, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related