Chatbotin rakentaminen React-sovelluksella

Minun filosofiani on yksinkertainen. Jos haluat tulla hyväksi jossakin, sinun on tehtävä se paljon.

Se ei riitä tekemään se kerran. Sinun on tehtävä se uudestaan ​​ja uudestaan ​​ja uudestaan. Se ei koskaan lopu. Käytin samaa filosofiaa saadakseni hyvän ohjelmoinnin.

Yksi asia, jonka olen huomannut tällä matkalla, on se, että on paljon hauskempaa rakentaa mielenkiintoisia ja hyvältä näyttäviä asioita. Asiat, joita voit näyttää ystävillesi ja joista voit olla ylpeä. Jotain, mikä saa sinut innostumaan aloittamisesta, kun istut alas näppäimistön eteen.

Siksi rakensin chatbotin.

Mikä muuttui npm-paketiksi.

Joten rakennetaan yksi yhdessä. Jos haluat vastata tähän haasteeseen itse, voit siirtyä suoraan dokumentaatioon (joka on oikeastaan ​​chatbot). Tai jos olet visuaalinen oppija, loin opetusohjelman YouTubeen.

Muuten, mennään. Oletan, että sinulla on solmu asennettuna, ja pääsyn npx-komentoon. Jos ei, mene hakemaan se täältä.

Alkuasennus

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

Tämän pitäisi asentaa npm-paketti ja avata kehityspalvelin osoitteessa localhost: 3000.

Seuraava App.jsja tee nämä muutokset:

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

Hyvää työtä. Olemme menossa sinne. Tämän pitäisi näkyä kehityspalvelimessasi nyt:

Chatbotilla on kolme rekvisiittaa, jotka on sisällytettävä toimimaan. Ensinnäkin se tarvitsee kokoonpanon, jonka on sisällettävä initialMessagesominaisuus, jossa on chatbot-viestiobjekteja.

Toiseksi se tarvitsee MessageParserluokan, jonka on toteutettava jäsennysmenetelmä.

Kolmanneksi se tarvitsee ActionProviderluokan, joka toteuttaa toimet, jotka haluamme toteuttaa viestin jäsentämisen perusteella.

Menemme syvemmälle tähän myöhemmin. Siirry toistaiseksi tänne saadaksesi kattilakoodi aloittaaksesi.

  • Lisää MessageParserkoodi tiedostoon nimeltäMessageParser.js
  • Lisää ActionProviderkoodi tiedostoon nimeltäActionProvider.js
  • Laita määrityskoodi tiedostoon nimeltä config.js

Kun se on valmis, palaa App.jstiedostoon ja lisää tämä koodi:

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

Sinun pitäisi nyt nähdä tämä osoitteessa localhost: 3000:

Makea. Nyt chatbot on renderöity ruudulle ja voimme kirjoittaa syöttökenttään ja lähettää sen lähettämään viestin keskusteluun. Mutta kun yritämme sitä, mitään ei tapahdu.

Chatbotin toiminnan ymmärtäminen

Täällä meidän on pidettävä pysähdyspaikka ja katsottava miten MessageParserja ActionProvidervuorovaikutuksessa, jotta botimme toimisi.

Kun botti alustetaan, initialMessageskonfiguraation ominaisuus laitetaan chatbotin sisäiseen tilaan nimellisessä ominaisuudessa messages, jota käytetään viestien näyttämiseen näytöllä.

Lisäksi kun kirjoitamme ja MessageParserpainamme Lähetä-painiketta chat-kentässä, meidän (jonka välitimme rekvisiittaa chatbotille) kutsuu sen parsemenetelmää. Siksi tämä menetelmä on toteutettava.

Katsotaanpa tarkemmin MessageParseraloituskoodia:

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

Jos katsomme tarkkaan, tämä menetelmä rakennetaan actionProvider. Tämä on sama ActionProviderluokka, jonka välitämme rekvisiittaa chatbotille. Tämä tarkoittaa sitä, että hallitsemme kahta asiaa - miten viesti jäsennetään ja mitä toimia suoritetaan mainitun jäsentämisen perusteella.

Käytetään näitä tietoja yksinkertaisen chatbot-vastauksen luomiseen. Muuta ensin MessageParsernäin:

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

Nyt MessageParsersaa käyttäjä viestin, tarkistetaan, onko se sisältää sanan "hei". Jos näin tapahtuu, se kutsuu greetmenetelmää actionProvider.

Juuri nyt tämä kaatuisi, koska emme ole ottaneet greetmenetelmää käyttöön. Tehdään se seuraavaksi. Suuntaa 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

Kiva. Jos kirjoitamme "hei" chat-kenttään, saamme tämän takaisin:

Fantastinen. Nyt kun voimme hallita viestin jäsentämistä ja vastaamista toiminnolla, yritetään tehdä jotain monimutkaisempaa. Yritetään tehdä botti, joka tarjoaa sinulle oppimisresursseja haluamallesi ohjelmointikielelle.

Oppibotin luominen

Palataan ensin config.jstiedostoon ja tehdään pieniä muutoksia:

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

OK, joten olemme lisänneet joitain ominaisuuksia tähän ja muuttaneet alkuperäistä viestiämme. Selkeimmin olemme antaneet botti nimi ja muuttanut väriä messageboxja chatbuttonkomponentteja.

Hyvä on. Nyt olemme pääsemässä hyvään osaan.

Sen lisäksi, että voimme jäsentää viestejä ja vastata käyttäjälle chatbot-viestillä, voimme määrittää mukautetut React-komponentit, jotka haluamme renderoida viestin kanssa. Nämä komponentit voivat olla mitä tahansa haluamiamme - ne ovat vain vanhoja React-komponentteja.

Kokeillaan sitä luomalla vaihtoehtokomponentti, joka opastaa käyttäjän mahdollisiin vaihtoehtoihin.

Ensin määritellään oppimisvaihtoehtojen komponentti:

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

Nyt kun meillä on komponenttimme, meidän on rekisteröitävä se chatbotillemme. Mene config.jsja lisää seuraava:

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

Widgetien ymmärtäminen

Hyvä on. Otetaan hengähdystauko ja tutkitaan, mitä olemme tehneet.

  1. Olemme luoneet LearningOptionskomponentin.
  2. Rekisteröimme komponentin widgetskonfiguraatiossamme.
  3. Annoimme createChatbotMessagefunktiolle vaihtoehtoobjektin, joka määrittää, mikä widget hahmonnetaan tällä viestillä.

Lopputulos:

Fantastinen, mutta miksi meidän piti rekisteröidä komponenttimme configissa widget-funktioksi?

Antamalla sille toiminnon hallitsemme, milloin suoritamme kutsun. Tämä antaa meille tilaa sisustaa widget tärkeillä ominaisuuksilla chatbotin sisällä.

Määrittelemämme widget saa chatbotilta useita ominaisuuksia (joitain niistä voidaan hallita määritysominaisuuksilla):

  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.

    Jos haluat kehittyä kehittäjänä, kehotan sinua jatkamaan rakentamista. Se on todellakin ainoa tie eteenpäin. Jos pidit tästä artikkelista ja haluat tietää, kun lähetän enemmän sisältöä, voit seurata minua Twitterissä.