Skip to content

Commit

Permalink
✅ chat bot added sussessfylly
Browse files Browse the repository at this point in the history
  • Loading branch information
sinanptm committed Oct 6, 2024
1 parent 355354c commit 714c590
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 44 deletions.
11 changes: 7 additions & 4 deletions client/components/page-components/chatbot/ChatBotController.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import { Button } from "@/components/ui/button";
import { ButtonV2 } from "@/components/button/ButtonV2";
import { Input } from "@/components/ui/input";
import { CardFooter } from "@/components/ui/card";
import { Send } from "lucide-react";
import { ButtonV2 } from "@/components/button/ButtonV2";

type ChatBotControllerProps = {
inputMessage: string;
setInputMessage: (value: string) => void;
sendMessage: () => void;
isSending: boolean;
};

const ChatBotController = ({ inputMessage, setInputMessage, sendMessage }: ChatBotControllerProps) => {
const ChatBotController = ({ inputMessage, setInputMessage, sendMessage, isSending }: ChatBotControllerProps) => {
return (
<CardFooter className="pt-3 bg-dark-300">
<form
onSubmit={(e) => {
e.preventDefault();
sendMessage();
if (!isSending) sendMessage();
}}
className="flex w-full items-center space-x-3"
>
Expand All @@ -27,13 +27,16 @@ const ChatBotController = ({ inputMessage, setInputMessage, sendMessage }: ChatB
onChange={(e) => setInputMessage(e.target.value)}
className="flex-grow bg-dark-100 text-white placeholder-gray-400 border-gray-600 focus:border-green-500 focus:ring-green-500 text-sm py-3 rounded-full"
aria-label="Type your message"
onKeyDown={(e) => e.key === 'Enter' && sendMessage()}
/>
<ButtonV2
type="submit"
variant={"ringHover"}
size="icon"
className="rounded-full bg-green-600 hover:bg-green-700"
aria-label="Send message"
disabled={isSending}
onKeyDown={(e) => e.key === 'Enter' && sendMessage()}
>
<Send className="h-5 w-5" />
</ButtonV2>
Expand Down
39 changes: 22 additions & 17 deletions client/components/page-components/chatbot/ChatSection.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client'

import { useState, useEffect, useRef } from 'react'
import { useState, useEffect, useRef, memo } from 'react'
import { Card } from "@/components/ui/card"
import { motion, AnimatePresence } from "framer-motion"
import ChatBotController from './ChatBotController'
Expand All @@ -10,6 +10,7 @@ import { IChatBotMessage } from '@/types/entities'
import { useCreateMessage } from '@/lib/hooks/chatbot/useChatBot'
import { useGetMessage } from '@/lib/hooks/chatbot/useChatBot'
import { toast } from '@/components/ui/use-toast'
import { getRandomId } from '@/lib/utils'

type Props = {
isVisible: boolean;
Expand All @@ -18,40 +19,43 @@ type Props = {
}

const ChatSection = ({ isVisible, setIsOpen, isAuthenticated }: Props) => {
const { data, isLoading } = useGetMessage()
const [messages, setMessages] = useState<IChatBotMessage[]>(data ?? []);
const { data } = useGetMessage();
const [messages, setMessages] = useState<IChatBotMessage[]>([]);
const [inputMessage, setInputMessage] = useState('');
const scrollAreaRef = useRef<HTMLDivElement>(null);
const { mutate: createMessage, isPending } = useCreateMessage();

useEffect(() => {
if (scrollAreaRef.current) {
scrollAreaRef.current.scrollTop = scrollAreaRef.current.scrollHeight;
if (data && data?.length > 0) {
setMessages(data);
}
}, [messages]);
}, [data]);

const handleClose = () => {
setIsOpen(false);
}
};

const sendMessage = () => {
if (inputMessage.trim()) {
const id = getRandomId()
const tempMessage: IChatBotMessage = { isBotMessage: false, message: inputMessage, _id:id, patientId:id };
setMessages(prev => [...prev, tempMessage]);
createMessage({ message: inputMessage },
{
onSuccess: (messages) => {
setMessages(prev => [...prev, ...messages]);
onSuccess: (newMessages) => {
setInputMessage("");
setMessages(prev => [...prev, newMessages]);
},
onError: (error) => {
toast({
title: "Error Occurred while sending message",
variant: "destructive",
description: error.response?.data.message || "Unknown error Occurred"
})
});
}
}
)
);
}
}
};

return (
<AnimatePresence onExitComplete={() => setIsOpen(false)}>
Expand All @@ -65,11 +69,12 @@ const ChatSection = ({ isVisible, setIsOpen, isAuthenticated }: Props) => {
>
{isAuthenticated ? (
<Card className="h-full sm:h-[600px] max-h-[800px] flex flex-col shadow-2xl border-primary/10 bg-dark-200 rounded-2xl overflow-hidden">
<MessageDisplay scrollAreaRef={scrollAreaRef} handleClose={handleClose} />
<MessageDisplay messages={messages} handleClose={handleClose} />
<ChatBotController
inputMessage={inputMessage}
setInputMessage={setInputMessage}
sendMessage={sendMessage}
isSending={isPending}
/>
</Card>
) : (
Expand All @@ -78,7 +83,7 @@ const ChatSection = ({ isVisible, setIsOpen, isAuthenticated }: Props) => {
</motion.div>
)}
</AnimatePresence>
)
}
);
};

