Moja filozofija je jednostavna. Da biste u nečemu postali dobri, to morate puno učiniti.
Nije dovoljno to učiniti jednom. Morate to ponoviti, i opet i opet. Nikad neće završiti. Istu filozofiju koristio sam da bih se dobro snašao u programiranju.
Jedna stvar koju sam primijetio na ovom putovanju je da je puno zabavnije graditi stvari koje su zanimljive i koje dobro izgledaju. Stvari koje možete pokazati prijateljima i biti ponosni. Nešto što vas uzbuđuje kad započnete kad sjednete ispred tipkovnice.
Zbog toga sam izgradio chatbot.
Što se pretvorilo u npm paket.
Pa hajde da ga zajedno izgradimo. Ako se želite samostalno suočiti s tim izazovom, možete prijeći izravno u dokumentaciju (koja je zapravo chatbot). Ili, ako ste vizualni učenik, stvorio sam vodič na YouTubeu.
Inače, idemo. Pretpostavit ću da imate instaliran Node i pristup naredbi npx. Ako ne, uzmi je ovdje.
Početno postavljanje
// Run these commands from your command line npx create-react-app chatbot cd chatbot yarn add react-chatbot-kit yarn start
To bi trebalo instalirati npm paket i otvoriti razvojni poslužitelj na localhost: 3000.
Slijedi App.js
i unesite ove promjene:
import Chatbot from 'react-chatbot-kit' function App() { return ( ); }
Odličan posao. Stižemo tamo. Ovo biste sada trebali vidjeti na svom razvojnom poslužitelju:

Chatbot uzima tri rekvizita koja moraju biti uključena da bi mogao raditi. Prvo, treba konfiguraciju koja mora sadržavati initialMessages
svojstvo s objektima poruke chatbota.
Drugo, treba MessageParser
klasa koja mora implementirati metodu raščlanjivanja.
Treće, potrebna mu je ActionProvider
klasa koja će implementirati radnje koje želimo poduzeti na temelju raščlanjivanja poruke.
Kasnije ćemo dublje ući u ovo. Za sada idite ovdje da biste započeli s šifrom uzorka.
- Stavite
MessageParser
kod u datoteku pod nazivomMessageParser.js
- Stavite
ActionProvider
kod u datoteku pod nazivomActionProvider.js
- Stavite konfiguracijski kod u datoteku pod nazivom
config.js
Kad je to gotovo, vratite se u svoju App.js
datoteku i dodajte ovaj kod:
import React from 'react'; import Chatbot from 'react-chatbot-kit' import './App.css'; import ActionProvider from './ActionProvider'; import MessageParser from './MessageParser'; import config from './config'; function App() { return ( ); }
Sada biste ovo trebali vidjeti na localhost: 3000:

