UI 편 ⬇️
https://bookcord.tistory.com/36
[React/Typescript] react-chatbot-kit으로 챗봇 개발하기 (UI 편)
📍 공식 문서https://fredrikoseberg.github.io/react-chatbot-kit-docs/docs/getting-started Getting Started | React-chatbot-kitStep 1: Install react-chatbot-kitfredrikoseberg.github.io 공식 문서에 나와있는대로 아래의 세 가지 단계
bookcord.tistory.com
KT wiz 웹페이지 개선 프로젝트에서, 추가할 기능으로 챗봇을 넣기로 했었다. 그런데 멘토님께서 챗봇은 api가 없기 때문에 그냥 안해도 된다고 하셨다.. 하지만 우리 팀은 이미 필수적인 개발을 다 마친 상태였어서, 내가 딱히 할 게 없었기 때문에 최소한의 기능만 넣어서 개발하는 걸 도전해봤다.
공식 문서를 보면서 개발했다.
https://fredrikoseberg.github.io/react-chatbot-kit-docs/docs/create-a-response
Create your first response | React-chatbot-kit
The chatbot should now be operational, but supplying a message through the input field will not
fredrikoseberg.github.io
멘토님이 처음에 요구사항으로 주셨던 기본적인 기능은, 사용자가 어떤 단어를 입력하면 해당하는 메뉴로 연결되게 하는 것이였다.
그래서 티켓 구매 메세지에만 대응할 수 있도록 구성해보았다.
사용자의 메세지를 분석하는 건 MessageParser.tsx 에서 수행한다.
내가 분석하고 싶은 사용자의 메세지는 티켓을 구매하고 싶은 경우이다. 다음의 경우를 생각해봤다.
/* MessageParser 내부 */
const parse = (message: string): void => {
if (message.trim().includes('티켓')) {
if (message.trim().includes('사') || message.trim().includes('구매'))
actions.handleTicketPurchase();
} else {
actions.handleUnknownMessage();
}
};
해당 메세지에 handleTicketPurchase()라는 동작을 수행하도록 설정했다.
그 외의 메세지에는 handleUnknownMessage()를 수행하도록 했다.
이 동작은 ActionProvider.tsx 에서 설정할 수 있다.
* 타입스크립트를 사용 중이므로, 사용할 타입을 상단에 지정하는 것에 유의해야한다.
interface ActionProviderProps {
createChatBotMessage: (
message: string,
options?: Record<string, unknown>
) => unknown;
setState: React.Dispatch<React.SetStateAction<unknown>>;
children: React.ReactNode;
}
interface BotMessage {
message: string;
[key: string]: unknown;
}
interface State {
messages: BotMessage[];
[key: string]: unknown;
}
/* ActionProvider 내부 */
const nav = useNavigate();
const handleTicketPurchase = () => {
const botMessage = createChatBotMessage('티켓 구매 옵션을 선택해주세요', {
widget: 'ticketPurchaseOptions',
});
setState((prev: State) => ({
...prev,
messages: [...prev.messages, botMessage],
}));
};
const handleClickHomepage = () => {
nav('/ticket/reservation');
};
const handleClickTicketLink = () => {
window.open('https://www.ticketlink.co.kr/sports/137/62', '_blank');
};
const handleUnknownMessage = () => {
const botMessage = createChatBotMessage(
'죄송해요. 무슨 말씀이신지 잘 모르겠어요.🥺'
);
setState((prev: State) => ({
...prev,
messages: [...prev.messages, botMessage],
}));
};
//return 문에 해당 함수 등록
return (
<div>
{React.Children.map(children, (child) => {
if (React.isValidElement(child)) {
return React.cloneElement(child as ReactElement, {
actions: { handleTicketPurchase, handleUnknownMessage, handleClickHomepage,
handleClickTicketLink },
});
}
return child;
})}
</div>
);
사용자가 티켓 구매 옵션을 선택할 수 있도록 두 개의 위젯 버튼을 띄운다. 각 버튼의 동작은 handleClickHomepage(), handleClickTicketLink() 이다.
이제 위젯에 해당 함수를 onClick 이벤트핸들러로 등록한다. 위젯 또한 헤더를 만들었을 때처럼 커스텀으로 만들고 config에 넣었다.
/* WidgetButton.tsx */
import { Button } from '@/components/ui';
export interface WidgetButtonProps {
actionProvider: {
handleClickHomepage: () => void;
handleClickTicketLink: () => void;
};
}
function WidgetButton(props: WidgetButtonProps) {
return (
<div className="flex gap-2">
<Button
onClick={() => props.actionProvider.handleClickHomepage()}
className="hover:bg-wiz-red border-wiz-black border-2 border-solid"
>
KT 홈페이지 예매
</Button>
<Button
onClick={() => props.actionProvider.handleClickTicketLink()}
className="hover:bg-wiz-red border-wiz-black border-2 border-solid"
>
티켓링크 예매
</Button>
</div>
);
}
export default WidgetButton;
/* config.ts */
import React from 'react';
import { createChatBotMessage } from 'react-chatbot-kit';
import Header from './Header';
import WidgetButton, { WidgetButtonProps } from './WidgetButton';
import WizAvatar from './WizAvatar';
const config = {
initialMessages: [
createChatBotMessage('안녕하세요! 궁금한 내용을 입력해주세요.', {
delay: 500,
widget: 'firstButtons',
}),
],
widgets: [
{
widgetName: 'ticketPurchaseOptions',
widgetFunc: (props: WidgetButtonProps) =>
React.createElement(WidgetButton, props),
props: {},
mapStateToProps: [],
},
],
customComponents: {
header: () => React.createElement(Header),
botAvatar: () => React.createElement(WizAvatar),
},
};
export default config;
<결과>
KT 홈페이지 예매 버튼을 누르면 홈페이지 내에 해당 페이지로 이동하고, 티켓링크 예매 버튼을 누르면 티켓링크의 KT wiz 경기 예매 페이지 탭이 열린다.
어렵다고 생각했지만 도전해보길 잘한 것 같다. 다음 번에 챗봇을 중점적으로 구현해야할 때 더 풍부하게 구현할 수 있을 것 같다.
'React' 카테고리의 다른 글
[React/Typescript] react-chatbot-kit으로 챗봇 개발하기 1 (UI 편) (0) | 2025.01.28 |
---|---|
[React] 카카오 로그인 구현하기 (with Supabase) (1) | 2025.01.25 |
[React] axios에서 React-Query로 리팩토링하기 (0) | 2025.01.09 |
[Error] Already included file name '파일경로' differs from file name '파일경로' only in casing. (1) | 2024.12.22 |
[React/트러블슈팅] filter 메서드로 검색 기능을 구현할 때 생긴 오류 해결 (1) | 2024.12.20 |