Files
crm.clientright.ru/ticket_form/docs/N8N_EMAIL_ATTACHMENTS_FIX.md

221 lines
8.5 KiB
Markdown
Raw Normal View History

# Исправление проблемы с вложениями в узле "Send email" n8n
## Проблема
Узел "Send email" выдает ошибку:
```
The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received undefined
```
**Причина:** В поле `Attachments` передается строка с именами файлов (`file_0,file_1,file_2...`), но узел ожидает бинарные данные файлов.
---
## Решение
### Вариант 1: Использование Code Node для подготовки данных (Рекомендуется)
#### Шаг 1: Добавьте Code Node перед узлом "Send email"
**Код для Code Node:**
```javascript
// Создаем объект для бинарных данных и массив имен файлов
const binary = {};
const attachmentString = [];
const attachmentArray = []; // Массив объектов для поля Attachments
let i = 0;
// Преобразуем все бинарные данные в формат file_0, file_1, etc.
for (const key of Object.keys($binary)) {
const newKey = `file_${i}`;
binary[newKey] = $binary[key];
attachmentString.push(newKey);
// Создаем объект для поля Attachments узла "Send email"
attachmentArray.push({
name: $binary[key].fileName || $binary[key].name || `file_${i}.pdf`,
data: newKey // Ссылка на бинарные данные
});
i++;
}
// Возвращаем данные с бинарными файлами
return [{
json: {
...$json,
attachment_field: attachmentString.join(','),
attachments: attachmentArray
},
binary: binary
}];
```
#### Шаг 2: Настройте узел "Send email"
**Согласно официальной документации n8n:**
> "Enter the name of the binary properties that contain data to add as an attachment. Add multiple attachments by entering a comma-separated list of binary properties."
**В поле "Attachments" используйте:**
**✅ ПРАВИЛЬНО (РЕКОМЕНДУЕТСЯ):**
```
{{ $json.attachment_field }}
```
Это строка с именами бинарных свойств через запятую: `"file_0,file_1,file_2,file_3"`
**Важно понимать:**
- Это имена ключей из объекта `binary`, а не сами данные
- Формат: строка через запятую, НЕ массив
- Узел "Send email" найдет бинарные данные по этим именам в объекте `binary`
**❌ НЕПРАВИЛЬНО - НЕ ИСПОЛЬЗУЙТЕ:**
1. **Массив объектов:**
```javascript
{{ $json.attachments }} // ❌ Это массив объектов!
```
2. **Массив строк:**
```javascript
{{ $json.attachment_keys }} // ❌ Это массив строк!
{{ Object.keys($binary) }} // ❌ Это тоже массив!
```
**⚠️ КРИТИЧНО:**
- Используйте **СТРОКУ** `{{ $json.attachment_field }}`
- Убедитесь, что бинарные данные переданы в объекте `binary` выходного значения Code Node
- Ключи в объекте `binary` должны точно совпадать с именами в строке `attachment_field`!
- Например: если `attachment_field = "file_0,file_1"`, то в `binary` должны быть ключи `file_0` и `file_1`
---
### Вариант 2: Прямое использование бинарных данных (Проще)
Если бинарные данные уже есть в правильном формате, просто используйте их напрямую:
**В поле Attachments узла "Send email":**
```javascript
{{
Object.keys($binary).map(key => {
const file = $binary[key];
return {
name: file.fileName || file.name || key,
data: file.data || file
};
})
}}
```
---
### Вариант 3: Использование Function Node (Если Code Node не работает)
Если Code Node не передает бинарные данные правильно, используйте Function Node:
```javascript
const items = $input.all();
const result = items.map(item => {
const binary = {};
const attachmentArray = [];
let i = 0;
for (const key of Object.keys(item.binary || {})) {
const newKey = `file_${i}`;
binary[newKey] = item.binary[key];
attachmentArray.push({
name: item.binary[key].fileName || item.binary[key].name || `file_${i}.pdf`,
data: newKey
});
i++;
}
return {
json: {
...item.json,
attachments: attachmentArray,
attachment_field: Object.keys(binary).join(',')
},
binary: binary
};
});
return result;
```
---
## Проверка работы
1. **Убедитесь, что бинарные данные передаются:**
- В Code/Function Node должен быть объект `binary` в возвращаемом значении
- Проверьте в OUTPUT панели, что бинарные данные присутствуют
2. **Проверьте формат данных:**
- В поле Attachments должен быть массив объектов или правильная ссылка на бинарные данные
- Каждый объект должен содержать `name` и `data`
3. **Тестирование:**
- Запустите workflow в тестовом режиме
- Проверьте, что email отправляется с вложениями
---
## Частые ошибки
1. **Ошибка: "Received undefined"**
- **Причина:** Бинарные данные не переданы в выходном объекте
- **Решение:** Убедитесь, что объект `binary` включен в возвращаемое значение Code/Function Node
2. **Ошибка: "options.attachments.split is not a function" или "property.split is not a function"**
- **Причина:** В поле Attachments передан массив (объектов или строк) вместо строки. Согласно документации n8n, поле ожидает "comma-separated list of binary properties" (строку через запятую), а не массив.
- **Решение:**
- ✅ Используйте СТРОКУ с именами бинарных свойств: `{{ $json.attachment_field }}`
- Формат должен быть: `"file_0,file_1,file_2"` (строка), а не `["file_0","file_1","file_2"]` (массив)
-НЕ используйте `{{ $json.attachments }}` (это массив объектов)
-НЕ используйте `{{ $json.attachment_keys }}` (это массив строк)
-НЕ используйте `{{ Object.keys($binary) }}` (это тоже массив)
3. **Ошибка: "Invalid argument type"**
- **Причина:** Неправильный формат данных в поле Attachments
- **Решение:** Используйте строку с именами бинарных свойств через запятую: `"file_0,file_1,file_2"` (строка), а не массив
4. **Файлы не прикрепляются**
- **Причина:** Имена файлов не совпадают с ключами в объекте `binary`
- **Решение:** Убедитесь, что ключи в массиве Attachments точно соответствуют ключам в объекте `binary`
---
## Пример полного workflow
```
Webhook → Process Files → Code Node (подготовка) → Send Email
(binary данные)
(attachments массив)
```
**Code Node:**
- Вход: бинарные данные из предыдущего узла
- Выход: `{ json: {...}, binary: {...} }` с правильными ссылками
**Send Email:**
- Attachments: `{{ $json.attachments }}` или прямое обращение к `$binary`
---
## Дополнительные ресурсы
- Файл с кодом: `ticket_form/docs/N8N_CODE_PREPARE_EMAIL_ATTACHMENTS.js`
- Документация n8n: https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.email/