- Добавлен 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 минут)
186 lines
6.4 KiB
Markdown
186 lines
6.4 KiB
Markdown
# Настройка n8n для прямой публикации в Redis
|
||
|
||
## 🎯 Цель
|
||
Настроить n8n workflow так, чтобы после обработки AI ответа он публиковал результат **напрямую в Redis**, без промежуточного callback.
|
||
|
||
## 📋 Архитектура
|
||
|
||
```
|
||
AI Drawer → n8n_proxy.php → n8n webhook
|
||
↓
|
||
[Обработка AI]
|
||
↓
|
||
Redis PUBLISH → ai:response:{taskId}
|
||
↓
|
||
SSE → браузер получает мгновенно! ⚡
|
||
```
|
||
|
||
## 🔧 Настройка n8n Workflow
|
||
|
||
### Шаг 1: Добавить Redis ноду после обработки AI
|
||
|
||
В вашем n8n workflow после ноды обработки AI добавьте **Redis ноду**:
|
||
|
||
1. **Тип ноды**: `Redis`
|
||
2. **Operation**: `Publish`
|
||
|
||
### Шаг 2: Настройки Redis ноды
|
||
|
||
**Connection:**
|
||
```
|
||
Host: crm.clientright.ru
|
||
Port: 6379
|
||
Password: CRM_Redis_Pass_2025_Secure!
|
||
Database: 0
|
||
```
|
||
|
||
**Operation Settings:**
|
||
```
|
||
Operation: Publish
|
||
Channel: {{ $json.redisChannel }}
|
||
```
|
||
|
||
**Message (вариант 1 - JSON объект, рекомендуется):**
|
||
```json
|
||
{
|
||
"task_id": "{{ $json.taskId }}",
|
||
"status": "completed",
|
||
"response": "{{ $json.aiResponse }}",
|
||
"timestamp": "{{ $now.toISO() }}"
|
||
}
|
||
```
|
||
|
||
**Message (вариант 2 - просто текст, тоже работает):**
|
||
```
|
||
{{ $json.aiResponse }}
|
||
```
|
||
|
||
⚠️ **Важно:** SSE endpoint поддерживает оба формата:
|
||
- JSON объект с полем `response` - предпочтительно
|
||
- Просто текст ответа - тоже работает (автоматически обрабатывается)
|
||
|
||
### Шаг 2.5: Сохранение в Redis ключ (ВАЖНО для fallback)
|
||
|
||
⚠️ **КРИТИЧНО:** Сохраняйте ответ в Redis ключ **ПЕРЕД** публикацией в канал!
|
||
|
||
**Порядок действий в n8n:**
|
||
1. Обработка AI → получен ответ
|
||
2. **Сначала:** Redis SET → сохранить в ключ `ai:response:cache:{taskId}` (TTL 300 сек)
|
||
3. **Потом:** Redis PUBLISH → опубликовать в канал `ai:response:{taskId}`
|
||
|
||
**Добавьте Redis ноду для SET (перед PUBLISH):**
|
||
|
||
**Operation:** `Set`
|
||
**Key:** `ai:response:cache:{{ $json.taskId }}`
|
||
**Value:**
|
||
```json
|
||
{
|
||
"task_id": "{{ $json.taskId }}",
|
||
"response": "{{ $json.aiResponse }}",
|
||
"status": "completed",
|
||
"timestamp": "{{ $now.toISO() }}"
|
||
}
|
||
```
|
||
**TTL:** `300` секунд (5 минут)
|
||
|
||
**Зачем это нужно:**
|
||
- Если SSE не подписался вовремя → fallback найдет ответ в ключе
|
||
- Если браузер перезагрузился → ответ все еще доступен
|
||
- Надежность: двойное сохранение (канал + ключ)
|
||
|
||
### Шаг 3: Канал Redis
|
||
|
||
Канал формируется автоматически из `taskId`:
|
||
```
|
||
ai:response:{{ $json.taskId }}
|
||
```
|
||
|
||
Или используйте значение из входящего запроса:
|
||
```
|
||
{{ $json.redisChannel }}
|
||
```
|
||
|
||
## 📝 Пример workflow
|
||
|
||
```
|
||
[Webhook] → [AI обработка] → [Redis SET] → [Redis PUBLISH] → [End]
|
||
↓ ↓
|
||
[Сохранить историю в n8n] [Ответ в ключе + канале]
|
||
```
|
||
|
||
**Порядок:**
|
||
1. SET в ключ `ai:response:cache:{taskId}` (для fallback)
|
||
2. PUBLISH в канал `ai:response:{taskId}` (для SSE)
|
||
3. Сохранение истории в n8n
|
||
|
||
### Детали Redis ноды:
|
||
|
||
**Input:**
|
||
- `taskId` - из входящего webhook запроса
|
||
- `aiResponse` - результат обработки AI
|
||
- `redisChannel` - канал из входящего запроса (`ai:response:{taskId}`)
|
||
|
||
**Output:**
|
||
- Публикация в Redis канал
|
||
- Браузер получает через SSE мгновенно
|
||
|
||
## ✅ Проверка
|
||
|
||
### Тест публикации из командной строки:
|
||
```bash
|
||
redis-cli -h crm.clientright.ru -p 6379 -a 'CRM_Redis_Pass_2025_Secure!' \
|
||
PUBLISH "ai:response:test-task" '{"task_id":"test-task","response":"Тест","status":"completed"}'
|
||
```
|
||
|
||
### Проверка в n8n:
|
||
1. Запустите workflow с тестовым запросом
|
||
2. Проверьте логи Redis ноды - должна быть успешная публикация
|
||
3. В браузере откройте AI Drawer и отправьте сообщение
|
||
4. Ответ должен прийти мгновенно через SSE
|
||
|
||
## 🔍 Отладка
|
||
|
||
### Если ответ не приходит:
|
||
|
||
1. **Проверьте канал Redis:**
|
||
```bash
|
||
redis-cli -h crm.clientright.ru -p 6379 -a 'CRM_Redis_Pass_2025_Secure!' \
|
||
MONITOR
|
||
```
|
||
Должны видеть PUBLISH команды
|
||
|
||
2. **Проверьте формат сообщения:**
|
||
Сообщение должно быть валидным JSON:
|
||
```json
|
||
{
|
||
"task_id": "task-123",
|
||
"response": "Ответ от AI",
|
||
"status": "completed"
|
||
}
|
||
```
|
||
|
||
3. **Проверьте SSE endpoint:**
|
||
```bash
|
||
curl -N "https://crm.clientright.ru/aiassist/ai_sse.php?task_id=test-task"
|
||
```
|
||
|
||
## 📊 Преимущества новой архитектуры
|
||
|
||
✅ **Проще** - нет промежуточного callback
|
||
✅ **Быстрее** - прямая публикация в Redis
|
||
✅ **Надежнее** - меньше точек отказа
|
||
✅ **Меньше кода** - убрали БД и callback
|
||
|
||
## 🚨 Важно
|
||
|
||
- История диалога сохраняется в n8n автоматически (не нужно дублировать в БД)
|
||
- Если Redis недоступен, браузер автоматически переключится на fallback (polling)
|
||
- Канал Redis уникален для каждого запроса: `ai:response:{taskId}`
|
||
|
||
## 📁 Связанные файлы
|
||
|
||
- `/aiassist/n8n_proxy.php` - отправляет запрос в n8n с параметрами Redis
|
||
- `/aiassist/ai_sse.php` - SSE endpoint для получения ответов из Redis
|
||
- `/layouts/v7/resources/js/ai-drawer-simple.js` - JavaScript клиент с SSE
|
||
|