UNPKG

react-gemini-ai-bot

Version:

This project provides a React component for integrating a chatbot powered by Gemini AI.

91 lines (77 loc) 3.56 kB
import "./Chatbot.css" import ChatForm from "./Components/ChatForm"; import { useEffect, useRef, useState } from "react"; import ChatMessage from "./Components/ChatMessage"; import xMark from './assets/xMark.svg'; import messageIcon from './assets/messageIcon.svg'; import angleDown from './assets/angleDown.svg'; import chatbotIcon from './assets/chatbotIcon.svg'; import chatbotIconViolet from './assets/chatbotIcon-violet.svg'; const App = ({ apiKey }) => { const [chatHistory, setChatHistory] = useState([]); const [showChatbot, setShowChatbot] = useState(false); const chatBodyRef = useRef(); const generateBotResponse = async (history) => { const updateChats = (resText, isError = false) => { setChatHistory(chats => [...chats.filter(msg => msg.text !== "Thinking..."), { role: "model", text: resText, isError }]) } //Parse the payload for api history = history.map(({ role, text }) => [{ role, parts: [{ text }] }]); const requestOptions = { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ contents: history }) }; try { const response = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${apiKey}`, requestOptions); const data = await response.json(); if (!response.ok) throw new Error(data.error.message || "Something went wrong"); const geminiResponseText = data.candidates[0].content.parts[0].text.replace(/\*\*(.*?)\*\*/g, "$1").trim(); updateChats(geminiResponseText); } catch (error) { updateChats(error.message, true); } } useEffect(() => { //Show latest messages by scrolling down chatBodyRef.current.scrollTo({ top: chatBodyRef.current.scrollHeight, behaviour: "smooth" }); }, [chatHistory]) return ( <div className={`container ${showChatbot && 'show-chatbot'}`}> <button id="chatbot-toggler" onClick={() => setShowChatbot(toggle => !toggle)} title="Toggle"> {!showChatbot && <img src={messageIcon} alt="open chat" width={30} height={30} />} {showChatbot && <img src={xMark} alt="close chat" width={30} height={30} />} </button> <div className="chatbot-popup"> {/* Chatbot Header */} <div className="chat-header"> <div className="header-info"> <img src={chatbotIconViolet} alt="close chat" width={50} height={50} /> <h2 className="logo-text">Chatbot</h2> </div> <button onClick={() => setShowChatbot(toggle => !toggle)} title="Close"> <img src={angleDown} alt="close chat" width={45} height={45} /> </button> </div> {/* Chatbot body */} <div ref={chatBodyRef} className="chat-body"> <div className="message bot-message"> <img src={chatbotIcon} alt="close chat" width={30} height={30} /> <p className="message-text"> Hey there <br /> How can I help you today? </p> </div> {/* Render the chat messages */} {chatHistory.map((chat, index) => ( <ChatMessage key={index} chat={chat} /> ))} </div> {/* Chatbot footer */} <div className="chat-footer"> <ChatForm chatHistory={chatHistory} setChatHistory={setChatHistory} generateBotResponse={generateBotResponse} /> </div> </div> </div> ) } export default App;