|
|
|
@ -72,8 +72,8 @@ export class GroupSyncService {
|
|
|
|
private static _membersTimer: any = null;
|
|
|
|
private static _membersTimer: any = null;
|
|
|
|
private static _membersSchedulerRunning = false;
|
|
|
|
private static _membersSchedulerRunning = false;
|
|
|
|
|
|
|
|
|
|
|
|
static async syncGroups(): Promise<{ added: number; updated: number }> {
|
|
|
|
static async syncGroups(force: boolean = false): Promise<{ added: number; updated: number }> {
|
|
|
|
if (!this.shouldSync()) {
|
|
|
|
if (!this.shouldSync(force)) {
|
|
|
|
return { added: 0, updated: 0 };
|
|
|
|
return { added: 0, updated: 0 };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const startedAt = Date.now();
|
|
|
|
const startedAt = Date.now();
|
|
|
|
@ -85,6 +85,8 @@ export class GroupSyncService {
|
|
|
|
console.log('ℹ️ WHATSAPP_COMMUNITY_ID no definido - mostrando todas las comunidades');
|
|
|
|
console.log('ℹ️ WHATSAPP_COMMUNITY_ID no definido - mostrando todas las comunidades');
|
|
|
|
const groups = await this.fetchGroupsFromAPI();
|
|
|
|
const groups = await this.fetchGroupsFromAPI();
|
|
|
|
const communities = groups.filter(g => g.linkedParent);
|
|
|
|
const communities = groups.filter(g => g.linkedParent);
|
|
|
|
|
|
|
|
// Intento best-effort de rellenar labels faltantes en allowed_groups usando la lista completa
|
|
|
|
|
|
|
|
try { (AllowedGroups as any).dbInstance = this.dbInstance; this.fillMissingAllowedGroupLabels(groups); } catch {}
|
|
|
|
return { added: 0, updated: 0 }; // No sync when just listing
|
|
|
|
return { added: 0, updated: 0 }; // No sync when just listing
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -115,6 +117,9 @@ export class GroupSyncService {
|
|
|
|
const dbGroupsAfter = this.dbInstance.prepare('SELECT id, active FROM groups').all();
|
|
|
|
const dbGroupsAfter = this.dbInstance.prepare('SELECT id, active FROM groups').all();
|
|
|
|
console.log('ℹ️ Grupos en DB después de upsert:', dbGroupsAfter);
|
|
|
|
console.log('ℹ️ Grupos en DB después de upsert:', dbGroupsAfter);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Completar labels faltantes en allowed_groups usando todos los grupos devueltos por la API
|
|
|
|
|
|
|
|
try { (AllowedGroups as any).dbInstance = this.dbInstance; this.fillMissingAllowedGroupLabels(groups); } catch {}
|
|
|
|
|
|
|
|
|
|
|
|
// Actualizar métricas
|
|
|
|
// Actualizar métricas
|
|
|
|
this.cacheActiveGroups();
|
|
|
|
this.cacheActiveGroups();
|
|
|
|
Metrics.set('active_groups', this.activeGroupsCache.size);
|
|
|
|
Metrics.set('active_groups', this.activeGroupsCache.size);
|
|
|
|
@ -136,7 +141,8 @@ export class GroupSyncService {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static shouldSync(): boolean {
|
|
|
|
private static shouldSync(force: boolean = false): boolean {
|
|
|
|
|
|
|
|
if (force) return true;
|
|
|
|
const timeSinceLastSync = Date.now() - this.lastSyncAttempt;
|
|
|
|
const timeSinceLastSync = Date.now() - this.lastSyncAttempt;
|
|
|
|
const shouldSync = timeSinceLastSync > this.SYNC_INTERVAL_MS;
|
|
|
|
const shouldSync = timeSinceLastSync > this.SYNC_INTERVAL_MS;
|
|
|
|
|
|
|
|
|
|
|
|
@ -230,6 +236,47 @@ export class GroupSyncService {
|
|
|
|
console.log(`Cached ${this.activeGroupsCache.size} active groups`);
|
|
|
|
console.log(`Cached ${this.activeGroupsCache.size} active groups`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Rellena labels faltantes en allowed_groups a partir de los grupos devueltos por la API.
|
|
|
|
|
|
|
|
private static fillMissingAllowedGroupLabels(allGroups: EvolutionGroup[]): number {
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
if (!Array.isArray(allGroups) || allGroups.length === 0) return 0;
|
|
|
|
|
|
|
|
const nameById = new Map<string, string>();
|
|
|
|
|
|
|
|
for (const g of allGroups) {
|
|
|
|
|
|
|
|
if (!g?.id) continue;
|
|
|
|
|
|
|
|
const name = String(g.subject || '').trim();
|
|
|
|
|
|
|
|
if (!name) continue;
|
|
|
|
|
|
|
|
nameById.set(String(g.id), name);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nameById.size === 0) return 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const rows = this.dbInstance.prepare(`
|
|
|
|
|
|
|
|
SELECT group_id AS id
|
|
|
|
|
|
|
|
FROM allowed_groups
|
|
|
|
|
|
|
|
WHERE label IS NULL OR TRIM(label) = ''
|
|
|
|
|
|
|
|
`).all() as any[];
|
|
|
|
|
|
|
|
if (!rows || rows.length === 0) return 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let filled = 0;
|
|
|
|
|
|
|
|
for (const r of rows) {
|
|
|
|
|
|
|
|
const id = r?.id ? String(r.id) : null;
|
|
|
|
|
|
|
|
if (!id) continue;
|
|
|
|
|
|
|
|
const label = nameById.get(id);
|
|
|
|
|
|
|
|
if (label) {
|
|
|
|
|
|
|
|
try { (AllowedGroups as any).dbInstance = this.dbInstance; AllowedGroups.upsertPending(id, label, null); } catch {}
|
|
|
|
|
|
|
|
filled++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (filled > 0) {
|
|
|
|
|
|
|
|
try { Metrics.inc('allowed_groups_labels_filled_total', filled); } catch {}
|
|
|
|
|
|
|
|
console.log(`ℹ️ Rellenadas ${filled} labels faltantes en allowed_groups`);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return filled;
|
|
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
|
|
console.warn('⚠️ No se pudieron rellenar labels faltantes en allowed_groups:', e);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static getActiveGroupsCount(): number {
|
|
|
|
private static getActiveGroupsCount(): number {
|
|
|
|
const result = this.dbInstance.prepare('SELECT COUNT(*) as count FROM groups WHERE active = TRUE').get();
|
|
|
|
const result = this.dbInstance.prepare('SELECT COUNT(*) as count FROM groups WHERE active = TRUE').get();
|
|
|
|
return result?.count || 0;
|
|
|
|
return result?.count || 0;
|
|
|
|
|