Slatko. Sada smo chatbot prikazali na ekranu i možemo upisati u polje za unos i poslati ga kako bismo poslali poruku u chat. Ali kad to pokušamo, ništa se ne događa.
Razumijevanje načina na koji chatbot radi
Ovdje se moramo zaustaviti i pogledati kako MessageParser
i kako ActionProvider
djeluje kako bi naš bot krenuo u akciju.
Kada se bot inicijalizira, initialMessages
svojstvo iz konfiguracije stavlja se u interno stanje chatbota u svojstvu pod nazivom messages
, koje se koristi za prikazivanje poruka na ekranu.
Štoviše, kad napišemo i pritisnemo gumb za slanje u polju za chat, naš MessageParser
(koji smo kao rekviziti proslijedili chatbotu) poziva svoju parse
metodu. Zbog toga se ova metoda mora implementirati.
Pogledajmo pobliže MessageParser
početni kod:
class MessageParser { constructor(actionProvider) { this.actionProvider = actionProvider; } parse(message) { ... parse logic } }
Ako pažljivo pogledamo, ova je metoda konstruirana s actionProvider
. To je ista ActionProvider
klasa koju predajemo chatbotu kao rekvizite. To znači da kontroliramo dvije stvari - kako se poruka raščlanjuje i koje radnje poduzimamo na temelju spomenutog raščlanjivanja.
Upotrijebimo ove podatke za stvaranje jednostavnog odgovora chatbota. Prvo izmijenite MessageParser
ovako:
class MessageParser { constructor(actionProvider) { this.actionProvider = actionProvider; } parse(message) { const lowerCaseMessage = message.toLowerCase() if (lowerCaseMessage.includes("hello")) { this.actionProvider.greet() } } } export default MessageParser
Sada mi MessageParser
primamo korisničku poruku, provjeravajući uključuje li riječ "zdravo". Ako se dogodi, poziva greet
metodu na actionProvider
.
Trenutno bi se ovo srušilo jer nismo primijenili greet
metodu. Učinimo to sljedeće. Pređite na ActionProvider.js
:
class ActionProvider { constructor(createChatBotMessage, setStateFunc) { this.createChatBotMessage = createChatBotMessage; this.setState = setStateFunc; } greet() { const greetingMessage = this.createChatBotMessage("Hi, friend.") this.updateChatbotState(greetingMessage) } updateChatbotState(message) { // NOTE: This function is set in the constructor, and is passed in // from the top level Chatbot component. The setState function here // actually manipulates the top level state of the Chatbot, so it's // important that we make sure that we preserve the previous state. this.setState(prevState => ({ ...prevState, messages: [...prevState.messages, message] })) } } export default ActionProvider
Lijepo. Sad ako upišemo "zdravo" u polje za chat, vratit ćemo ovo:

Fantastičan. Sad kad možemo kontrolirati raščlanjivanje poruke i odgovaranje akcijom, pokušajmo učiniti nešto složenijim. Pokušajmo napraviti bota koji će vam pružiti resurse za učenje programskog jezika koji tražite.
Izrada bota za učenje
Prvo se vratimo na našu config.js
datoteku i napravimo neke male promjene:
import { createChatBotMessage } from 'react-chatbot-kit'; const config = { botName: "LearningBot", initialMessages: [createChatBotMessage("Hi, I'm here to help. What do you want to learn?")], customStyles: { botMessageBox: { backgroundColor: "#376B7E", }, chatButton: { backgroundColor: "#376B7E", }, }, } export default config
U redu, ovdje smo dodali neka svojstva i promijenili početnu poruku. Najvažnije je da smo botu dali ime i promijenili boju messagebox
i chatbutton
komponenata.

U redu. Sad prelazimo na dobar dio.
Ne samo da možemo raščlaniti poruke i odgovoriti korisniku chatbotom, već možemo definirati prilagođene komponente React koje želimo prikazati uz poruku. Te komponente mogu biti sve što želimo - one su obične stare React komponente.
Isprobajmo ga stvaranjem komponente opcija koja će korisnika voditi do mogućih opcija.
Prvo definiramo komponentu mogućnosti učenja:
// in src/components/LearningOptions/LearningOptions.jsx import React from "react"; import "./LearningOptions.css"; const LearningOptions = (props) => { const options = [ { text: "Javascript", handler: () => {}, id: 1 }, { text: "Data visualization", handler: () => {}, id: 2 }, { text: "APIs", handler: () => {}, id: 3 }, { text: "Security", handler: () => {}, id: 4 }, { text: "Interview prep", handler: () => {}, id: 5 }, ]; const optionsMarkup = options.map((option) => ( {option.text} )); return {optionsMarkup} ; }; export default LearningOptions; // in src/components/LearningOptions/LearningOptions.css .learning-options-container { display: flex; align-items: flex-start; flex-wrap: wrap; } .learning-option-button { padding: 0.5rem; border-radius: 25px; background: transparent; border: 1px solid green; margin: 3px; }
Now that we have our component, we need to register it with our chatbot. Head over to config.js
and add the following:
import React from "react"; import { createChatBotMessage } from "react-chatbot-kit"; import LearningOptions from "./components/LearningOptions/LearningOptions"; const config = { initialMessages: [ createChatBotMessage("Hi, I'm here to help. What do you want to learn?", { widget: "learningOptions", }), ], ..., widgets: [ { widgetName: "learningOptions", widgetFunc: (props) => , }, ], }
Understanding widgets
Alright. Let's take a breather and explore what we've done.
- We created the
LearningOptions
component. - We registered the component under
widgets
in our config. - We gave the
createChatbotMessage
function an options object specifying which widget to render with this message.
The result:

Fantastic, but why did we need to register our component in the config as a widget function?
By giving it a function, we control when we perform the invocation. This allows us room to decorate the widget with important properties inside the chatbot.
The widget that we define will receive a number of properties from the chatbot (some of which can be controlled by config properties):
actionProvider
- we give theactionProvider
to the widget in order to execute actions if we need to.setState
- we give the top level chatbotsetState
function to the widget in case we need to manipulate state.scrollIntoView
- utility function to scroll to the bottom of the chat window, should we need to adjust the view.props
- if we define any props in the widget config, those will be passed to the widget under the property nameconfigProps
.state
- if we define custom state in the config, we can map it to the widget by using themapStateToProps
property
If you recall, we defined some options in the LearningOptions
component:
const options = [ { text: "Javascript", handler: () => {}, id: 1 }, { text: "Data visualization", handler: () => {}, id: 2 }, { text: "APIs", handler: () => {}, id: 3 }, { text: "Security", handler: () => {}, id: 4 }, { text: "Interview prep", handler: () => {}, id: 5 }, ];
Currently these have an empty handler. What we want to do now is to replace this handler by a call to the actionProvider
.
So what do we want to have happen when we execute these functions? Ideally, we'd have some sort of chatbot message, and an accompanying widget that displays a list of links to helpful resources for each topic. So let's see how we can implement that.
First, we need to create the link list component:
// in src/components/LinkList/LinkList.jsx import React from "react"; import "./LinkList.css"; const LinkList = (props) => { const linkMarkup = props.options.map((link) => ( {link.text} )); return
{linkMarkup}
; }; export default LinkList; // in src/components/LinkList/LinkList.css .link-list { padding: 0; } .link-list-item { text-align: left; font-size: 0.9rem; } .link-list-item-url { text-decoration: none; margin: 6px; display: block; color: #1d1d1d; background-color: #f1f1f1; padding: 8px; border-radius: 3px; box-shadow: 2px 2px 4px rgba(150, 149, 149, 0.4); }
Great. We now have a component that can display a list of links. Now we need to register it in in the widget section of the config:
import React from "react"; import { createChatBotMessage } from "react-chatbot-kit"; import LearningOptions from "./components/LearningOptions/LearningOptions"; import LinkList from "./components/LinkList/LinkList"; const config = { ... widgets: [ { widgetName: "learningOptions", widgetFunc: (props) => , }, { widgetName: "javascriptLinks", widgetFunc: (props) => , }, ], }; export default config;
So far so good, but we want to dynamically pass in props to this component so that we can reuse it for the other options as well. This means that we need to add another property to the widget object in the config:
import React from "react"; import { createChatBotMessage } from "react-chatbot-kit"; import LearningOptions from "./components/LearningOptions/LearningOptions"; import LinkList from "./components/LinkList/LinkList"; const config = { ..., widgets: [ ..., { widgetName: "javascriptLinks", widgetFunc: (props) => , props: { options: [ { text: "Introduction to JS", url: "//www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/", id: 1, }, { text: "Mozilla JS Guide", url: "//developer.mozilla.org/en-US/docs/Web/JavaScript/Guide", id: 2, }, { text: "Frontend Masters", url: "//frontendmasters.com", id: 3, }, ], }, }, ], }; export default config;
Now these props will be passed to the LinkList
component as props.
Now we need to do two more things.
- We need to add a method to the
actionProvider
class ActionProvider { constructor(createChatBotMessage, setStateFunc) { this.createChatBotMessage = createChatBotMessage; this.setState = setStateFunc; } handleJavascriptList = () => { const message = this.createChatBotMessage( "Fantastic, I've got the following resources for you on Javascript:", { widget: "javascriptLinks", } ); this.updateChatbotState(message); }; updateChatbotState(message) { // NOTICE: This function is set in the constructor, and is passed in from the top level Chatbot component. The setState function here actually manipulates the top level state of the Chatbot, so it's important that we make sure that we preserve the previous state. this.setState((prevState) => ({ ...prevState, messages: [...prevState.messages, message], })); } } export default ActionProvider;
2. We need to add this method as the handler in the LearningOptions
component:
import React from "react"; import "./LearningOptions.css"; const LearningOptions = (props) => { const options = [ { text: "Javascript", handler: props.actionProvider.handleJavascriptList, id: 1, }, { text: "Data visualization", handler: () => {}, id: 2 }, { text: "APIs", handler: () => {}, id: 3 }, { text: "Security", handler: () => {}, id: 4 }, { text: "Interview prep", handler: () => {}, id: 5 }, ]; const optionsMarkup = options.map((option) => ( {option.text} )); return {optionsMarkup} ; }; export default LearningOptions;
Alright! That was quite a lot of information. But if we now try to click the JavaScript option in the chatbot, we get this result:

Perfect. But we don't want to stop there, this is a chatbot after all. We want to be able to respond to users who want to use the input field as well. So we need to make a new rule in MessageParser
.
Let's update our MessageParser.js
file to look like this:
class MessageParser { constructor(actionProvider) { this.actionProvider = actionProvider; } parse(message) { const lowerCaseMessage = message.toLowerCase(); if (lowerCaseMessage.includes("hello")) { this.actionProvider.greet(); } if (lowerCaseMessage.includes("javascript")) { this.actionProvider.handleJavascriptList(); } } } export default MessageParser;
Now try typing "javascript" into the input field and sending the message. You should get the same list in response from the chatbot.
So there you have it. We've set up a chatbot that renders a list of possible options and responds to user input.
For now, we've only set up the bot to handle when someone clicks or types in JavaScript, but you can try to expand the other options on your own. Here's a link to the repository.
All the code is on GitHub, so feel free to dive into the react-chatbot-kit code or docs.
Conclusion
Building things is fun, and a great way to expand your skillset. There are no limits to where you could take this next.
Perhaps you could make a chatbot that finds the ideal product in webshop based on some simple questions (utilising routing in the app), or maybe you can make one for your company taking care of the most common customer inquiries.
Feel free to expand, come up with new ideas, and test them out. And if you see something that can be improved, send a pull request.
If you want to improve as a developer, I encourage you to keep building. It truly is the only path forward. If you enjoyed this article, and would like to know when I post more content, you can follow me on Twitter.