반응형
HTML, CSS, JavaScript를 사용하여 AI 챗봇을 빌드하기 위한 전체 소스 코드 입니다.^^
index.html
<!DOCTYPE html>
<html lang="ko" dir="ltr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Chatbot in JavaScript | xpx.kr</title>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@48,400,0,0" />
<link rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@48,400,1,0" />
<script src="script.js" defer></script>
</head>
<body>
<button class="chatbot-toggler">
<span class="material-symbols-rounded">mode_comment</span>
<span class="material-symbols-outlined">close</span>
</button>
<div class="chatbot">
<header>
<h2>Chatbot</h2>
<span class="close-btn material-symbols-outlined">close</span>
</header>
<ul class="chatbox">
<li class="chat incoming">
<span class="material-symbols-outlined">smart_toy</span>
<p>Hi there 👋<br>How can I help you today?</p>
</li>
</ul>
<div class="chat-input">
<textarea placeholder="Enter a message..." spellcheck="false" required></textarea>
<span id="send-btn" class="material-symbols-rounded">send</span>
</div>
</div>
</body>
</html>
script.js
const chatbotToggler = document.querySelector(".chatbot-toggler");
const closeBtn = document.querySelector(".close-btn");
const chatbox = document.querySelector(".chatbox");
const chatInput = document.querySelector(".chat-input textarea");
const sendChatBtn = document.querySelector(".chat-input span");
let userMessage = null; // 사용자의 메시지를 저장하는 변수
const inputInitHeight = chatInput.scrollHeight;
// API 구성
const API_KEY = "MY API 키"; // https://aistudio.google.com/app/apikey 에서 생성한 API 키
const API_URL = `https://generativelanguage.googleapis.com/v1/models/gemini-pro:generateContent?key=${API_KEY}`;
const createChatLi = (message, className) => {
//전달된 메시지와 클래스 이름으로 채팅 <li> 요소를 만듭니다.
const chatLi = document.createElement("li");
chatLi.classList.add("chat", `${className}`);
let chatContent = className === "outgoing" ? `<p></p>` : `<span class="material-symbols-outlined">smart_toy</span><p></p>`;
chatLi.innerHTML = chatContent;
chatLi.querySelector("p").textContent = message;
return chatLi; // 채팅 <li> 요소로 돌아가기
}
const generateResponse = async (chatElement) => {
const messageElement = chatElement.querySelector("p");
//API 요청에 대한 속성 및 메시지를 정의합니다.
const requestOptions = {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
contents: [{
role: "user",
parts: [{ text: userMessage }]
}]
}),
}
// API에 POST 요청을 보내고 응답을 받고 응답을 문단 텍스트로 설정합니다.
try {
const response = await fetch(API_URL, requestOptions);
const data = await response.json();
if (!response.ok) throw new Error(data.error.message);
// API 응답 텍스트를 가져오고 메시지 요소를 업데이트합니다.
messageElement.textContent = data.candidates[0].content.parts[0].text.replace(/\*\*(.*?)\*\*/g, '$1');
} catch (error) {
//오류 처리
messageElement.classList.add("error");
messageElement.textContent = error.message;
} finally {
chatbox.scrollTo(0, chatbox.scrollHeight);
}
}
const handleChat = () => {
userMessage = chatInput.value.trim(); // 사용자가 입력한 메시지를 가져오고 불필요한 공백을 제거합니다.
if (!userMessage) return;
// 입력 텍스트 영역을 지우고 높이를 기본값으로 설정합니다.
chatInput.value = "";
chatInput.style.height = `${inputInitHeight}px`;
//사용자의 메시지를 채팅 상자에 추가합니다.
chatbox.appendChild(createChatLi(userMessage, "outgoing"));
chatbox.scrollTo(0, chatbox.scrollHeight);
setTimeout(() => {
// 응답을 기다리는 동안 "생각 중..." 메시지를 표시합니다.
const incomingChatLi = createChatLi("생각중...", "incoming");
chatbox.appendChild(incomingChatLi);
chatbox.scrollTo(0, chatbox.scrollHeight);
generateResponse(incomingChatLi);
}, 600);
}
chatInput.addEventListener("input", () => {
// 입력 텍스트 영역의 높이를 내용에 따라 조정합니다.
chatInput.style.height = `${inputInitHeight}px`;
chatInput.style.height = `${chatInput.scrollHeight}px`;
});
chatInput.addEventListener("keydown", (e) => {
if (e.key === "Enter" && !e.shiftKey && window.innerWidth > 800) {
e.preventDefault();
handleChat();
}
});
sendChatBtn.addEventListener("click", handleChat);
closeBtn.addEventListener("click", () => document.body.classList.remove("show-chatbot"));
chatbotToggler.addEventListener("click", () => document.body.classList.toggle("show-chatbot"));
style.css
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: "Poppins", sans-serif;
}
body {
background: #E3F2FD;
}
.chatbot-toggler {
position: fixed;
bottom: 30px;
right: 35px;
outline: none;
border: none;
height: 50px;
width: 50px;
display: flex;
cursor: pointer;
align-items: center;
justify-content: center;
border-radius: 50%;
background: #724ae8;
transition: all 0.2s ease;
}
body.show-chatbot .chatbot-toggler {
transform: rotate(90deg);
}
.chatbot-toggler span {
color: #fff;
position: absolute;
}
.chatbot-toggler span:last-child,
body.show-chatbot .chatbot-toggler span:first-child {
opacity: 0;
}
body.show-chatbot .chatbot-toggler span:last-child {
opacity: 1;
}
.chatbot {
position: fixed;
right: 35px;
bottom: 90px;
width: 420px;
background: #fff;
border-radius: 15px;
overflow: hidden;
opacity: 0;
pointer-events: none;
transform: scale(0.5);
transform-origin: bottom right;
box-shadow: 0 0 128px 0 rgba(0, 0, 0, 0.1),
0 32px 64px -48px rgba(0, 0, 0, 0.5);
transition: all 0.1s ease;
}
body.show-chatbot .chatbot {
opacity: 1;
pointer-events: auto;
transform: scale(1);
}
.chatbot header {
padding: 16px 0;
position: relative;
text-align: center;
color: #fff;
background: #724ae8;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
.chatbot header span {
position: absolute;
right: 15px;
top: 50%;
display: none;
cursor: pointer;
transform: translateY(-50%);
}
header h2 {
font-size: 1.4rem;
}
.chatbot .chatbox {
overflow-y: auto;
height: 510px;
padding: 30px 20px 100px;
}
.chatbot :where(.chatbox, textarea)::-webkit-scrollbar {
width: 6px;
}
.chatbot :where(.chatbox, textarea)::-webkit-scrollbar-track {
background: #fff;
border-radius: 25px;
}
.chatbot :where(.chatbox, textarea)::-webkit-scrollbar-thumb {
background: #ccc;
border-radius: 25px;
}
.chatbox .chat {
display: flex;
list-style: none;
}
.chatbox .outgoing {
margin: 20px 0;
justify-content: flex-end;
}
.chatbox .incoming span {
width: 32px;
height: 32px;
color: #fff;
cursor: default;
text-align: center;
line-height: 32px;
align-self: flex-end;
background: #724ae8;
border-radius: 4px;
margin: 0 10px 7px 0;
}
.chatbox .chat p {
white-space: pre-wrap;
padding: 12px 16px;
border-radius: 10px 10px 0 10px;
max-width: 75%;
color: #fff;
font-size: 0.95rem;
background: #724ae8;
}
.chatbox .incoming p {
border-radius: 10px 10px 10px 0;
}
.chatbox .chat p.error {
color: #721c24;
background: #f8d7da;
}
.chatbox .incoming p {
color: #000;
background: #f2f2f2;
}
.chatbot .chat-input {
display: flex;
gap: 5px;
position: absolute;
bottom: 0;
width: 100%;
background: #fff;
padding: 3px 20px;
border-top: 1px solid #ddd;
}
.chat-input textarea {
height: 55px;
width: 100%;
border: none;
outline: none;
resize: none;
max-height: 180px;
padding: 15px 15px 15px 0;
font-size: 0.95rem;
}
.chat-input span {
align-self: flex-end;
color: #724ae8;
cursor: pointer;
height: 55px;
display: flex;
align-items: center;
visibility: hidden;
font-size: 1.35rem;
}
.chat-input textarea:valid~span {
visibility: visible;
}
@media (max-width: 490px) {
.chatbot-toggler {
right: 20px;
bottom: 20px;
}
.chatbot {
right: 0;
bottom: 0;
height: 100%;
border-radius: 0;
width: 100%;
}
.chatbot .chatbox {
height: 90%;
padding: 25px 15px 100px;
}
.chatbot .chat-input {
padding: 5px 15px;
}
.chatbot header span {
display: block;
}
}
챗봇과 채팅하는 동안 "API 키가 유효하지 않습니다. 유효한 API 키를 전달하세요."와 같은 오류가 발생하면 다음 단계를 따르세요.
## API 키 가져오기
1. [Google AI Studio](https://aistudio.google.com/app/apikey)로 이동합니다.
2. API 키 섹션으로 이동하여 새 API 키를 만듭니다.
API 키는 다음과 같습니다. 예) AIzaSyAtpnKGX13bTgmx0l_gQeatYvdWvY_wOTQ
**참고:** API는 무료이지만 사용 요청 수가 제한되어 있습니다.
## API 키 삽입
1. `script.js` 파일 에서 `API_KEY` 변수를 찾아 `MY API 키`를 실제 API 키로 바꿉니다.
2. API 키를 추가한 후 `script.js` 파일을 저장합니다.
3. 브라우저에서 `index.html`을 열어 Chatbot이 제대로 작동하는지 확인합니다.
즐거운 코딩 되세요!
반응형
'SMART GPT' 카테고리의 다른 글
MySQL과 jQuery(Ajax)를 사용한 PHP 간단한 챗봇 만들기 (0) | 2024.11.14 |
---|---|
윈도우 아파치서버 에서 다른 드라이브(예: 로컬 디스크 D 드라이브)의 web 폴더를 DocumentRoot로 설정 (0) | 2024.10.04 |
윈도우에서 Apache 서버 상태를 체크한 후 문제가 발생하면 자동으로 재부팅 (0) | 2024.09.25 |
Windows 서비스 관리자에서 Apache 서버가 멈췄을 때 시스템 자체를 재부팅 (0) | 2024.09.25 |
phpMyAdmin에서 데이터베이스를 추가할 때 비밀번호와 권한을 바로 설정하는 방법 (0) | 2024.09.21 |
ORDER BY 절에서 사용할 수 있는 몇 가지 옵션 (0) | 2024.09.19 |
MySQL에서 테이블을 생성하고 입, 출력 해보자(입력,출력,페이지네이션,검색) (1) | 2024.09.16 |
유튜브 동영상의 썸네일 이미지를 체크하여 유효한 영상이 아닐때 연결된 체크박스를 자동으로 체크 (1) | 2024.09.13 |
댓글