const axios = require('axios'); const { createClient } = require('redis'); const Gorgias = require('../models/gorgias.model'); const logger = require('../utils/logger'); class GorgiasService { constructor() { this.redis = createClient({ url: process.env.REDIS_URL }); this.redis.on('error', err => logger.error('Redis Client Error:', err)); this.redis.connect().catch(err => logger.error('Redis connection error:', err)); this.apiClient = axios.create({ baseURL: 'https://acherryontop.gorgias.com/api', auth: { username: process.env.GORGIAS_API_USERNAME, password: process.env.GORGIAS_API_PASSWORD } }); } async getStatistics(name, filters = {}) { const cacheKey = `gorgias:stats:${name}:${JSON.stringify(filters)}`; logger.info(`Attempting to fetch statistics for ${name}`, { filters, cacheKey }); try { // Try Redis first const cachedData = await this.redis.get(cacheKey); if (cachedData) { logger.info(`Statistics ${name} found in Redis cache`); return JSON.parse(cachedData); } // Check MongoDB const mongoData = await Gorgias.findValidCache(name, filters); if (mongoData) { logger.info(`Statistics ${name} found in MongoDB`); const formattedData = mongoData.formatResponse(); await this.redis.set(cacheKey, JSON.stringify(formattedData), { EX: Gorgias.getCacheDuration(name) }); return formattedData; } // Fetch from API const response = await this.apiClient.post(`/stats/${name}`, { filters }); // Save to MongoDB const doc = await Gorgias.create({ type: name, params: filters, data: response.data }); const formattedData = doc.formatResponse(); // Save to Redis await this.redis.set(cacheKey, JSON.stringify(formattedData), { EX: Gorgias.getCacheDuration(name) }); return formattedData; } catch (error) { logger.error(`Error in getStatistics for ${name}:`, { error: error.message, stack: error.stack, filters, response: error.response?.data }); throw error; } } async getTickets() { const cacheKey = 'gorgias:tickets'; try { // Try Redis first const cachedData = await this.redis.get(cacheKey); if (cachedData) { logger.info('Tickets found in Redis cache'); return JSON.parse(cachedData); } // Check MongoDB const mongoData = await Gorgias.findValidCache('tickets'); if (mongoData) { logger.info('Tickets found in MongoDB'); const formattedData = mongoData.formatResponse(); await this.redis.set(cacheKey, JSON.stringify(formattedData), { EX: Gorgias.getCacheDuration('tickets') }); return formattedData; } // Fetch from API const response = await this.apiClient.get('/tickets'); // Save to MongoDB const doc = await Gorgias.create({ type: 'tickets', data: response.data }); const formattedData = doc.formatResponse(); // Save to Redis await this.redis.set(cacheKey, JSON.stringify(formattedData), { EX: Gorgias.getCacheDuration('tickets') }); return formattedData; } catch (error) { logger.error('Error fetching tickets:', { error: error.message, stack: error.stack }); throw error; } } } module.exports = new GorgiasService();