import express from 'express'; import cors from 'cors'; import dotenv from 'dotenv'; import rateLimit from 'express-rate-limit'; import { createApiRouter } from './routes/index.js'; import path from 'path'; import { fileURLToPath } from 'url'; // Get directory name in ES modules const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); // Load environment variables const envPath = path.resolve(__dirname, '.env'); console.log('[Server] Loading .env file from:', envPath); dotenv.config({ path: envPath }); // Debug environment variables (without exposing sensitive data) console.log('[Server] Environment variables loaded:', { REDIS_HOST: process.env.REDIS_HOST || '(not set)', REDIS_PORT: process.env.REDIS_PORT || '(not set)', REDIS_USERNAME: process.env.REDIS_USERNAME || '(not set)', REDIS_PASSWORD: process.env.REDIS_PASSWORD ? '(set)' : '(not set)', NODE_ENV: process.env.NODE_ENV || '(not set)', }); const app = express(); const port = process.env.KLAVIYO_PORT || 3004; // Rate limiting for reporting endpoints const reportingLimiter = rateLimit({ windowMs: 10 * 60 * 1000, // 10 minutes max: 10, // limit each IP to 10 requests per windowMs message: 'Too many requests to reporting endpoint, please try again later', keyGenerator: (req) => { // Use a combination of IP and endpoint for more granular control return `${req.ip}-reporting`; }, skip: (req) => { // Only apply to campaign-values-reports endpoint return !req.path.includes('campaign-values-reports'); } }); // Middleware app.use(cors()); app.use(express.json()); // Debug middleware to log all requests app.use((req, res, next) => { console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`); next(); }); // Apply rate limiting to reporting endpoints app.use('/api/klaviyo/reporting', reportingLimiter); // Create and mount API routes const apiRouter = createApiRouter( process.env.KLAVIYO_API_KEY, process.env.KLAVIYO_API_REVISION || '2024-02-15' ); app.use('/api/klaviyo', apiRouter); // Error handling middleware app.use((err, req, res, next) => { console.error('Unhandled error:', err); res.status(500).json({ status: 'error', message: 'Internal server error', details: process.env.NODE_ENV === 'development' ? err.message : undefined }); }); // Start server app.listen(port, '0.0.0.0', () => { console.log(`Klaviyo server listening at http://0.0.0.0:${port}`); });