From 4644e7a588b13d6d4912f0dfe241ad35810a000d Mon Sep 17 00:00:00 2001 From: "borja (aider)" Date: Sat, 29 Mar 2025 22:19:01 +0100 Subject: [PATCH] feat: add group sync service with API integration --- src/services/group-sync.ts | 90 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 src/services/group-sync.ts diff --git a/src/services/group-sync.ts b/src/services/group-sync.ts new file mode 100644 index 0000000..53747fd --- /dev/null +++ b/src/services/group-sync.ts @@ -0,0 +1,90 @@ +import { db } from '../db'; +import { env } from '../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}`); + } + + return response.json(); + } + + private static async upsertGroups(groups: EvolutionGroup[]): Promise<{ added: number; updated: number }> { + let added = 0; + let updated = 0; + + db.transaction(() => { + // First mark all groups as inactive + db.exec('UPDATE groups SET active = FALSE'); + + for (const group of groups) { + const existing = db.query('SELECT 1 FROM groups WHERE id = ?').get(group.id); + + if (existing) { + db.exec( + 'UPDATE groups SET name = ?, active = TRUE, last_verified = CURRENT_TIMESTAMP WHERE id = ?', + [group.subject, group.id] + ); + updated++; + } else { + db.exec( + 'INSERT INTO groups (id, community_id, name, active) VALUES (?, ?, ?, TRUE)', + [group.id, env.WHATSAPP_COMMUNITY_ID, group.subject] + ); + added++; + } + } + }); + + console.log(`Group sync completed: ${added} added, ${updated} updated`); + return { added, updated }; + } +}