'Method not allowed']); exit; } // Получаем данные webhook $input = file_get_contents('php://input'); $data = json_decode($input, true); logWebhook("Webhook received: " . $input); if (!$data) { http_response_code(400); echo json_encode(['error' => 'Invalid JSON']); exit; } // Проверяем обязательные поля if (!isset($data['action']) || !isset($data['file_path'])) { http_response_code(400); echo json_encode(['error' => 'Missing required fields']); exit; } $action = $data['action']; $filePath = $data['file_path']; $projectId = isset($data['project_id']) ? $data['project_id'] : null; logWebhook("Processing action: $action, path: $filePath, project: $projectId"); // Создаем событие для SSE $event = [ 'type' => $action, 'data' => [ 'module' => 'Project', 'recordId' => $projectId ?: '123', 'documentId' => '456', 'fileName' => basename($filePath) ], 'timestamp' => time() ]; // Сохраняем событие в файл для SSE endpoint с блокировкой $eventsFile = '/tmp/crm_sse_events.json'; // Открываем файл с блокировкой $fp = fopen($eventsFile, 'c+'); if ($fp && flock($fp, LOCK_EX)) { // Читаем текущие события $content = stream_get_contents($fp); $events = []; if (!empty($content)) { $events = json_decode($content, true) ?: []; } // Добавляем новое событие $events[] = $event; // Записываем обратно ftruncate($fp, 0); rewind($fp); fwrite($fp, json_encode($events)); // Освобождаем блокировку flock($fp, LOCK_UN); fclose($fp); logWebhook("Event saved to SSE queue: " . json_encode($event)); } else { logWebhook("ERROR: Failed to lock events file"); if ($fp) fclose($fp); } // Отправляем успешный ответ http_response_code(200); echo json_encode(['status' => 'success', 'message' => 'Event processed']); ?>