diff --git a/.gitignore b/.gitignore index d791678..f05270a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ .env node_modules dist -package-lock.json \ No newline at end of file +package-lock.json +*.ogg +*.wav +*.mp3 \ No newline at end of file diff --git a/example.env b/example.env index 81dea95..9ca76ac 100644 --- a/example.env +++ b/example.env @@ -5,4 +5,5 @@ DATABASE_TABLE = DATABASE_NAME = DATABASE_URL = DATABASE_USER = -DATABASE_PASSWORD = \ No newline at end of file +DATABASE_PASSWORD = +GEMINI_KEY = \ No newline at end of file diff --git a/gemini.js b/gemini.js new file mode 100644 index 0000000..4925a10 --- /dev/null +++ b/gemini.js @@ -0,0 +1,107 @@ +import { GoogleGenAI, createUserContent, createPartFromUri } from "@google/genai"; +import dotenv from "dotenv"; +dotenv.config(); + +import wav from 'wav'; + + +// The client gets the API key from the environment variable `GEMINI_API_KEY`. +const ai = new GoogleGenAI({apiKey: process.env.GEMINI_KEY}); + +const AUDIO_URL = "https://s3.twcstorage.ru/22b2a814-mhand/audio_2026-01-28_12-59-38.ogg" + +async function saveWaveFile( + filename, + pcmData, + channels = 1, + rate = 24000, + sampleWidth = 2, +) { + return new Promise((resolve, reject) => { + const writer = new wav.FileWriter(filename, { + channels, + sampleRate: rate, + bitDepth: sampleWidth * 8, + }); + + writer.on('finish', resolve); + writer.on('error', reject); + + writer.write(pcmData); + writer.end(); + }); +} + +async function main() { + const response = await ai.models.generateContent({ + model: "gemini-2.5-flash-lite", + contents: "Что ты умеешь делать? На какой модели ты построен?", + }); + console.log(response.text); +} + + +async function pepe(){ + const prompt = 'Нужно сделать анализ аудиофайла и вывести текстовую расшифровку.' + + + const response = await ai.models.generateContent({ + model: "gemini-3-flash-preview", + contents: { + parts:[ + { + fileData: { + fileUri:AUDIO_URL, + }, + }, + { + text: prompt + } + ] + } + }) + console.log(response.text) +} + +async function shneine(){ + const myfile = await ai.files.upload({ + file:'./pedik.ogg', + config:{ + mimeType:'audio/ogg', + } + }); + + const response = await ai.models.generateContent({ + model: "gemini-3-flash-preview", + contents: createUserContent([ + createPartFromUri(myfile.uri, myfile.mimeType), + 'Нужно сделать анализ аудиофайла, краткую выжимку самого важного, вывести тезисы.' + ]) + }) + console.log(response.text) +} +//await shneine(); + + +async function fawatafa() { + const response = await ai.models.generateContent({ + model: "gemini-2.5-flash-preview-tts", + contents: [{ parts: [{ text: `Say aggresive: А перекинул я этот пост, потому что его Саша переслал. И вот вдумайся: Саше 30 лет, и вот на него это полностью работает. То есть он верит, что можно заставить Дурова открыть представительство в России, и это снимет к нему все вопросы, и Телеграм оставят незаблокированным` }] }], + config: { + responseModalities: ['AUDIO'], + speechConfig: { + voiceConfig: { + prebuiltVoiceConfig: { voiceName: 'Leda' }, + }, + }, + }, + }); + + const data = response.candidates?.[0]?.content?.parts?.[0]?.inlineData?.data; + const audioBuffer = Buffer.from(data, 'base64'); + + const fileName = 'outMarat5.wav'; + await saveWaveFile(fileName, audioBuffer); +} + +await fawatafa(); \ No newline at end of file diff --git a/package.json b/package.json index 1509afa..809e279 100644 --- a/package.json +++ b/package.json @@ -3,17 +3,26 @@ "version": "1.0.0", "main": "index.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "dev": "nodemon src/server.js", + "start": "node src/server.js", + "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "description": "", "dependencies": { + "@google/genai": "^1.38.0", "axios": "^1.13.2", "dotenv": "^17.2.3", + "express": "^5.2.1", + "jsonwebtoken": "^9.0.3", "node-telegram-bot-api": "^0.67.0", - "pg": "^8.17.2" + "pg": "^8.17.2", + "wav": "^1.0.2" }, - "type": "module" + "type": "module", + "devDependencies": { + "nodemon": "^3.1.11" + } } diff --git a/src/middleware/auth.js b/src/middleware/auth.js new file mode 100644 index 0000000..4c3a4b8 --- /dev/null +++ b/src/middleware/auth.js @@ -0,0 +1,23 @@ +import jwt from "jsonwebtoken"; + +export function authMiddleware(req, res, next) { + const authHeader = req.headers.authorization; + + if (!authHeader) { + return res.status(401).json({ message: "Нет Authorization header" }); + } + + const [type, token] = authHeader.split(" "); + + if (type !== "Bearer" || !token) { + return res.status(401).json({ message: "Неверный формат токена" }); + } + + try { + const payload = jwt.verify(token, process.env.JWT_SECRET); + req.user = payload; + next(); + } catch { + return res.status(401).json({ message: "Токен невалиден" }); + } +} diff --git a/src/routes/auth.js b/src/routes/auth.js new file mode 100644 index 0000000..5139fcc --- /dev/null +++ b/src/routes/auth.js @@ -0,0 +1,24 @@ +import { Router } from "express"; +import jwt from "jsonwebtoken"; + +const router = Router(); + +// POST /auth/login +router.post("/login", (req, res) => { + const { email, password } = req.body; + + // ⚠️ Заглушка + if (email !== "test@test.com" || password !== "1234") { + return res.status(401).json({ message: "Неверные данные" }); + } + + const token = jwt.sign( + { id: 1, email }, + process.env.JWT_SECRET, + { expiresIn: "1h" } + ); + + res.json({ token }); +}); + +export default router; diff --git a/src/routes/user.js b/src/routes/user.js new file mode 100644 index 0000000..cd0f5e3 --- /dev/null +++ b/src/routes/user.js @@ -0,0 +1,14 @@ +import { Router } from "express"; +import { authMiddleware } from "../middleware/auth.js"; + +const router = Router(); + +// GET /user/profile +router.get("/profile", authMiddleware, (req, res) => { + res.json({ + message: "Приватный профиль", + user: req.user, + }); +}); + +export default router; diff --git a/src/server.js b/src/server.js new file mode 100644 index 0000000..1b05926 --- /dev/null +++ b/src/server.js @@ -0,0 +1,23 @@ +import express from "express"; +import dotenv from "dotenv"; + +import authRoutes from "./routes/auth.js"; +import userRoutes from "./routes/user.js"; + +dotenv.config(); + +const app = express(); + +app.use(express.json()); + +app.use("/auth", authRoutes); +app.use("/user", userRoutes); + +app.get("/health", (req, res) => { + res.json({ status: "ok" }); +}); + +const PORT = process.env.PORT || 3000; +app.listen(PORT, () => { + console.log(`🚀 Server started on http://localhost:${PORT}`); +});