getConnection(); $bufferPrevio = $conn->getAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY); $conn->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false); $leidos = 0; try { $stmt = $conn->query( "SELECT request_body FROM webhook_logs WHERE request_body LIKE '%user_id%' AND request_body LIKE '%\"messages\"%'" ); while ($fila = $stmt->fetch(PDO::FETCH_ASSOC)) { $leidos++; if ($leidos % 50000 === 0) printf(" ...%d registros\n", $leidos); $d = json_decode($fila['request_body'], true); if (!$d) continue; foreach ($d['entry'] ?? [] as $entry) { foreach ($entry['changes'] ?? [] as $cambio) { $v = $cambio['value'] ?? []; // El teléfono puede venir en contacts[].wa_id o en messages[].from foreach ($v['contacts'] ?? [] as $c) { if (!empty($c['user_id']) && !empty($c['wa_id'])) { $mapa[$c['user_id']] = $c['wa_id']; } } foreach ($v['messages'] ?? [] as $m) { $uid = $m['from_user_id'] ?? null; if (!$uid) continue; if (!empty($m['from'])) $mapa[$uid] = $m['from']; else $sinTelefono[$uid] = true; } // Cuando alguien comparte su contacto, el teléfono llega aquí foreach ($v['messages'] ?? [] as $m) { if (($m['type'] ?? '') !== 'contacts') continue; $uid = $m['from_user_id'] ?? null; foreach ($m['contacts'] ?? [] as $c) { foreach ($c['phones'] ?? [] as $t) { $num = $t['wa_id'] ?? ($t['phone'] ?? null); if ($uid && $num) $mapa[$uid] = preg_replace('/[^0-9]/', '', $num); } } } } } } $stmt->closeCursor(); } finally { // Dejar la conexión como estaba: las escrituras siguientes la necesitan con buffer $conn->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, $bufferPrevio); } printf("\n registros revisados: %d\n", $leidos); printf(" equivalencias encontradas: %d\n", count($mapa)); printf(" personas que llegaron sin teléfono: %d\n\n", count($sinTelefono)); // --- 2. Escribir el BSUID en el usuario que corresponde --- $marcados = 0; $noExisten = 0; $yaEstaban = 0; $conflictos = 0; foreach ($mapa as $bsuid => $telefono) { $u = $db->fetch("SELECT id, bsuid FROM users WHERE phone_number = :t", ['t' => $telefono]); if (!$u) { $noExisten++; continue; } if ($u['bsuid'] === $bsuid) { $yaEstaban++; continue; } if (!empty($u['bsuid'])) { // El BSUID se regenera si la persona cambia de número: gana el más reciente printf(" aviso: %s tenía %s y ahora %s\n", $telefono, $u['bsuid'], $bsuid); $conflictos++; } if (!$simular) { try { $db->update('users', ['bsuid' => $bsuid], 'id = ?', [$u['id']]); } catch (Exception $e) { printf(" error en %s: %s\n", $telefono, $e->getMessage()); continue; } } $marcados++; } printf("\n usuarios marcados con su BSUID: %d\n", $marcados); printf(" ya lo tenían: %d\n", $yaEstaban); printf(" sin usuario en la base: %d\n", $noExisten); printf(" BSUID reemplazados (cambio de número): %d\n", $conflictos); // --- 3. ¿A cuántos de los perdidos rescatamos? --- $rescatables = array_intersect_key($mapa, $sinTelefono); printf("\n de los que llegaron sin teléfono, quedan identificados: %d\n", count($rescatables)); foreach ($rescatables as $b => $t) { printf(" %-24s → %s\n", $b, substr($t, 0, -4) . '****'); } $pendientes = array_diff_key($sinTelefono, $mapa); printf("\n siguen sin identificar: %d (hay que pedirles el contacto)\n", count($pendientes)); echo $simular ? "\nSimulación terminada, no se escribió nada.\n" : "\nListo.\n";