프로젝트 회고록 - 2 chat-GPT를 활용한 대화구현

RumbleBi·2023년 5월 14일
0

로맨스가필요해

목록 보기
2/6

채팅창 구현하기

프로젝트에서 chat-GPT 기능을 활용하여 채팅형식의 심리상담을 받을 수 있는 기능을 구현하였다. 여기서 적용한 내용과 개선해야 될 점에 대해서 정리하였다.

UI UX를 고려한 채팅 페이지

UI는 카카오톡과 같은 채팅페이지를 비슷하게 벤치마킹하여 구성하였다. 여기서 자신의 고민을 작성 후, UX를 고려하여 Enter 또는 전송 버튼을 누르게 되면 메세지가 전송이 된다.

서버에 텍스트를 전송하고 chat-GPT와 연동된 백엔드에서 대답을 생성한 뒤 답장을 보내주는 형식이다.

답변을 받는 시간이 짧으면 3초 길면 10초 정도로 시간이 소요되기 때문에 mask를 사용하여 답변을 받기 전까지는 질문을 할 수 없도록 UI를 구성하였다. 또한 사용자가 진행중임을 알 수 있도록 . .. ... 을 반복시켜 진행상황에 문제가 없음을 UX적인 부분도 고려하였다.

아래는 구현한 코드의 일부분이다.

// components/units/chatGPT/ChatGPT.container.tsx

// loading 이거나 빈 문자열을 보낼경우 early return 시켰다.
const submitKeyPressUserText = (e: KeyboardEvent<HTMLInputElement>) => {
    if (loading) {
      return;
    }
    if (userText === "") {
      return;
    }
    if (e.charCode == 13) {
      submitUserText();
    }
  };

// 메세지 저장방식은 하나의 배열에서 관리하여 기존 배열의 값을 복사하고, 새로운 값을 추가하는 형식으로 구성하였다.
  const submitUserText = async () => {
    setMessageList((prevText) => [...prevText, userText]);
    setUserText("");
    setLoading(true);

    try {
      const response = await postUserQuestion({ accessToken, text: userText });
      setMessageList((prevText) => [...prevText, response]);
    } catch (error) {
      setMessageList((prevText) => [
        ...prevText,
        "통신에 에러가 발생했습니다. 나중에 다시 시도해 주세요.",
      ]);
      throw error;
    } finally {
      setLoading(false);
    }
  };

// components/units/chatGPT/ChatGPT.presenter.tsx

import { ExclamationCircleFilled, SendOutlined } from "@ant-design/icons";
import * as S from "./ChatGPT.styles";
import ScrollToBottom from "react-scroll-to-bottom";
import { IChatGPTProps } from "./ChatGPT.types";

export default function ChatGPTUI({
  userText,
  handleChangeUserText,
  submitUserText,
  messageList,
  loading,
  submitKeyPressUserText,
}: IChatGPTProps) {
  return (
    <>
      <S.Position>
        <S.Wrapper>
          {loading && (		// post요청시 true로 변경되어 마스크 적용
            <S.LodingWrapper>
              <S.LoadingNotice></S.LoadingNotice>
            </S.LodingWrapper>
          )}
          <S.TitleWrapper>
            <S.Title>당신의 고민을 들려주세요</S.Title>
            <S.Notice>
              <ExclamationCircleFilled
                style={{ color: "#fff", fontSize: "1.5rem" }}
              />
              <div>
                개인정보 보호를 위해 채팅 내용은 저장되지 않습니다. 채팅 창을
                나가면 대화 내용이 사라집니다.
              </div>
            </S.Notice>
          </S.TitleWrapper>
          <S.ChatBody>
            <ScrollToBottom mode="bottom">
              <S.ChatWrapper>
                // 메세지 리스트는 하나의 배열로 관리되며, 짝수일 경우 유저가 작성한 채팅이며
                // 홀수일 경우 chat-GPT가 답변한 채팅으로 구성하였다. 
                {messageList?.map((text: string, index: number) => {
                  return (
                    <>
                      {index % 2 === 0 ? (
                        <S.WrapperMessageUser key={index}>
                          <S.MessageUser>{text}</S.MessageUser>
                        </S.WrapperMessageUser>
                      ) : (
                        <S.WrapperMessageGPT key={index}>
                          <S.MessageGPT>{text}</S.MessageGPT>
                        </S.WrapperMessageGPT>
                      )}
                    </>
                  );
                })}
              </S.ChatWrapper>
            </ScrollToBottom>
          </S.ChatBody>
          <S.WrapperInput>
            <S.TextInput
              value={userText}
              type="text"
              placeholder="고민을 말해주세요!"
              onChange={handleChangeUserText}
              onKeyPress={submitKeyPressUserText}
            />
            <S.SendBtn
              onClick={submitUserText}
              disabled={loading ? true : false}
            >
              <SendOutlined />
            </S.SendBtn>
          </S.WrapperInput>
        </S.Wrapper>
      </S.Position>
    </>
  );
}

성공적으로 받아와진 모습이다. 만약 무언가의 문제로 인해 답변이 정상적으로 받아지지 않는다면 통신에 에러가 발생했습니다. 나중에 다시 시도해 주세요. 라는 에러 메세지를 답변을 보여주게 된다.

개선이 필요한 점

react-scroll-to-bottom 이라는 라이브러리를 활용하여 이전 경험으로 채팅창 페이지 구현을 할 때, 채팅의 양이 많아지면 카카오톡과 같이 가장 최신 대화가 밑으로 보이도록 자동으로 스크롤이 되었지만 이상하게도 이번 프로젝트에서는 적용이 되지 않았다. 원인은 라이브러리가 height의 값을 인지하지 못해 요소가 overflow되어도 움직이지 않는 것 같은데.. 아직 해결중인 문제이다.

이러한 부분은 UX관점에서 대화가 길어지면 매번 답장을 확인할 때 스크롤해서 확인해야 되기 때문에 문제가 있음이 분명하다. 이러한 불편함이나 버그에 대해서 찾고 개선해서 더 나은 개발자가 되기 위해 노력하고 있다.

https://www.npmjs.com/package/react-scroll-to-bottom

profile
기억보다는 기록하는 개발자

0개의 댓글

Powered by GraphCDN, the GraphQL CDN