Files
crm.clientright.ru/api_attach_documents.php

252 lines
8.2 KiB
PHP
Raw Normal View History

<?php
/**
* API для привязки документов к проекту/заявке
*
* Использование из n8n:
* POST https://crm.clientright.ru/api_attach_documents.php
*
* Входные данные (JSON массив):
* [
* {
* "contact_id": "320096",
* "project_id": "396868",
* "ticket_id": "396936",
* "filename": "boarding_pass.pdf",
* "file_type": "flight_delay_boarding_or_ticket",
* "file": "/bucket/path/to/file.pdf"
* }
* ]
*/
error_reporting(E_ALL);
ini_set('display_errors', '0');
// Функция для логирования
function log_message($message) {
$timestamp = date('Y-m-d H:i:s');
$line = "[$timestamp] $message\n";
@file_put_contents(__DIR__ . '/logs/api_attach_documents.log', $line, FILE_APPEND | LOCK_EX);
error_log('[api_attach_documents] ' . $message);
}
// Функция для JSON ответа
function json_response($data, $code = 200) {
if (!headers_sent()) {
http_response_code($code);
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type');
}
echo json_encode($data, JSON_UNESCAPED_UNICODE);
exit;
}
// CORS preflight
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
json_response(['status' => 'ok']);
}
// Только POST
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
json_response(['success' => false, 'error' => 'Method not allowed'], 405);
}
log_message('=== START API REQUEST ===');
// Получаем входные данные
$input = file_get_contents('php://input');
log_message('Raw input: ' . substr($input, 0, 500));
$input = ltrim($input, "\xEF\xBB\xBF\x00\x09\x0A\x0D\x20");
$data = json_decode($input, true);
if (json_last_error() !== JSON_ERROR_NONE) {
log_message('❌ JSON Error: ' . json_last_error_msg());
json_response([
'success' => false,
'error' => 'Invalid JSON: ' . json_last_error_msg()
], 400);
}
// Поддерживаем как массив, так и одиночный объект
$documents_array = is_array($data) && isset($data[0]) ? $data : [$data];
log_message('Processing ' . count($documents_array) . ' document(s)');
// Обрабатываем каждый документ
$processed_documents = [];
$S3_HOST = 'https://s3.twcstorage.ru';
foreach ($documents_array as $idx => $doc) {
$contact_id = $doc['contact_id'] ?? null;
$project_id = $doc['project_id'] ?? null;
$ticket_id = $doc['ticket_id'] ?? null;
// Поддерживаем оба формата: file и file_url
$file_path = $doc['file'] ?? $doc['file_url'] ?? null;
if (!$file_path) {
log_message("❌ Document #{$idx}: missing 'file' or 'file_url'");
continue;
}
// Строим полный S3 URL
if (strpos($file_path, 'http') === 0) {
$file_url = $file_path;
} elseif (strpos($file_path, '/') === 0) {
$file_url = $S3_HOST . $file_path;
} else {
$file_url = $S3_HOST . '/' . $file_path;
}
// Поддерживаем оба формата: filename и file_name
$file_name = $doc['filename'] ?? $doc['file_name'] ?? null;
if (!$file_name) {
log_message("❌ Document #{$idx}: missing 'filename' or 'file_name'");
continue;
}
$file_type = $doc['file_type'] ?? 'Документ';
// Валидация обязательных полей
if (!$contact_id || !$project_id) {
log_message("❌ Document #{$idx}: missing contact_id or project_id");
continue;
}
log_message(" [{$idx}] {$file_name} (type: {$file_type})");
log_message(" Contact: {$contact_id}, Project: {$project_id}, Ticket: " . ($ticket_id ?: 'N/A'));
log_message(" File URL: {$file_url}");
$processed_documents[] = [
'url' => $file_url,
'file_name' => $file_name,
'description' => $file_type,
'projectid' => (int)$project_id,
'ticket_id' => $ticket_id ? (int)$ticket_id : null,
'contactid' => (int)$contact_id,
'pages' => 1
];
}
if (empty($processed_documents)) {
log_message('❌ No valid documents to process');
json_response([
'success' => false,
'error' => 'No valid documents to process'
], 400);
}
log_message('📤 Sending ' . count($processed_documents) . ' documents to upload_documents_to_crm.php');
// Формируем запрос к upload_documents_to_crm.php
$upload_url = 'https://crm.clientright.ru/upload_documents_to_crm.php';
// Берем общие параметры из первого документа
$first_doc = $processed_documents[0];
$payload = json_encode([
'documents' => $processed_documents,
'projectid' => $first_doc['projectid'],
'ticket_id' => $first_doc['ticket_id'],
'user_id' => 1
], JSON_UNESCAPED_UNICODE);
log_message('Payload: ' . substr($payload, 0, 500));
// Отправляем запрос
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $upload_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Content-Length: ' . strlen($payload)
]);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($response === false) {
log_message('❌ CURL error: ' . curl_error($ch));
json_response([
'success' => false,
'error' => 'Internal error: ' . curl_error($ch)
], 500);
}
log_message("Response HTTP code: {$http_code}");
log_message("Response: " . substr($response, 0, 500));
// Парсим ответ
$result = json_decode($response, true);
if (json_last_error() !== JSON_ERROR_NONE) {
log_message('❌ Failed to parse response JSON: ' . json_last_error_msg());
json_response([
'success' => false,
'error' => 'Invalid response from upload service'
], 500);
}
// Проверяем успешность
if ($result && $result['success'] && isset($result['results'])) {
$results_array = $result['results'];
// Формируем ответ
$processed_results = [];
$errors = [];
foreach ($results_array as $idx => $res) {
if ($res['status'] === 'success') {
$crm_result = $res['crm_result'] ?? [];
$processed_results[] = [
'document_id' => $crm_result['document_id'] ?? null,
'document_numeric_id' => $crm_result['document_numeric_id'] ?? null,
'attached_to' => isset($res['ticket_id']) && $res['ticket_id'] ? 'ticket' : 'project',
'attached_to_id' => $res['ticket_id'] ?? $res['projectid'] ?? null,
'file_name' => $res['file_name'] ?? null,
'file_type' => $res['description'] ?? null,
's3_bucket' => $crm_result['s3_bucket'] ?? null,
's3_key' => $crm_result['s3_key'] ?? null,
'file_size' => $crm_result['file_size'] ?? null,
'message' => $crm_result['message'] ?? null
];
log_message(" ✅ [{$idx}] {$res['file_name']}{$crm_result['document_id']}");
} else {
$error_msg = $res['crm_result']['message'] ?? 'Unknown error';
$errors[] = [
'file_name' => $res['file_name'] ?? 'Unknown',
'error' => $error_msg
];
log_message(" ❌ [{$idx}] {$res['file_name']}: {$error_msg}");
}
}
log_message('✅ Success: ' . count($processed_results) . ' documents attached');
json_response([
'success' => true,
'total_processed' => count($results_array),
'successful' => count($processed_results),
'failed' => count($errors),
'results' => $processed_results,
'errors' => !empty($errors) ? $errors : null
]);
} else {
log_message('❌ Upload failed: ' . ($result['error']['message'] ?? 'Unknown error'));
json_response([
'success' => false,
'error' => $result['error']['message'] ?? 'Upload failed'
], 500);
}