Ako zostaviť Chatbota s Reactom

Moja filozofia je jednoduchá. Aby ste sa v niečom stali dobrými, musíte to urobiť veľa.

Nestačí to urobiť raz. Musíte to robiť znova a znova a znova. Nikdy sa to neskončí. Rovnakú filozofiu som použil na to, aby som bol dobrý v programovaní.

Jedna vec, ktorú som si na tejto ceste všimol, je, že je oveľa zábavnejšie stavať veci, ktoré sú zaujímavé a ktoré vyzerajú dobre. Veci, ktoré vám môžu ukázať priatelia a na ktoré môžete byť hrdí. Niečo, čo vás nadchne na úvod, keď si sadnete pred klávesnicu.

Preto som postavil chatbota.

Ktoré sa zmenili na balíček NPM.

Postavme teda jeden spolu. Ak sa chcete tejto výzvy zhostiť sami, môžete prejsť priamo do dokumentácie (čo je vlastne chatbot). Alebo ak ste vizuálnym študentom, vytvoril som návod na YouTube.

Inak poďme. Budem predpokladať, že máte nainštalovaný Node a prístup k príkazu npx. Ak nie, choďte sem.

Pôvodné nastavenie

// Run these commands from your command line npx create-react-app chatbot cd chatbot yarn add react-chatbot-kit yarn start

To by malo nainštalovať balíček npm a otvoriť vývojový server na localhost: 3000.

Ďalej prejdite na App.jsa vykonajte tieto zmeny:

import Chatbot from 'react-chatbot-kit' function App() { return ( ); }

Dobrá práca. Dostávame sa tam. Toto by ste teraz mali vidieť na svojom vývojovom serveri:

Chatbot si vezme tri rekvizity, ktoré musia byť zahrnuté, aby fungoval. Najprv potrebuje konfiguráciu, ktorá musí obsahovať initialMessagesvlastnosť s objektmi správ chatbot.

Po druhé, potrebuje MessageParsertriedu, ktorá musí implementovať metódu syntaktickej analýzy.

Po tretie, potrebuje ActionProvidertriedu, ktorá bude implementovať akcie, ktoré chceme podniknúť na základe analýzy správy.

Pôjdeme do toho hlbšie neskôr. Pre túto chvíľu choďte sem, aby ste získali začiatočný kód štandardného kódu.

  • Vložte MessageParserkód do súboru s názvomMessageParser.js
  • Vložte ActionProviderkód do súboru s názvomActionProvider.js
  • Vložte konfiguračný kód do súboru s názvom config.js

Po dokončení sa vráťte k svojmu App.jssúboru a pridajte tento kód:

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 ( ); }

Toto by ste teraz mali vidieť na localhost: 3000:

Sladké. Teraz máme chatbota vykresleného na obrazovku a môžeme napísať do vstupného poľa a odoslať ho, aby sme mohli poslať správu do chatu. Keď to však skúsime, nič sa nedeje.

Pochopenie fungovania chatbotu

Tu sa musíme zastaviť v boxoch a pozrieť sa, ako interaguje MessageParsera ActionProviderinteraguje, aby náš robot vykonal akciu.

Pri inicializácii robota sa initialMessagesvlastnosť z konfigurácie uvedie do interného stavu chatbota vo vlastnosti s názvom messages, ktorá sa používa na vykreslenie správ na obrazovku.

Navyše, keď napíšeme a stlačíme tlačidlo odoslať v poli chatu, naša MessageParser(ktorú sme ako rekvizity odovzdali chatbotovi) volá svoju parsemetódu. Z tohto dôvodu musí byť táto metóda implementovaná.

Pozrime sa podrobnejšie na MessageParserštartovací kód:

class MessageParser { constructor(actionProvider) { this.actionProvider = actionProvider; } parse(message) { ... parse logic } }

