const http = require("http"); const fs = require("fs"); const path = require("path"); const PORT = process.env.PORT || 3000; function body(req) { return new Promise((resolve) => { let s = ""; req.on("data", (c) => (s += c)); req.on("end", () => { try { resolve(JSON.parse(s || "{}")); } catch (_) { resolve({}); } }); }); } async function ai(prompt) { const r = await fetch(process.env.AI_BASE_URL + "/chat/completions", { method: "POST", headers: { "Content-Type": "application/json", Authorization: "Bearer " + process.env.AI_API_KEY }, body: JSON.stringify({ model: process.env.AI_MODEL, temperature: 0.4, messages: [ { role: "system", content: "Сен — артрит, артроз және анкилозды спондилит (Бехтерев ауруы) бар адамдарға арналған көмекші-кеңесші. Қазақ тілінде, жай сөзбен, қысқа әрі нақты жауап бер. Жауабыңда мыналар болсын: 1) шағымды қалай бағалауға болады; 2) қазір не істеу керек (жеңіл қозғалыс, жылу/суық, тыныштық) — жаттығуды тек ауырсынбай ғана орындау керектігін ескерт; 3) дәрі-дәрмекті тек дәрігер тағайындайтынын еске сал, дәрі атын ұсынба; 4) қандай белгілер кезінде дәрігерге шұғыл қаралу керектігін анық жаз (қатты күшейген ауырсыну, қатты ісіну, қызба, аяқ-қолды қозғалта алмау, сезімталдық жоғалуы). Шағымға байланысты пайдалы болса, осы бөлімдерге сілтеме ата: жаттығуларға — «Сайттағы Жаттығу бөлімінде дайын кешен бар» деп, дәрі/мазь/уколға — «Дәрілер және Аптека бөлімдерін қара» деп. Ақырында: «Бұл ақпарат дәрігер кеңесінің орнын баспайды» деп қос. Сен медициналық маман емессің." }, { role: "user", content: prompt } ] }) }); if (!r.ok) throw new Error("ИИ недоступен, код " + r.status); const j = await r.json(); const out = j.choices?.[0]?.message?.content; if (!out) throw new Error("ИИ вернул пустой ответ"); return out.trim(); } http.createServer(async (req, res) => { const url = req.url.split("?")[0]; if (req.method === "POST" && url === "/api/advice") { const data = await body(req); const text = (data.text || "").trim(); if (!text) { res.writeHead(400, { "Content-Type": "application/json; charset=utf-8" }); return res.end(JSON.stringify({ ok: false, error: "Хабарлама бос" })); } try { const answer = await ai(text); res.writeHead(200, { "Content-Type": "application/json; charset=utf-8" }); return res.end(JSON.stringify({ ok: true, answer })); } catch (e) { res.writeHead(502, { "Content-Type": "application/json; charset=utf-8" }); return res.end(JSON.stringify({ ok: false, error: "ИИ временно недоступен, попробуйте ещё раз" })); } } let file = url === "/" ? "/index.html" : url; const full = path.join(__dirname, file); if (full.startsWith(__dirname) && fs.existsSync(full) && fs.statSync(full).isFile()) { const ext = path.extname(full); const type = ext === ".css" ? "text/css" : ext === ".js" ? "application/javascript" : "text/html"; res.writeHead(200, { "Content-Type": type + "; charset=utf-8" }); return res.end(fs.readFileSync(full)); } res.writeHead(404); res.end("Not found"); }).listen(PORT, () => console.log("Сервер на порту " + PORT));