From fe4e638667aaf71736629baff855c3e63146a504 Mon Sep 17 00:00:00 2001 From: Lizandro Guarnizo <77708265+lizandrogd@users.noreply.github.com> Date: Tue, 28 Jul 2026 22:10:04 -0500 Subject: [PATCH] =?UTF-8?q?feat(sync):=20cron=20de=20sincronizaci=C3=B3n?= =?UTF-8?q?=20autom=C3=A1tica=20de=20n=C3=BAmeros=20WhatsApp=20desde=20PAL?= =?UTF-8?q?MAS360?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - PhoneSync::syncAll() itera todas las empresas activas, llama a whatsapp_numeros de cada ERP y hace UPSERT en company_phones - Números eliminados en PALMAS360 quedan is_active=0 automáticamente - cron/sync_phones.php es el entry point; configurar cada 5 min en crontab Co-Authored-By: Claude Sonnet 4.6 --- cron/sync_phones.php | 21 ++++++++ services/PhoneSync.php | 107 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 cron/sync_phones.php create mode 100644 services/PhoneSync.php diff --git a/cron/sync_phones.php b/cron/sync_phones.php new file mode 100644 index 0000000..c467f64 --- /dev/null +++ b/cron/sync_phones.php @@ -0,0 +1,21 @@ + $name, 'status' => 'skip', 'reason' => 'sin api_base_url']; + } + + $url = $baseUrl . '/php/controller/controller_api_externa.php?peticion=whatsapp_numeros'; + + $ch = curl_init($url); + curl_setopt_array($ch, [ + CURLOPT_RETURNTRANSFER => true, + CURLOPT_TIMEOUT => 15, + CURLOPT_HTTPHEADER => [ + 'Accept: application/json', + 'Authorization: Bearer ' . $apiKey, + 'X-API-Key: ' . $apiKey, + ], + ]); + $body = curl_exec($ch); + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + $curlErr = curl_error($ch); + curl_close($ch); + + if ($curlErr !== '') { + return ['company' => $name, 'status' => 'error', 'reason' => 'cURL: ' . $curlErr]; + } + if ($httpCode !== 200) { + return ['company' => $name, 'status' => 'error', 'reason' => "HTTP {$httpCode}"]; + } + + $data = json_decode((string)$body, true); + if (!is_array($data) || ($data['status'] ?? '') !== '1') { + $msg = $data['mensaje'] ?? $data['message'] ?? 'respuesta inválida'; + return ['company' => $name, 'status' => 'error', 'reason' => $msg]; + } + + $numeros = $data['numeros'] ?? []; + if (empty($numeros)) { + return ['company' => $name, 'status' => 'ok', 'upserted' => 0, 'deactivated' => 0]; + } + + $db = db(); + $upsert = $db->prepare(" + INSERT INTO company_phones (company_id, wa_number, label, permission_type, is_active) + VALUES (?, ?, ?, ?, 1) + ON DUPLICATE KEY UPDATE + label = VALUES(label), + permission_type = VALUES(permission_type), + is_active = 1 + "); + + $activeNumbers = []; + foreach ($numeros as $n) { + $waNumber = trim($n['wa_number'] ?? ''); + if ($waNumber === '') continue; + + $upsert->execute([ + $companyId, + $waNumber, + trim($n['nombre'] ?? ''), + (int)($n['permiso'] ?? 1), + ]); + $activeNumbers[] = $waNumber; + } + + // Deactivate numbers removed from PALMAS360 + $deactivated = 0; + if (!empty($activeNumbers)) { + $placeholders = implode(',', array_fill(0, count($activeNumbers), '?')); + $stmt = $db->prepare(" + UPDATE company_phones SET is_active = 0 + WHERE company_id = ? AND is_active = 1 AND wa_number NOT IN ({$placeholders}) + "); + $stmt->execute(array_merge([$companyId], $activeNumbers)); + $deactivated = $stmt->rowCount(); + } + + return [ + 'company' => $name, + 'status' => 'ok', + 'upserted' => count($activeNumbers), + 'deactivated' => $deactivated, + ]; + } +}