forked from zenflies/Itinerate
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.js
More file actions
118 lines (101 loc) · 5.3 KB
/
Copy pathserver.js
File metadata and controls
118 lines (101 loc) · 5.3 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
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
117
118
require('dotenv').config();
const express = require('express');
const cors = require('cors');
const path = require('path');
const { GoogleGenerativeAI } = require('@google/generative-ai');
const { initDB } = require('./db');
const authRoutes = require('./routes/auth');
const itineraryRoutes = require('./routes/itinerary');
const contactRoutes = require('./routes/contact');
const adminRoutes = require('./routes/admin');
const app = express();
const PORT = process.env.PORT || 3000;
// ── Middleware ──────────────────────────────────────────────────────────────
app.use(cors({
origin: process.env.ALLOWED_ORIGIN || '*',
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization']
}));
app.use(express.json());
// ── Serve static frontend files ─────────────────────────────────────────────
// Place your HTML/CSS/JS in a `public/` folder alongside server.js
app.use(express.static(path.join(__dirname, 'public')));
// ── API Routes ───────────────────────────────────────────────────────────────
app.use('/api/auth', authRoutes);
app.use('/api/itinerary', itineraryRoutes);
app.use('/api/contact', contactRoutes);
app.use('/api/admin', adminRoutes);
// ── AI Chatbot Route ─────────────────────────────────────────────────────────
app.post('/api/chat', async (req, res) => {
try {
const { message } = req.body;
if (!message) return res.status(400).json({ error: 'No message provided' });
const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
const model = genAI.getGenerativeModel({ model: 'gemini-2.5-flash' });
const systemPrompt = `You are the friendly, helpful AI support chatbot for 'Itinerate', an automated travel planning application.
You are chatting live with a user on our website.
Rules:
1. Read the user's input carefully.
2. Provide a short, helpful, and conversational response (1-2 sentences).
3. If they are reporting a bug or asking a complex question you cannot answer,
politely apologize and ask them to email support at travel.itinerate@gmail.com.
User Message:
${message}`;
const result = await model.generateContent(systemPrompt);
res.json({ reply: result.response.text() });
} catch (err) {
console.error('AI Chat Error:', err);
res.status(500).json({ error: 'Sorry, I am having trouble connecting to the AI.' });
}
});
app.post('/api/flights', async (req, res) => {
const { query } = req.body;
if (!query) return res.status(400).json({ error: 'query required', flights: [] });
try {
const response = await fetch('http://localhost:5000/flights', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query })
});
const data = await response.json();
res.json(data);
} catch (err) {
console.error('Flight agent unreachable:', err.message);
res.status(502).json({ error: 'Flight agent unavailable', flights: [] });
}
});
app.post('/api/hotels', async (req, res) => {
const { destination, check_in_date, check_out_date, max_price_per_night } = req.body;
if (!destination) return res.status(400).json({ error: 'destination required', hotels: [] });
try {
const response = await fetch('http://localhost:5000/hotels', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ destination, check_in_date, check_out_date, max_price_per_night })
});
const data = await response.json();
res.json(data);
} catch (err) {
console.error('Hotel search unreachable:', err.message);
res.status(502).json({ error: 'Hotel search unavailable', hotels: [] });
}
});
// ── Health check ─────────────────────────────────────────────────────────────
app.get('/api/health', (req, res) => {
res.json({ status: 'ok', timestamp: new Date().toISOString() });
});
// ── Admin panel ───────────────────────────────────────────────────────────────
app.get('/admin', (req, res) => {
res.sendFile(path.join(__dirname, 'admin.html'));
});
// ── Fallback: serve index.html for SPA routing ────────────────────────────────
app.get('/{*path}', (req, res) => {
res.sendFile(path.join(__dirname, 'public', 'index.html'));
});
// ── Boot ──────────────────────────────────────────────────────────────────────
initDB();
app.listen(PORT, () => {
console.log(`\n🌍 Itinerate backend running on http://localhost:${PORT}`);
console.log(` → API: http://localhost:${PORT}/api/health\n`);
});
module.exports = app;