221 lines
8.5 KiB
Markdown
221 lines
8.5 KiB
Markdown
|
|
# Исправление проблемы с вложениями в узле "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/
|
|||
|
|
|