Реализован SSE + Redis Pub/Sub для AI Drawer

- Добавлен SSE endpoint (aiassist/ai_sse.php) для real-time получения ответов от n8n
- Обновлен n8n_proxy.php: убран callback, добавлена передача Redis параметров в n8n
- Обновлен ai-drawer-simple.js: переход с polling на SSE с fallback через Redis
- Добавлен check_redis_response.php для прямого чтения из Redis кэша
- Добавлена документация: N8N_REDIS_SETUP.md, N8N_REDIS_FIX.md, AI_DRAWER_REDIS_SSE.md
- Поддержка plain text ответов от n8n (автоматическое определение формата)
- Кэширование ответов в Redis для надежности (TTL 5 минут)
This commit is contained in:
Fedor
2025-11-11 15:16:27 +03:00
parent f770bd0e43
commit 1a4653298d
6 changed files with 768 additions and 70 deletions

155
N8N_REDIS_FIX.md Normal file
View File

@@ -0,0 +1,155 @@
# 🔧 Исправление конфигурации n8n для Redis публикации
## ❌ Проблема в текущей конфигурации
```json
{
"channel": "=ai:response:{{ $('Edit Fields').item.json.taskId }}",
"messageData": "={{ JSON.stringify($json.output) }}"
}
```
**Проблемы:**
1. ❌ Канал использует `$('Edit Fields').item.json.taskId` - неправильный путь
2.`messageData` содержит `$json.output` - неправильный формат
3. ❌ Нет сохранения в Redis ключ для fallback
## ✅ Правильная конфигурация
### Вариант 1: Если taskId в корне webhook body
**Channel:**
```
ai:response:{{ $json.taskId }}
```
**Message (JSON объект):**
```json
{
"task_id": "{{ $json.taskId }}",
"response": "{{ $json.output }}",
"status": "completed"
}
```
### Вариант 2: Если taskId в webhook.body
**Channel:**
```
ai:response:{{ $json.webhook.body.taskId }}
```
**Message (JSON объект):**
```json
{
"task_id": "{{ $json.webhook.body.taskId }}",
"response": "{{ $json.output }}",
"status": "completed"
}
```
### Вариант 3: Если ответ в другой ноде (например, AI Chat)
**Channel:**
```
{{ $json.webhook.body.redisChannel }}
```
**Message (JSON объект):**
```json
{
"task_id": "{{ $json.webhook.body.taskId }}",
"response": "{{ $json['AI Chat'].json.response }}",
"status": "completed"
}
```
## 📋 Полная настройка n8n workflow
### Шаг 1: Redis SET (сохранить в ключ для fallback)
**Operation:** `Set`
**Key:** `ai:response:cache:{{ $json.webhook.body.taskId }}`
**Value:**
```json
{
"task_id": "{{ $json.webhook.body.taskId }}",
"response": "{{ $json['AI Chat'].json.response }}",
"status": "completed",
"timestamp": "{{ $now.toISO() }}"
}
```
**TTL:** `300` секунд
### Шаг 2: Redis PUBLISH (опубликовать в канал для SSE)
**Operation:** `Publish`
**Channel:** `{{ $json.webhook.body.redisChannel }}`
**Message:**
```json
{
"task_id": "{{ $json.webhook.body.taskId }}",
"response": "{{ $json['AI Chat'].json.response }}",
"status": "completed"
}
```
## 🔍 Как найти правильный путь к данным
1. **Добавьте ноду "Set" перед Redis:**
- Сохраните все данные из предыдущих нод
- Посмотрите структуру данных в n8n
2. **Используйте Expression Editor в n8n:**
- Нажмите на поле "Channel" или "Message"
- Выберите "Expression"
- Начните вводить `$json.` - увидите доступные поля
3. **Проверьте webhook body:**
- В ноде Webhook посмотрите что приходит
- `taskId` и `redisChannel` должны быть в `$json.webhook.body`
## ✅ Проверка
После настройки проверьте:
1. **В n8n:**
- Запустите workflow
- Проверьте что Redis ноды выполнились успешно
- Посмотрите что именно публикуется в канал
2. **В Redis:**
```bash
redis-cli -h crm.clientright.ru -p 6379 -a 'CRM_Redis_Pass_2025_Secure!' \
MONITOR
```
Должны видеть:
- `SET ai:response:cache:task-xxx ...`
- `PUBLISH ai:response:task-xxx ...`
3. **В браузере:**
- Откройте консоль (F12)
- Должны видеть: `AI Drawer: SSE connection opened`
- Должны видеть: `AI Drawer: Received response via SSE`
## 🐛 Отладка
Если не работает:
1. **Проверьте формат сообщения:**
- Должен быть валидный JSON
- Должно быть поле `response` или `task_id`
2. **Проверьте канал:**
- Должен совпадать с `redisChannel` из `n8n_proxy.php`
- Формат: `ai:response:task-xxx`
3. **Проверьте логи PHP:**
```bash
tail -f /var/log/apache2/error.log | grep "AI SSE"
```
4. **Проверьте что SSE endpoint доступен:**
- Откройте в браузере: `/aiassist/ai_sse.php?task_id=test-123`
- Должен открыться поток SSE (не ошибка)