fetchAll( "SELECT * FROM media_queue WHERE (status = 'pending' OR (status = 'failed' AND (attempts IS NULL OR attempts < 5))) ORDER BY created_at ASC LIMIT 10" ); if (empty($rows)) { echo date('Y-m-d H:i:s') . " - No pending media jobs\n"; exit(0); } $ms = new MediaService(); $processed = 0; $success = 0; $failed = 0; foreach ($rows as $idx => $r) { // Pausa entre items para evitar saturar conexiones a Facebook if ($idx > 0) sleep(2); $processed++; $attempts = intval($r['attempts'] ?? 0) + 1; try { // Marcar como procesando $db->query("UPDATE media_queue SET status = 'processing', attempts = :att WHERE id = :id", ['att' => $attempts, 'id' => $r['id']]); $res = null; if (!empty($r['media_id'])) { $res = $ms->fetchAndStoreFromGraph($r['media_id'], $r['subdir'] ?? date('Y/m')); } elseif (!empty($r['media_url'])) { if (preg_match('/^\d+$/', $r['media_url'])) { $res = $ms->fetchAndStoreFromGraph($r['media_url'], $r['subdir'] ?? date('Y/m')); } else { $res = $ms->fetchAndStoreFromUrl($r['media_url'], $r['subdir'] ?? date('Y/m')); } } if ($res && !empty($res['local_file'])) { // Éxito $db->query( "UPDATE media_queue SET status = 'done', result = :res WHERE id = :id", ['res' => json_encode($res), 'id' => $r['id']] ); // Actualizar conversations con el archivo local if (!empty($r['conversation_id'])) { $update = ['local_file' => $res['local_file']]; if (!empty($res['local_thumb'])) $update['local_thumb'] = $res['local_thumb']; if (!empty($res['mime_type'])) $update['mime_type'] = $res['mime_type']; $db->update('conversations', $update, 'id = :id', ['id' => $r['conversation_id']]); echo date('Y-m-d H:i:s') . " - OK Media #{$r['id']} -> {$res['local_file']} (conv:{$r['conversation_id']})\n"; } else { // Sin conversation_id: buscar por media_id/media_url $mediaRef = !empty($r['media_id']) ? $r['media_id'] : $r['media_url']; if ($mediaRef) { try { $db->query( "UPDATE conversations SET local_file = :lf, local_thumb = :lt, mime_type = :mt WHERE (media_url = :mid OR whatsapp_media_id = :mid2) AND (local_file IS NULL OR local_file = '') LIMIT 5", [ 'lf' => $res['local_file'], 'lt' => $res['local_thumb'] ?? null, 'mt' => $res['mime_type'] ?? null, 'mid' => $mediaRef, 'mid2' => $mediaRef ] ); } catch (Exception $e) { error_log("[media_worker] Error updating conversations: " . $e->getMessage()); } } echo date('Y-m-d H:i:s') . " - OK Media #{$r['id']} -> {$res['local_file']} (sin conv_id)\n"; } $success++; } else { throw new Exception('Download returned empty result'); } } catch (Exception $e) { $failed++; $status = ($attempts >= 5) ? 'permanently_failed' : 'failed'; $db->query( "UPDATE media_queue SET status = :st, attempts = :att, result = :res WHERE id = :id", ['st' => $status, 'att' => $attempts, 'res' => json_encode(['error' => $e->getMessage()]), 'id' => $r['id']] ); echo date('Y-m-d H:i:s') . " - FAIL Media #{$r['id']} attempt {$attempts}: " . $e->getMessage() . "\n"; } } echo date('Y-m-d H:i:s') . " - Processed {$processed}: {$success} ok, {$failed} failed\n";