187 lines
9.0 KiB
HTML
187 lines
9.0 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="ru">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Отладка ответа n8n</title>
|
||
<style>
|
||
body { font-family: Arial, sans-serif; margin: 20px; }
|
||
.debug-section { margin: 20px 0; padding: 15px; border: 1px solid #ddd; border-radius: 5px; }
|
||
.success { background-color: #d4edda; border-color: #c3e6cb; }
|
||
.error { background-color: #f8d7da; border-color: #f5c6cb; }
|
||
.info { background-color: #d1ecf1; border-color: #bee5eb; }
|
||
button { padding: 10px 20px; margin: 5px; cursor: pointer; }
|
||
pre { background: #f8f9fa; padding: 10px; border-radius: 3px; overflow-x: auto; white-space: pre-wrap; }
|
||
.response-box { border: 2px solid #007bff; padding: 10px; margin: 10px 0; border-radius: 5px; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<h1>🔍 Отладка ответа n8n</h1>
|
||
|
||
<div class="debug-section info">
|
||
<h3>📋 Проблема</h3>
|
||
<p>n8n возвращает <code>[object Object]</code> вместо текста. Нужно понять структуру ответа.</p>
|
||
</div>
|
||
|
||
<div class="debug-section">
|
||
<h3>🧪 Тест с таймаутом</h3>
|
||
<button onclick="testWithTimeout()">Тест с таймаутом 2 минуты</button>
|
||
<div id="timeout-result"></div>
|
||
</div>
|
||
|
||
<div class="debug-section">
|
||
<h3>📊 Анализ ответа</h3>
|
||
<button onclick="analyzeResponse()">Анализировать структуру ответа</button>
|
||
<div id="analysis-result"></div>
|
||
</div>
|
||
|
||
<div class="debug-section">
|
||
<h3>🎯 Симуляция ответа n8n</h3>
|
||
<button onclick="simulateN8NResponse()">Симулировать разные форматы ответа</button>
|
||
<div id="simulation-result"></div>
|
||
</div>
|
||
|
||
<script>
|
||
async function testWithTimeout() {
|
||
const resultDiv = document.getElementById('timeout-result');
|
||
resultDiv.innerHTML = '<p>⏳ Тестируем с таймаутом 2 минуты... (n8n может обрабатывать AI запросы долго)</p>';
|
||
|
||
try {
|
||
const controller = new AbortController();
|
||
const timeoutId = setTimeout(() => controller.abort(), 120000); // 2 минуты
|
||
|
||
const response = await fetch('/aiassist/n8n_proxy.php', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({
|
||
message: 'что ты умеешь?',
|
||
context: { projectId: '391604', module: 'Project' },
|
||
sessionId: 'debug-test-' + Date.now()
|
||
}),
|
||
signal: controller.signal
|
||
});
|
||
|
||
clearTimeout(timeoutId);
|
||
|
||
if (response.ok) {
|
||
const data = await response.json();
|
||
resultDiv.innerHTML = `
|
||
<div class="success">
|
||
<h4>✅ Ответ получен!</h4>
|
||
<div class="response-box">
|
||
<strong>Текст ответа:</strong><br>
|
||
<pre>${data.response}</pre>
|
||
</div>
|
||
<div class="response-box">
|
||
<strong>Сырой ответ n8n:</strong><br>
|
||
<pre>${JSON.stringify(data.rawResponse, null, 2)}</pre>
|
||
</div>
|
||
</div>
|
||
`;
|
||
} else {
|
||
resultDiv.innerHTML = `<div class="error"><h4>❌ Ошибка HTTP ${response.status}</h4><p>${await response.text()}</p></div>`;
|
||
}
|
||
} catch (error) {
|
||
if (error.name === 'AbortError') {
|
||
resultDiv.innerHTML = '<div class="error"><h4>⏰ Таймаут - n8n не отвечает за 2 минуты</h4><p>Возможно, n8n webhook не настроен, не активен или AI обработка занимает очень много времени.</p></div>';
|
||
} else {
|
||
resultDiv.innerHTML = `<div class="error"><h4>❌ Ошибка подключения</h4><p>${error.message}</p></div>`;
|
||
}
|
||
}
|
||
}
|
||
|
||
function analyzeResponse() {
|
||
const resultDiv = document.getElementById('analysis-result');
|
||
|
||
const possibleFormats = [
|
||
{ name: 'Стандартный', data: { output: 'Привет! Я умею помогать с CRM.' } },
|
||
{ name: 'С массивом', data: { output: ['Строка 1', 'Строка 2'] } },
|
||
{ name: 'С объектом', data: { output: { text: 'Текст ответа', type: 'message' } } },
|
||
{ name: 'С message', data: { message: 'Ответ в поле message' } },
|
||
{ name: 'С text', data: { text: 'Ответ в поле text' } },
|
||
{ name: 'С response', data: { response: 'Ответ в поле response' } },
|
||
{ name: 'Сложный объект', data: {
|
||
output: {
|
||
message: 'Основной текст',
|
||
metadata: { source: 'ai', confidence: 0.95 }
|
||
}
|
||
}}
|
||
];
|
||
|
||
let analysis = '<h4>📊 Анализ возможных форматов ответа n8n:</h4>';
|
||
|
||
possibleFormats.forEach(format => {
|
||
const processed = processN8NResponse(format.data);
|
||
analysis += `
|
||
<div class="response-box">
|
||
<strong>${format.name}:</strong><br>
|
||
<pre>Исходный: ${JSON.stringify(format.data, null, 2)}</pre>
|
||
<pre>Обработанный: ${processed}</pre>
|
||
</div>
|
||
`;
|
||
});
|
||
|
||
resultDiv.innerHTML = analysis;
|
||
}
|
||
|
||
function processN8NResponse(responseData) {
|
||
let responseText = '';
|
||
|
||
if (responseData.output) {
|
||
if (typeof responseData.output === 'string') {
|
||
responseText = responseData.output;
|
||
} else if (Array.isArray(responseData.output)) {
|
||
responseText = responseData.output.join('\n');
|
||
} else if (typeof responseData.output === 'object') {
|
||
responseText = JSON.stringify(responseData.output, null, 2);
|
||
}
|
||
} else if (responseData.message) {
|
||
responseText = typeof responseData.message === 'string' ?
|
||
responseData.message : JSON.stringify(responseData.message, null, 2);
|
||
} else if (responseData.text) {
|
||
responseText = typeof responseData.text === 'string' ?
|
||
responseData.text : JSON.stringify(responseData.text, null, 2);
|
||
} else if (responseData.response) {
|
||
responseText = typeof responseData.response === 'string' ?
|
||
responseData.response : JSON.stringify(responseData.response, null, 2);
|
||
} else {
|
||
responseText = JSON.stringify(responseData, null, 2);
|
||
}
|
||
|
||
return responseText;
|
||
}
|
||
|
||
function simulateN8NResponse() {
|
||
const resultDiv = document.getElementById('simulation-result');
|
||
|
||
const testCases = [
|
||
{ name: 'Простой текст', response: { output: 'Я умею помогать с CRM!' } },
|
||
{ name: 'Массив строк', response: { output: ['Строка 1', 'Строка 2', 'Строка 3'] } },
|
||
{ name: 'Объект с текстом', response: { output: { text: 'Текст ответа', type: 'message' } } },
|
||
{ name: 'Сложная структура', response: {
|
||
output: {
|
||
message: 'Основной ответ',
|
||
suggestions: ['Вариант 1', 'Вариант 2'],
|
||
metadata: { source: 'ai' }
|
||
}
|
||
}}
|
||
];
|
||
|
||
let simulation = '<h4>🎯 Симуляция обработки ответов:</h4>';
|
||
|
||
testCases.forEach(testCase => {
|
||
const processed = processN8NResponse(testCase.response);
|
||
simulation += `
|
||
<div class="response-box">
|
||
<strong>${testCase.name}:</strong><br>
|
||
<pre>${processed}</pre>
|
||
</div>
|
||
`;
|
||
});
|
||
|
||
resultDiv.innerHTML = simulation;
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>
|