Răsfoiți Sursa

feat: integrate Google Gemini AI for content generation in post editor

Adam Jafarov 1 săptămână în urmă
părinte
comite
17127a905e
5 a modificat fișierele cu 593 adăugiri și 128 ștergeri
  1. 3 1
      backend/.env.production
  2. 10 0
      backend/package-lock.json
  3. 1 0
      backend/package.json
  4. 46 0
      backend/server.js
  5. 533 127
      src/components/PostEditor.jsx

+ 3 - 1
backend/.env.production

@@ -14,6 +14,8 @@ FRONTEND_URL=https://goonblog.thevakhovske.eu.org
 POSTS_DIR=../public/posts
 THEMES_FILE=./themes.json
 
+GEMINI_API_KEY=AIzaSyBn_UbFZKCZ18GeMv6l0tSccxDpzRJsbW0
+
 # Security Settings
 COOKIE_SECURE=true
-COOKIE_SAME_SITE=strict
+COOKIE_SAME_SITE=strict

+ 10 - 0
backend/package-lock.json

@@ -8,6 +8,7 @@
       "name": "gooneral-wheelchair-backend",
       "version": "1.0.0",
       "dependencies": {
+        "@google/generative-ai": "^0.24.1",
         "bcryptjs": "^3.0.2",
         "connect-session-file": "^1.0.4",
         "cors": "^2.8.5",
@@ -23,6 +24,15 @@
         "nodemon": "^3.1.7"
       }
     },
+    "node_modules/@google/generative-ai": {
+      "version": "0.24.1",
+      "resolved": "https://registry.npmjs.org/@google/generative-ai/-/generative-ai-0.24.1.tgz",
+      "integrity": "sha512-MqO+MLfM6kjxcKoy0p1wRzG3b4ZZXtPI+z2IE26UogS2Cm/XHO+7gGRBh6gcJsOiIVoH93UwKvW4HdgiOZCy9Q==",
+      "license": "Apache-2.0",
+      "engines": {
+        "node": ">=18.0.0"
+      }
+    },
     "node_modules/accepts": {
       "version": "1.3.8",
       "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",

+ 1 - 0
backend/package.json

@@ -10,6 +10,7 @@
     "dev": "nodemon server.js"
   },
   "dependencies": {
+    "@google/generative-ai": "^0.24.1",
     "bcryptjs": "^3.0.2",
     "connect-session-file": "^1.0.4",
     "cors": "^2.8.5",

+ 46 - 0
backend/server.js

@@ -7,6 +7,7 @@ import path from "path";
 import { fileURLToPath } from "url";
 import { v4 as uuidv4 } from "uuid";
 import multer from "multer";
+import { GoogleGenerativeAI } from "@google/generative-ai";
 
 // Load environment variables
 dotenv.config();
@@ -319,6 +320,51 @@ app.post(
     },
 );
 
+// AI Generation Route
+app.post("/api/ai/generate", requireAuth, async (req, res) => {
+    try {
+        const { context, prompt } = req.body;
+        const apiKey = process.env.GEMINI_API_KEY;
+
+        if (!apiKey) {
+            return res
+                .status(500)
+                .json({ error: "AI API key is not configured." });
+        }
+
+        if (!prompt) {
+            return res.status(400).json({ error: "A prompt is required." });
+        }
+
+        res.setHeader("Content-Type", "text/event-stream");
+        res.setHeader("Cache-Control", "no-cache");
+        res.setHeader("Connection", "keep-alive");
+
+        const genAI = new GoogleGenerativeAI(apiKey);
+        const model = genAI.getGenerativeModel({
+            model: "gemini-3-flash-preview",
+        });
+
+        const fullPrompt = `${context}\n\n${prompt}`;
+        const result = await model.generateContentStream(fullPrompt);
+
+        for await (const chunk of result.stream) {
+            const chunkText = chunk.text();
+            res.write(`data: ${JSON.stringify({ chunk: chunkText })}\n\n`);
+        }
+
+        res.end();
+    } catch (error) {
+        console.error("AI generation error:", error);
+        // We can't send a 500 status here as the headers are already sent.
+        // We can write an error event to the stream.
+        res.write(
+            `data: ${JSON.stringify({ error: "Failed to generate AI content." })}\n\n`,
+        );
+        res.end();
+    }
+});
+
 // MEDIA ROUTES
 
 // POST /api/upload - Upload file

Fișier diff suprimat deoarece este prea mare
+ 533 - 127
src/components/PostEditor.jsx


Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff