-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
116 lines (97 loc) · 3.41 KB
/
index.js
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
require('dotenv').config();
const express = require("express");
const cors = require("cors");
const rateLimit = require("express-rate-limit");
const { OpenAI } = require("openai");
// Validate environment variables
const requiredEnvVars = ['OPENAI_API_KEY', 'ASSISTANT_ID'];
for (const envVar of requiredEnvVars) {
if (!process.env[envVar]) {
console.error(`Error: ${envVar} environment variable is missing`);
process.exit(1);
}
}
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
const ASSISTANT_ID = process.env.ASSISTANT_ID;
const app = express();
// Configure CORS
const corsOptions = {
origin: process.env.ALLOWED_ORIGINS ? process.env.ALLOWED_ORIGINS.split(',') : '*',
methods: 'GET,POST',
allowedHeaders: 'Content-Type,Authorization',
};
app.use(cors(corsOptions));
// Configure rate limiting
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100 // limit each IP to 100 requests per windowMs
});
app.use(limiter);
app.use(express.json());
app.get("/", (req, res) => {
res.send("Welcome to the PEC.UP AI chatbot server!");
});
app.get("/start", async (req, res) => {
try {
const thread = await openai.beta.threads.create();
return res.json({ thread_id: thread.id });
} catch (error) {
console.error("Error creating thread:", error);
return res.status(500).json({ error: "Failed to create thread", details: error.message });
}
});
app.post("/chat", async (req, res) => {
const { thread_id, message } = req.body;
if (!thread_id || !message) {
console.log("Error: Missing thread_id or message");
return res.status(400).json({ error: "Missing thread_id or message" });
}
console.log(`Received message: ${message} for thread ID: ${thread_id}`);
const timeoutPromise = new Promise((_, reject) =>
setTimeout(() => reject(new Error('Timeout')), 9990) // 9.99 seconds timeout
);
const chatPromise = async () => {
await openai.beta.threads.messages.create(thread_id, {
role: "user",
content: message,
});
const run = await openai.beta.threads.runs.create(thread_id, {
assistant_id: ASSISTANT_ID,
});
let status;
do {
await new Promise(resolve => setTimeout(resolve, 1000)); // Poll every second
const runStatus = await openai.beta.threads.runs.retrieve(thread_id, run.id);
status = runStatus.status;
} while (status === 'in_progress' || status === 'queued');
if (status !== 'completed') {
throw new Error(`Run ended with status: ${status}`);
}
const messages = await openai.beta.threads.messages.list(thread_id);
return messages.data[0].content[0].text.value;
};
try {
const response = await Promise.race([chatPromise(), timeoutPromise]);
console.log("Chat response:", { response });
return res.json({ response });
} catch (error) {
console.error("Error or timeout in /chat endpoint:", error);
let responseObj;
if (error.message === 'Timeout') {
responseObj = {
response: "I'm still processing your request. Please try again in a few seconds."
};
} else {
responseObj = { error: "Failed to handle chat", details: error.message };
}
console.log("Error response:", responseObj);
return res.status(error.message === 'Timeout' ? 200 : 500).json(responseObj);
}
});
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
module.exports = app;