diff --git a/.gitignore b/.gitignore
index 3c3629e..1dcef2d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
node_modules
+.env
\ No newline at end of file
diff --git a/backend/index.js b/backend/index.js
index f421bb8..d50e9a4 100644
--- a/backend/index.js
+++ b/backend/index.js
@@ -100,6 +100,6 @@ app.get("*", (req, res) => {
res.sendFile(path.join(__dirname, "../frontend/vite-project/dist/index.html"));
});
-server.listen(port, () => {
- console.log(`Server is running on port ${port}`);
-});
+// server.listen(port, () => {
+// console.log(`Server is running on port ${port}`);
+// });
diff --git a/backend/routes/httpRoutes.js b/backend/routes/httpRoutes.js
index f6419bb..8de052f 100644
--- a/backend/routes/httpRoutes.js
+++ b/backend/routes/httpRoutes.js
@@ -2,11 +2,12 @@
import express from 'express';
import RoomController from '../controllers/RoomController.js';
import VideoCallController from '../controllers/VideoCallController.js';
+import { GeminiAiService } from '../services/geminiAiService.js';
// Create controller instances (io will be null for HTTP routes)
const roomController = new RoomController(null);
const videoCallController = new VideoCallController(null);
-
+const geminiService = new GeminiAiService();
const router = express.Router();
// Health check endpoint
@@ -64,6 +65,24 @@ router.get('/api/rooms', (req, res) => {
}
});
+
+router.post("/api/chatai", async (req, res) => {
+ try {
+ const { message, history = [] } = req.body;
+ if (!message) {
+ return res.status(400).json({ error: "Message is required" });
+ }
+ const resp = await geminiService.chatWithGemini(message, history);
+ return res.json({ data: resp.data });
+ } catch (err) {
+ console.error("[chatBotRoute] error:", err.message || err);
+ return res.status(500).json({
+ error: "Failed to fetch response from Gemini AI",
+ details: (err.message || "").slice(0, 1000),
+ });
+ }
+});
+
// API documentation endpoint
router.get('/api/docs', (req, res) => {
res.json({
diff --git a/backend/server.js b/backend/server.js
index 0a758b6..47a8c8d 100644
--- a/backend/server.js
+++ b/backend/server.js
@@ -7,7 +7,8 @@ import { Server } from "socket.io";
import path, { dirname, join } from "path";
import { fileURLToPath } from "url";
import cors from "cors";
-
+import dotenv from "dotenv"
+dotenv.config({ path: './.env' });
// Import configurations
import { serverConfig, staticConfig } from './config/server.js';
diff --git a/backend/services/geminiAiService.js b/backend/services/geminiAiService.js
new file mode 100644
index 0000000..56fc3a0
--- /dev/null
+++ b/backend/services/geminiAiService.js
@@ -0,0 +1,61 @@
+import axios from "axios";
+
+const GEMINI_API_URL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent";
+const API_KEY= YOUR_API_KEY;
+
+if (!API_KEY) {
+ throw new Error("GEMINI_API_KEY is not set in environment variables");
+}
+
+function extractReply(resp) {
+ try {
+ return (
+ resp.data?.candidates?.[0]?.content?.parts?.[0]?.text ||
+ resp.data?.candidates?.[0]?.content?.[0]?.text ||
+ resp.data?.output?.[0]?.content?.[0]?.text ||
+ null
+ );
+ } catch (error) {
+ console.error("Error extracting reply:", error);
+ return null;
+ }
+}
+
+export class GeminiAiService {
+ constructor() {
+ this.axios = axios.create({ timeout: 30000 });
+ }
+async chatWithGemini(message, history = []) {
+ const promptText = `You are an AI coding assistant in a collaborative coding room. Keep responses concise (max 4 lines). User message: ${message}`;
+
+ // 🔥 Convert history into Gemini's format
+ const formattedHistory = history.map(h => ({
+ role: h.role,
+ parts: [{ text: h.text }]
+ }));
+
+ const payload = {
+ contents: [
+ ...formattedHistory,
+ { role: "user", parts: [{ text: promptText }] }
+ ],
+ generationConfig: { temperature: 0.3, maxOutputTokens: 512 },
+ };
+
+ try {
+ const resp = await this.axios.post(
+ `${GEMINI_API_URL}?key=${API_KEY}`,
+ payload,
+ { headers: { "Content-Type": "application/json" } }
+ );
+
+ const reply = extractReply(resp);
+ const tokensUsed = resp.data?.usageMetadata?.totalTokenCount ?? null;
+
+ return { data: { reply: reply || "No reply from Gemini.", tokensUsed } };
+ } catch (err) {
+ console.error("Gemini API Error:", err.response?.status, err.response?.data || err.message);
+ throw new Error(err.response?.data?.error?.message || err.message || "Gemini request failed");
+ }
+}
+}
\ No newline at end of file
diff --git a/frontend/vite-project/src/App.jsx b/frontend/vite-project/src/App.jsx
index 2dcf5a0..5d4d346 100644
--- a/frontend/vite-project/src/App.jsx
+++ b/frontend/vite-project/src/App.jsx
@@ -25,6 +25,7 @@ import {
import BackToTop from "./components/ui/BackToTop";
import * as monaco from 'monaco-editor';
+import FloatingChatbot from "./components/floating";
const App = () => {
@@ -1022,6 +1023,7 @@ const App = () => {
)}
+