export default ChatSection;
export default memo(ChatSection);
21 changes: 15 additions & 6 deletions client/components/page-components/chatbot/MessageDisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,24 @@ import { motion } from "framer-motion"
import Image from "next/image"
import ChatBotCardHeader from "./ChatBotCardHeader"
import { IChatBotMessage } from "@/types/entities"


import { useEffect, useRef } from "react"

type Props = {
scrollAreaRef: React.RefObject<HTMLDivElement>;
handleClose: () => void;
messages?:IChatBotMessage[];
messages?: IChatBotMessage[];
}

const MessageDisplay = ({ scrollAreaRef, handleClose, messages }: Props) => {
const MessageDisplay = ({ handleClose, messages }: Props) => {
const scrollAreaRef = useRef<HTMLDivElement>(null);
const bottomRef = useRef<HTMLDivElement>(null);

const scrollToBottom = () => {
bottomRef.current?.scrollIntoView({ behavior: 'auto' });
};

useEffect(() => {
scrollToBottom();
}, [messages]);

return (
<>
Expand Down Expand Up @@ -49,13 +57,14 @@ const MessageDisplay = ({ scrollAreaRef, handleClose, messages }: Props) => {
}
</div>
<i
className={`max-w-[75%] p-4 rounded-2xl shadow-md ${!msg.isBotMessage ? 'bg-green-600 text-white' : 'bg-gray-700 text-white'}`}
className={`max-w-[75%] p-4 rounded-2xl shadow-md ${msg.isBotMessage ? 'bg-green-600 text-white' : 'bg-gray-700 text-white'}`}
>
<p className="text-sm">{msg.message}</p>
</i>
</div>
</motion.div>
))}
<div ref={bottomRef}></div>
</ScrollArea>
</CardContent>
</>
Expand Down
2 changes: 1 addition & 1 deletion client/lib/hooks/chatbot/useChatBot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useMutation, useQuery } from "@tanstack/react-query"
import { AxiosError } from "axios"

export const useCreateMessage = () => {
return useMutation<IChatBotMessage[], AxiosError<ErrorResponse>, { message: string }>({
return useMutation<IChatBotMessage, AxiosError<ErrorResponse>, { message: string }>({
mutationFn: ({ message }) => createChatMessage(message)
})
};
Expand Down
4 changes: 4 additions & 0 deletions client/lib/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,7 @@ export const formatDate = (date: Date): string => {
const year = date.getFullYear();
return `${day}/${month}/${year}`;
};

export const getRandomId = () => {
return (Math.random() * 121 / 12).toString() + new Date()
}
24 changes: 15 additions & 9 deletions server/src/config/chatBotConfig.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
const chatBotConfig = {
description: "You are an Ayurvedic hospital chatbot. You assist users with health-related queries about Ayurveda, allopathy, treatments, medicines, appointments, and hospital services. Respond politely, with helpful and informative guidance. ",
description: "You are an Ayurvedic hospital chatbot. You assist users with health-related queries about Ayurveda, allopathy, treatments, medicines, appointments, and hospital services. Respond politely, with helpful and informative guidance.",

behavior_rules: `
- Only respond to health-related queries about Ayurveda, allopathy, medicines, hospital services, and hospital contact/location information.
- Provide dosage information and potential side effects for Ayurvedic and allopathic medicines, when appropriate.
- Ask follow-up questions based on symptoms to suggest treatments or guide users toward consultations.
- Offer Ayurvedic lifestyle and dietary recommendations.
- Support multiple languages (if applicable).
- When necessary, refer users to contact hospital staff for more personalized advice.
- Be culturally sensitive and align responses with Ayurvedic principles.
- Always offer additional help at the end of each response.
- Avoid starting responses with “I understand...” and instead use more neutral, conversational phrases to gather details.
- Example questions to ask when a user mentions symptoms like a headache:
* "Could you tell me more about how long you’ve been experiencing the headache?"
* "Where exactly do you feel the headache?"
* "How would you rate the intensity of the headache (mild, moderate, or severe)?"
* "Are you experiencing any additional symptoms alongside the headache?"
* "Have you taken any medication for this?"
- Ask follow-up questions to provide better recommendations but keep the tone neutral and avoid assuming any diagnosis.
- Provide general advice based on symptoms but suggest consulting an Ayurvedic doctor for personalized treatment.
- Be mindful of not over-personalizing conversations—keep responses professional and neutral, allowing users to describe their condition in detail.
- Always offer additional assistance at the end of each response: "Let me know if you'd like further advice or to consult with one of our doctors."
- Align all health-related advice with Ayurvedic principles while also offering modern allopathic guidance if necessary.
`
}

export default chatBotConfig;
export default chatBotConfig;
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import ChatbotMessageModel from "../model/ChatBotMessageModel";
export default class ChaBotMessageRepository implements IChatBotMessageRepository {
model = ChatbotMessageModel;
async getMessagesByPatientId(patientId: string): Promise<IChatBotMessage[] | []> {
return await this.model.find({ patientId }).lean(true);
return await this.model.find({ patientId }).limit(50).lean(true);
}
async create(message: IChatBotMessage): Promise<IChatBotMessage> {
return await this.model.create(message);
Expand Down
7 changes: 1 addition & 6 deletions server/src/infrastructure/services/GeminiBotService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,7 @@ export default class GeminiBotService implements IChatBotService {
}

async generateResponse(userMessage: string): Promise<string> {
const prompt = `
**User Message:** ${userMessage}
**Behavior Rules:**
${chatBotConfig.behavior_rules}
`;
const prompt = `**User Message:** ${userMessage}`;

const result = await this.model.generateContent({
contents: [
Expand Down

0 comments on commit 714c590

Please sign in to comment.