Kim Nguyen
Posted on March 31, 2021
"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>
)}
}
We should see a chatbot photo and an input field on DOM like this:
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)
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])
}
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;
}
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;
}
This would be our end result, creating a simple conversation with a chatbot:
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.
Posted on March 31, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.