오늘의 한 일
1. Chatbot(챗봇) 관련 학습
1. Chatbot(챗봇) 관련 학습 - 프론트엔드 구현
1. 기본적인 템플렛 박스 만들기 - App.js
import React from "react";
import { Typography, Icon } from 'antd';
import Chatbot from './Chatbot/ChatbotClone';
const { Title } = Typography;
function App() {
return (
<div>
<div style={{ display: 'flex', justifyContent: 'center', marginTop: '2rem' }}>
<Title level={2} >CHAT BOT APP <Icon type="robot" /></Title>
</div>
<div style={{ display: 'flex', justifyContent: 'center' }}>
<Chatbot />
</div>
</div>
)
}
export default App
여기서 중요한 점은 Chatbot은 따로 파일을 만들어서 기능을 구현합니다.
2. Chatbot 구현
챗봇과 대화를 할 수 있는 대화창을 만드는 코드입니다.
import React from 'react';
function Chatbot() {
const keyPressHendler = (e) => {
if(e.key === "Enter") {
if(!e.target.value) {
return alert('메세지를 입력해주세요')
}
//request 로 메세지 전달.
// textQuery(e.target.value)
e.target.value=""
}
}
return (
<div style={{height: 700, width: 700, border: '3px solid black', borderRadius: '7px'}}>
<div style={{height: 644, width: '100%', overflow: 'auto'}}>
</div>
<input
style={{margin: 0, width: '100%', height: 50, borderRadius: '4px', padding: '5px', fontSize: ''}}
placeholder="여기에 입력해주세요..."
onKeyPress={keyPressHendler}
type="text"
/>
</div>
)
}
export default Chatbot;
3. 메세지를 보내고 답장 받기
여기서부터 이제 백엔드와 통신하여 메세지를 보내고 그에 해당하는 답변을 받습니다.
위에 주석 처리된 textQuery 함수를 만들고 사용합니다.
const textQuery = async (text) => {
const conversations = []
//우선은 받은 메세지를 화면에 나타내어 처리합니다.
let conversation = {
who: 'user',
content: {
//아래와 같은 형태를 한 이유는 dialogflow에서 보내는 res와 형태를 일치하기 위함입니다.
text: {
text: text
}
}
}
//conversations.push(conversation)
console.log(conversation)
const textQueryVariables = {
text
}
//그 다음은 메세지를 전달하고 챗봇을 통해 돌려받은 답변을 나타냅니다.
try {
// textQuery Route에 req를 보냄.
const response = await Axios.post('/api/dialogflow/textQuery', textQueryVariables)
const content = response.data.fulfillmentMessages[0]
conversation = {
who: 'bot',
content: content
}
// conversations.push(conversation)
console.log(conversation)
} catch (err) {
conversation = {
who: 'bot',
content: {
text: {
text: "잘못된 메세지입니다. 다시 작성해주세요."
}
}
}
// conversations.push(conversation)
console.log(conversation)
}
}
완성된 conversation을 랜더링을 해야하지만 인프런 강의가 여기서 리덕스를 활용하여 값을 처리할 예정이므로 우선 기본적인 형태까지 완성된 함수입니다. 리덕스 활용은 현재 conversations라는 배열을 만들었는데 이거 대신 리덕스를 사용한다는 말입니다.
4. 유저가 들어왔을 때 인사말 건네는 eventQuery 함수
메세지를 보내지 않아도 유저가 채팅방에 입장할 때 인사말을 건네는 함수를 작성해보려고 합니다.
const eventQuery = async (event) => {
//이벤트쿼리에서는 챗봇으로부터 받은 메세지만 나타내면 됩니다.
const eventQueryVariables = {
event
}
try {
// textQuery Route에 req를 보냄.
const response = await Axios.post('/api/dialogflow/eventQuery', eventQueryVariables)
const content = response.data.fulfillmentMessages[0]
let conversation = {
who: 'bot',
content: content
}
// conversations.push(conversation)
console.log(conversation)
} catch (err) {
let conversation = {
who: 'bot',
content: {
text: {
text: "잘못된 메세지입니다. 다시 작성해주세요."
}
}
}
// conversations.push(conversation)
console.log(conversation)
}
}
보시면 textQuery와의 차이점이 거의 없습니다. 저희가 메세지를 안보내니깐 그 부분은 지워주시고 밑에 몇몇 textQuery를 eventQuery라고 변경만 해주시면 됩니다.
5. 메세지 데이터를 리덕스로 관리하기
앞의 메세지 데이터를 담고 있는 conversation을 이제 리덕스를 통해 관리해보려고 합니다.
강의 소스코드에서 이미 기본적인 미들웨어나 리덕스 관련된 데이터처리를 다 해놓아서 그 부분을 우선 봅시다.
우선 index.js 파일의 코드입니다.
import React from "react";
import ReactDOM from "react-dom";
import './index.css';
import "antd/dist/antd.css";
import App from "./App";
import Reducer from './_reducers';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import promiseMiddleware from 'redux-promise';
import ReduxThunk from 'redux-thunk';
import { BrowserRouter } from "react-router-dom";
import * as serviceWorker from "./serviceWorker";
const createStoreWithMiddleware = applyMiddleware(promiseMiddleware, ReduxThunk)(createStore);
ReactDOM.render(
<Provider
store={createStoreWithMiddleware(
Reducer,
window.__REDUX_DEVTOOLS_EXTENSION__ &&
window.__REDUX_DEVTOOLS_EXTENSION__()
)}
>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>
,
document.getElementById("root")
);
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
이 밖에도 리덕스 관련 파일과 코드가 많습니다. 하지만 다 이해하기 힘들어 글을 작성하기 어렵습니다.
리덕스 관련 학습은 추후에 보충하여 그 때 열심히 작성해야겠습니다.
최종적으로 완성된 코드만 보여드리고 이상 마치겠습니다.
import React, { useEffect } from 'react';
import Axios from 'axios';
import { useDispatch, useSelector } from 'react-redux'
import { saveMessage } from '../_actions/message_actions';
function Chatbot() {
const dispatch = useDispatch();
useEffect(() => {
eventQuery('WelcomeToMyWebsite')
},[])
const textQuery = async (text) => {
//우선은 받은 메세지를 화면에 나타내어 처리합니다.
let conversation = {
who: 'user',
content: {
//아래와 같은 형태를 한 이유는 dialogflow에서 보내는 res와 형태를 일치하기 위함입니다.
text: {
text: text
}
}
}
dispatch(saveMessage(conversation))
console.log("내가 보낸거",conversation)
const textQueryVariables = {
text
}
//그 다음은 메세지를 전달하고 챗봇을 통해 돌려받은 답변을 나타냅니다.
try {
// textQuery Route에 req를 보냄.
const response = await Axios.post('/api/dialogflow/textQuery', textQueryVariables)
const content = response.data.fulfillmentMessages[0]
conversation = {
who: 'bot',
content: content
}
console.log(conversation)
dispatch(saveMessage(conversation))
} catch (err) {
conversation = {
who: 'bot',
content: {
text: {
text: "잘못된 메세지입니다. 다시 작성해주세요."
}
}
}
console.log(conversation)
dispatch(saveMessage(conversation))
}
}
const eventQuery = async (event) => {
//이벤트쿼리에서는 챗봇으로부터 받은 메세지만 나타내면 됩니다.
const eventQueryVariables = {
event
}
try {
// textQuery Route에 req를 보냄.
const response = await Axios.post('/api/dialogflow/eventQuery', eventQueryVariables)
const content = response.data.fulfillmentMessages[0]
let conversation = {
who: 'bot',
content: content
}
// conversations.push(conversation)
dispatch(saveMessage(conversation))
console.log(conversation)
} catch (err) {
let conversation = {
who: 'bot',
content: {
text: {
text: "잘못된 메세지입니다. 다시 작성해주세요."
}
}
}
// conversations.push(conversation)
dispatch(saveMessage(conversation))
console.log(conversation)
}
}
const keyPressHendler = (e) => {
if(e.key === "Enter") {
if(!e.target.value) {
return alert('메세지를 입력해주세요')
}
//request 로 메세지 전달.
textQuery(e.target.value)
e.target.value=""
}
}
return (
<div style={{height: 700, width: 700, border: '3px solid black', borderRadius: '7px'}}>
<div style={{height: 644, width: '100%', overflow: 'auto'}}>
</div>
<input
style={{margin: 0, width: '100%', height: 50, borderRadius: '4px', padding: '5px', fontSize: ''}}
placeholder="여기에 입력해주세요..."
onKeyPress={keyPressHendler}
type="text"
/>
</div>
)
}
export default Chatbot;
여기까지해서 채팅창에는 아직 메세지들이 보여지지 않지만 Console.log 에서 확인하면 데이터가 제대로 오고가는 모습을 확인할 수 있습니다. 물론 리덕스를 통해서 말이죠~! 내일은 마지막으로 실제로 채팅 메세지를 랜더링 하는 코드를 작성해보겠습니다. 내일까지하면 강의를 완강하네요ㅎㅎ 수고하셨습니다.
강의 영상은 여기 있으니 참고하세요.
따라하며 배우는 노드, 리액트 시리즈 - 챗봇 사이트 만들기 - 인프런
이 강의를 통해서 Google에서 제공하는 API를 사용해서 챗봇을 만들어 볼 수 있습니다. 초급 웹 개발 프레임워크 및 라이브러리 React Node.js 웹 개발 서비스 개발 온라인 강의 구글 API를 활용한 챗봇
www.inflearn.com
'TIL (Today I learn)' 카테고리의 다른 글
12월 01일 (화)_입사 2일차 (Chatbot 챗봇, Semantic ui) (0) | 2020.12.01 |
---|---|
10월 20일 (화)_Final Project - 03 (state 비동기 처리) (0) | 2020.10.20 |
10월 13일 (화)_Final Project - 02 (React Native) (2) | 2020.10.13 |
10월 7일 (수)_Final Project - 01 (끝과 시작) (2) | 2020.10.07 |
9월 29일 (화)_First Project - 07 (passport) (0) | 2020.09.29 |