Ak sa pozrieme pozorne, táto metóda je konštruovaná s actionProvider. Toto je rovnaká ActionProvidertrieda, ktorú odovzdávame ako rekvizity chatbotovi. To znamená, že kontrolujeme dve veci - to, ako sa správa analyzuje a aké kroky treba na základe tejto analýzy podniknúť.

Pomocou týchto informácií vytvoríme jednoduchú odpoveď chatbota. Najskôr upravte MessageParsertakto:

class MessageParser { constructor(actionProvider) { this.actionProvider = actionProvider; } parse(message) { const lowerCaseMessage = message.toLowerCase() if (lowerCaseMessage.includes("hello")) { this.actionProvider.greet() } } } export default MessageParser

Teraz náš MessageParserprijíma správu od používateľa a kontroluje, či obsahuje slovo „ahoj“. Ak sa to stane, zavolá greetmetódu na actionProvider.

Momentálne by to zlyhalo, pretože sme greetmetódu neimplementovali . Urobme to ďalej. Zamierte 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

Pekný. Ak teraz napíšeme „ahoj“ do poľa pre rozhovor, dostaneme to späť:

Fantastické. Teraz, keď môžeme ovládať syntaktickú analýzu správy a reakciu na akciu, skúsme urobiť niečo komplikovanejšie. Pokúsme sa vyrobiť robota, ktorý vám poskytne učebné zdroje pre programovací jazyk, ktorý požadujete.

Vytvorenie učiaceho sa robota

Najprv sa vráťme k nášmu config.jssúboru a urobme niekoľko drobných zmien:

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

Dobre, takže sme sem pridali niektoré vlastnosti a zmenili sme pôvodnú správu. Najvýznamnejšie sme dali robotovi meno a zmenili sme farbu komponentov messageboxa chatbutton.

Dobre. Teraz sa dostávame k dobrej časti.

Nielenže môžeme analyzovať správy a odpovedať používateľovi správou chatbotu, ale môžeme definovať aj vlastné komponenty React, ktoré chceme pomocou správy vykresliť. Tieto komponenty môžu byť čokoľvek, čo chceme - sú to obyčajné staré komponenty React.

Vyskúšajme to vytvorením komponentu možností, ktorý používateľa prevedie možnými možnosťami.

Najskôr definujeme komponent možností učenia:

// 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; }

Teraz, keď máme náš komponent, musíme ho zaregistrovať u nášho chatbota. Zamierte na config.jsa pridajte nasledujúce:

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) => , }, ], }

Pochopenie miniaplikácií

Dobre. Oddýchneme si a preskúmajme, čo sme urobili.

  1. Vytvorili sme LearningOptionskomponent.
  2. V widgetsnašej konfigurácii sme komponent zaregistrovali pod .
  3. Funkcii sme dali createChatbotMessageobjekt volieb, ktorý určuje, ktorý widget sa má touto správou vykresliť.

Výsledok:

Fantastické, ale prečo sme potrebovali zaregistrovať náš komponent v konfigurácii ako funkciu widgetu?

Tým, že mu dáme funkciu, kontrolujeme, kedy vykonáme vyvolanie. To nám umožňuje miestnosť zdobiť widget dôležitými vlastnosťami vnútri chatbota.

Widget, ktorý definujeme, dostane od chatbota niekoľko vlastností (niektoré z nich je možné ovládať pomocou vlastností konfigurácie):

  1. actionProvider - we give the actionProvider to the widget in order to execute actions if we need to.
  2. setState - we give the top level chatbot setState function to the widget in case we need to manipulate state.
  3. scrollIntoView - utility function to scroll to the bottom of the chat window, should we need to adjust the view.
  4. props - if we define any props in the widget config, those will be passed to the widget under the property name configProps.
  5. state - if we define custom state in the config, we can map it to the widget by using the mapStateToProps 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.

    1. 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.

    Ak sa chcete zlepšiť ako vývojár, odporúčam vám pokračovať v budovaní. Je to skutočne jediná cesta vpred. Ak sa vám tento článok páčil a chceli by ste vedieť, kedy zverejním viac obsahu, môžete ma sledovať na Twitteri.