Repository navigation
Expand file tree
/
Copy pathserver.js
More file actions
84 lines (70 loc) · 2.94 KB
/
Copy pathserver.js
File metadata and controls
84 lines (70 loc) · 2.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
require('dotenv').config();
const express = require('express');
const http = require('http');
const path = require('path');
const rateLimit = require('express-rate-limit');
const twilio = require('twilio');
const app = express();
const server = http.createServer(app);
const PORT = process.env.PORT || 3000;
// Rate limiting for API endpoints
const aiLimiter = rateLimit({
windowMs: 1 * 60 * 1000, // 1 minute
max: 10, // Limit each IP to 10 requests per `window` (here, per minute)
message: { text: "Too many requests to the AI endpoint, please try again after a minute." },
standardHeaders: true,
legacyHeaders: false,
});
// Serve static files from the 'public' directory
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.json());
// AI Chat Route
const Groq = require('groq-sdk');
const hasGroqApiKey = Boolean(
process.env.GROQ_API_KEY && process.env.GROQ_API_KEY !== 'your_groq_api_key_here'
);
const groq = hasGroqApiKey ? new Groq({ apiKey: process.env.GROQ_API_KEY }) : null;
app.post('/api/ai', aiLimiter, async (req, res) => {
try {
if (!groq) {
return res.status(503).json({ text: "AI assistant is not configured on this server yet." });
}
const { message } = req.body;
if (!message || message.length > 500) {
return res.status(400).json({ text: "Message is too long or empty." });
}
const completion = await groq.chat.completions.create({
messages: [
{ role: "system", content: "You are a helpful study assistant in a virtual study room. Answer concisely." },
{ role: "user", content: message }
],
// llama-3.1-8b-instant was deprecated by Groq (shut down 08/16/26);
// openai/gpt-oss-20b is Groq's designated replacement — fast and
// well-suited to a chat assistant.
model: "openai/gpt-oss-20b",
});
res.json({ text: completion.choices[0].message.content });
} catch (e) {
console.error("AI Error:", e);
res.status(500).json({ text: "Sorry, I am having trouble connecting to my brain right now." });
}
});
// Twilio TURN Credentials Route
app.post('/api/turn-credentials', async (req, res) => {
try {
const accountSid = process.env.TWILIO_ACCOUNT_SID;
const authToken = process.env.TWILIO_AUTH_TOKEN;
if (!accountSid || !authToken) {
return res.status(500).json({ error: "Twilio credentials not configured on server." });
}
const client = twilio(accountSid, authToken);
const token = await client.tokens.create();
res.json({ iceServers: token.iceServers });
} catch (e) {
console.error("TURN Error:", e);
res.status(500).json({ error: "Failed to generate TURN credentials" });
}
});
server.listen(PORT, () => {
console.log(`Flow static server running on port ${PORT}`);
});