import { db } from '../db'; // Environment variables will be mocked in tests const env = process.env; type EvolutionGroup = { id: string; subject: string; linkedParent?: string; // Other fields from API response }; export class GroupSyncService { private static readonly SYNC_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24 hours private static lastSyncAttempt = 0; static async syncGroups(): Promise<{ added: number; updated: number }> { if (!this.shouldSync()) { return { added: 0, updated: 0 }; } try { const communityId = env.WHATSAPP_COMMUNITY_ID; if (!communityId) { throw new Error('WHATSAPP_COMMUNITY_ID is not set'); } const groups = await this.fetchGroupsFromAPI(); const communityGroups = groups.filter( (group) => group.linkedParent === communityId ); return await this.upsertGroups(communityGroups); } catch (error) { console.error('Group sync failed:', error); throw error; } finally { this.lastSyncAttempt = Date.now(); } } private static shouldSync(): boolean { const timeSinceLastSync = Date.now() - this.lastSyncAttempt; return timeSinceLastSync > this.SYNC_INTERVAL_MS; } private static async fetchGroupsFromAPI(): Promise { const url = `${env.EVOLUTION_API_URL}/group/fetchAllGroups/${env.EVOLUTION_API_INSTANCE}?getParticipants=false`; const response = await fetch(url, { headers: { apikey: env.EVOLUTION_API_KEY, }, }); if (!response.ok) { throw new Error(`API request failed: ${response.statusText}`); } const data = await response.json(); if (data.status !== 'success') { throw new Error(`API error: ${data.message || 'Unknown error'}`); } return data.response; } private static async upsertGroups(groups: EvolutionGroup[]): Promise<{ added: number; updated: number }> { let added = 0; let updated = 0; const transactionResult = db.transaction(() => { // First mark all groups as inactive and update verification timestamp const inactiveResult = db.prepare(` UPDATE groups SET active = FALSE, last_verified = CURRENT_TIMESTAMP `).run(); console.log('Marked groups inactive:', inactiveResult); for (const group of groups) { const existing = db.prepare('SELECT 1 FROM groups WHERE id = ?').get(group.id); console.log('Checking group:', group.id, 'exists:', !!existing); if (existing) { const updateResult = db.prepare( 'UPDATE groups SET name = ?, active = TRUE, last_verified = CURRENT_TIMESTAMP WHERE id = ?' ).run(group.subject, group.id); console.log('Updated group:', group.id, 'result:', updateResult); updated++; } else { const insertResult = db.prepare( 'INSERT INTO groups (id, community_id, name, active) VALUES (?, ?, ?, TRUE)' ).run(group.id, env.WHATSAPP_COMMUNITY_ID, group.subject); console.log('Added group:', group.id, 'result:', insertResult); added++; } } return { added, updated }; }); try { const result = transactionResult(); console.log(`Group sync completed: ${result.added} added, ${result.updated} updated`); return result; } catch (error) { console.error('Error in upsertGroups:', error); throw error; } } }