n8n-binary-and-data – skill Dữ liệu & Khoa học cho agent AI
Xử lý file và dữ liệu nhị phân trong n8n: upload, download, transform, input đa phương thức, công cụ agent và giao diện chat.
Cài skill n8n-binary-and-data bằng một lệnh
Chọn công cụ bạn đang dùng, copy lệnh và dán vào terminal. Skill sẽ nằm trong thư mục skills của công cụ đó và sẵn sàng dùng ở phiên làm việc tiếp theo.
Claude Code
mkdir -p ~/.claude/skills && curl -fsSL https://skill.dn1nguoi.com/z/n8n-binary-and-data-ac2e0.tgz | tar xz -C ~/.claude/skills
Gọi trong Claude Code: /n8n-binary-and-data – rồi mô tả công việc bạn muốn làm.
Codex
mkdir -p ~/.codex/skills && curl -fsSL https://skill.dn1nguoi.com/z/n8n-binary-and-data-ac2e0.tgz | tar xz -C ~/.codex/skills
Gọi trong Codex: $n8n-binary-and-data – rồi mô tả công việc bạn muốn làm.
Hermes Agent
mkdir -p ~/.hermes/skills && curl -fsSL https://skill.dn1nguoi.com/z/n8n-binary-and-data-ac2e0.tgz | tar xz -C ~/.hermes/skills
Gọi trong Hermes Agent: /n8n-binary-and-data – rồi mô tả công việc bạn muốn làm.
DeepSeek
mkdir -p ~/.deepcode/skills && curl -fsSL https://skill.dn1nguoi.com/z/n8n-binary-and-data-ac2e0.tgz | tar xz -C ~/.deepcode/skills
Gọi trong DeepSeek: /n8n-binary-and-data – rồi mô tả công việc bạn muốn làm.
Nội dung SKILL.md
Nội dung SKILL.md gốc bằng tiếng Anh.
n8n Binary and Data
When to Use
Use this skill when an n8n workflow reads, transforms, stores, uploads, downloads, or transmits files and binary fields, including multimodal agent inputs and chat attachments.
Treat uploaded files and generated URLs as potentially sensitive. Obtain approval before sending data to a new external host, use the narrowest retention and access scope available, avoid logging bytes or base64 payloads, and do not embed credentials in URLs or workflow fields.
Every n8n item carries two independent slots: $json for structured data and $binary for file bytes. They travel side by side through the workflow. File contents — the actual PDF, image, or zip — live in $binary, never in $json. Get that split wrong and you read an empty field, lose a file mid-flow, or hand an AI agent a tool input it can't use.
This skill covers where binary lives, how to read and write it, how to keep it from being silently stripped, the hard wall between binary and the AI-agent tool boundary, and why chat surfaces need a URL instead of raw bytes.
---
Three common binary-data rules
1. File contents are in $binary, not $json. After an HTTP download, a "Read Files", or an email-attachment trigger, the bytes sit in $binary.<key>. $json holds metadata at most. Reading $json.data for file contents gives you nothing.
2. Binary cannot cross the AI-agent tool boundary — in either direction. Tool arguments and tool return values are JSON only. An uploaded image can't be passed into a tool as a file, and a tool can't return raw bytes. Pre-stage to storage and pass a key or URL through JSON instead. See references/AGENT_TOOL_BINARY.md.
3. Chat surfaces render images by URL, not by $binary. Slack, Discord, Teams, Telegram, embedded webhook chat — none of them read the binary slot. The image has to live somewhere a URL can fetch it. See references/CDN_REQUIREMENT.md.
---
The two slots
Each item is shaped like this:
{
"json": { "customerId": 42, "status": "sent" },
"binary": {
"invoice": {
"data": "<base64-encoded bytes>",
"mimeType": "application/pdf",
"fileName": "invoice-42.pdf",
"fileExtension": "pdf"
}
}
}The key inside binary (invoice here) is the binary property name. Most file-handling nodes have a binaryPropertyName parameter that points at it — the producer names the slot, the consumer references it by that name. The default key across most nodes is data, so when nothing tells you otherwise, assume $binary.data.
$json and $binary are separate namespaces. An expression like {{ $binary.invoice.fileName }} reads file metadata; {{ $json.customerId }} reads data. They never mix.
This split also explains a webhook gotcha: a Webhook trigger receiving multipart/form-data puts the uploaded file in $binary and the accompanying form fields in $json.body — so an uploaded file is not somewhere under $json at all. (The $json.body nesting for webhooks is n8n-expression-syntax territory.)
See references/BINARY_BASICS.md for the full slot anatomy, mime types, and size limits.
---
Producing binary
You rarely build a $binary slot by hand — nodes populate it for you:
| Source | How binary appears |
|---|---|
| HTTP Request with responseFormat: "file" | Response body lands in $binary.data (or the name you set) |
| Read/Write Files from Disk | File contents read into $binary |
| Storage downloads (S3, Google Drive, Dropbox, etc.) | Downloaded file in $binary.<key> |
| Email triggers with attachments | Each attachment arrives in $binary |
| Provider AI media nodes (image/audio gen) | Set options.binaryPropertyOutput so the bytes land where the next node looks |
For an HTTP download, the one field that matters is responseFormat. Confirm it with get_node on nodes-base.httpRequest — leaving it as the default JSON/string format is the classic reason a downloaded file ends up as garbled text in $json instead of clean bytes in $binary.
---
Reading and writing binary in a Code node
Most workflows never need to crack open the bytes — they just pass binary through to a consumer (email attachment, file upload, Slack file). When you do need the raw bytes, do it in a Code node.
Read with getBinaryDataBuffer — do not try to base64-decode $binary.<key>.data by hand:
// Code node, "Run Once for All Items"; single-item example only
const buffer = await this.helpers.getBinaryDataBuffer(0, 'data'); // (itemIndex, propertyName)
const text = buffer.toString('utf-8');
const length = buffer.length;
return [{
json: { ...$json, length },
binary: $input.item.binary, // pass the binary through, or it's gone
}];Write by building the slot yourself — base64 the bytes plus a mime type and file name:
const text = 'Hello, world!';
return [{
json: { ok: true },
binary: {
report: {
data: Buffer.from(text).toString('base64'),
mimeType: 'text/plain',
fileName: 'report.txt',
fileExtension: 'txt',
},
},
}];The Code-node sandbox, helpers, and execution modes are the domain of n8n-code-javascript (and n8n-code-python) — use those for the language-level detail. The one binary-specific thing to remember here: a Code node that returns [{ json: {...} }] without re-attaching binary silently drops the file. See references/BINARY_BASICS.md.
---
Keeping binary alive across transforms
JSON-only nodes — Edit Fields (Set), Code, IF, and others — can drop the $binary slot from their output. The workflow validates clean and runs without error; the file just isn't there downstream when the email node goes to attach it.
Two ways to keep it:
- Pass-through option on the transforming node. Edit Fields has
includeOtherFields; a Code node can returnbinary: $input.item.binaryexplicitly. Cheapest fix when it's available. - Fan out and Merge by position. Route the source into both the transform and a bypass branch, then recombine with a Merge in
combineByPositionmode. The JSON comes from the transform side, the binary survives on the bypass side.
[Source with binary] ─┬─→ [Edit Fields: change JSON] ─┐
│ (binary stripped here) ├─→ [Merge: combineByPosition] ─→ [Email: attach]
└──────────────────────────────────┘
(bypass — binary passes through untouched)combineByPosition pairs item N from each input, so the field counts must line up. The connection wiring and the alternatives for many-strip-point chains (upload-early, sub-workflow) are in references/MERGE_FOR_CONTEXT.md.
---
The agent-tool binary boundary
This is the sharpest edge. An AI Agent talks to its tools (Custom Code Tool, Call n8n Workflow Tool, HTTP Request Tool, MCP tools) over JSON. Binary does not fit through that pipe in either direction. The fix is the same shape both ways: stage the bytes in storage, pass a key/URL through JSON, fetch on the other side.
Inbound — a user uploads a file the agent's tool must operate on:
1. The chat trigger gives you a files[] array. Split it out and upload each file to private storage under a hashed key.
2. Re-merge that branch before the agent runs (it's a synchronization barrier, not decoration), and set executeOnce: true on the agent so N files don't trigger N agent runs.
3. Inject the keys into the agent's system prompt, listing both the original name (human context) and the storage key (what the tool needs), with an explicit "use EXACTLY this key".
4. The tool receives the key as a string argument and downloads the file from storage itself.
Outbound — a tool generates a file the agent must return:
1. The tool sub-workflow generates the binary, uploads it to storage, and returns JSON like { "ok": true, "key": "...", "url": "https://...", "mimeType": "image/png" }.
2. The agent embeds the URL in its reply (or passes the key to another tool).
passthroughBinaryImages: true on the agent only changes what the LLM sees for vision — it does not let tools receive the file, and it's image-only (no PDFs, audio, or video). You still need the upload-and-pass-key pattern for any tool. Full patterns, hash strategy, storage choices, and the long-running-tool variant are in references/AGENT_TOOL_BINARY.md.
> Building the tool itself? See n8n-code-tool for the Custom Code Tool contract and n8n-workflow-patterns for the AI-Agent-with-tools shape.
---
The CDN requirement for chat surfaces
When a workflow generates an image and the user wants it shown inside a chat message:
- Binary on the item isn't enough. The chat client renders messages that reference images by URL (or pushes bytes through the platform's own file-upload API). It never reads
$binary. - The bytes have to live somewhere a URL can fetch over HTTPS. Upload to an object store or drive f
… (nội dung đầy đủ có trong gói tải về)
Skill liên quan
- native-data-fetching – Dùng khi triển khai hoặc gỡ lỗi BẤT KỲ yêu cầu mạng, lệnh gọi API hoặc việc lấy dữ liệu…
- neon-object-storage – Lưu trữ đối tượng tương thích S3, phân nhánh cùng dự án Neon của bạn, giúp tệp và cơ sở…
- news-sentiment-engine – Tổng hợp tin tức RSS từ nhiều nguồn, phân tích cảm xúc bằng Claude và xuất bản tin tóm…
- nexrad-product-access – Tìm và truy cập dữ liệu NEXRAD cho trạm radar, thời điểm, sản phẩm hoặc moment Level II…
- nextjs-best-practices – Nguyên tắc App Router của Next.js. Server Components, lấy dữ liệu, các mẫu định tuyến.
- ontoly-software-graph – Dùng Software Graph xác định, máy chủ MCP và các skill của agent từ Ontoly để review…
- pangolinfo-amazon-data-research – Lập kế hoạch và thực hiện nghiên cứu chỉ đọc về sản phẩm, đánh giá, danh mục, người bán…
- pci-compliance – Rà soát luồng dữ liệu thanh toán và bằng chứng kiểm soát kỹ thuật cho đánh giá PCI trong…