feat(sync): cron de sincronización automática de números WhatsApp desde PALMAS360
- 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 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
e3d9aac26d
commit
fe4e638667
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once __DIR__ . '/../config/env.php';
|
||||
require_once __DIR__ . '/../config/db.php';
|
||||
require_once __DIR__ . '/../services/CompanyRepository.php';
|
||||
require_once __DIR__ . '/../services/PhoneSync.php';
|
||||
|
||||
$results = PhoneSync::syncAll();
|
||||
|
||||
$ts = date('Y-m-d H:i:s');
|
||||
foreach ($results as $r) {
|
||||
$status = $r['status'];
|
||||
if ($status === 'ok') {
|
||||
echo "[{$ts}] {$r['company']}: {$r['upserted']} upserted, {$r['deactivated']} deactivated\n";
|
||||
} elseif ($status === 'skip') {
|
||||
echo "[{$ts}] {$r['company']}: skip — {$r['reason']}\n";
|
||||
} else {
|
||||
echo "[{$ts}] {$r['company']}: ERROR — {$r['reason']}\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
class PhoneSync
|
||||
{
|
||||
public static function syncAll(): array
|
||||
{
|
||||
$companies = CompanyRepository::findAll();
|
||||
$results = [];
|
||||
|
||||
foreach ($companies as $company) {
|
||||
$results[] = self::syncCompany($company);
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
public static function syncCompany(array $company): array
|
||||
{
|
||||
$companyId = (int)$company['id'];
|
||||
$name = $company['name'] ?? "company {$companyId}";
|
||||
$baseUrl = rtrim($company['api_base_url'] ?? '', '/');
|
||||
$apiKey = $company['api_key'] ?? '';
|
||||
|
||||
if ($baseUrl === '') {
|
||||
return ['company' => $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,
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user