Files
agents/n8n-Bale-file-fetch/HOW_IT_WORKS.md
2026-08-29 18:37:48 +03:30

61 lines
4.0 KiB
Markdown

# Bale File Agent — How It Works
## The idea
The interviewer's brief was: type a natural-language request like *"grab the devops PDFs from this channel"* and have an agent go fetch them — the way a person would, but automated. This workflow implements that as a short pipeline in n8n, using an LLM only for the one step that actually needs language understanding (turning a sentence into a structured filter), and plain code/API calls for everything else.
## The pipeline, step by step
```
Chat message
↓
LLM parses intent → {file_type, keyword}
↓
Fetch messages the Bale bot has seen
↓
Filter messages against the parsed intent
↓
Download each match from Bale
↓
Save to disk
```
### 1. Chat Trigger
A live chat box inside the n8n editor. Whatever you type becomes the field `chatInput` on the item that flows to the next node. This stands in for "a person typing a request" — in a real deployment this could be a Slack bot, a web form, or Bale itself.
### 2. Parse command (LLM)
A single HTTP call to BazaarLink's OpenAI-compatible endpoint. The system prompt forces the model into a narrow, mechanical job: read the sentence, output nothing but `{"file_type": "...", "keyword": "..."}`. This is intentionally the *only* place an LLM is used — everything else is deterministic, which keeps the workflow fast, cheap, and easy to debug.
### 3. Extract filters
A small Code node that takes the LLM's raw text response, strips any accidental markdown fences, and parses it into real JSON so the rest of the workflow can use `.file_type` and `.keyword` as normal fields.
### 4. Fetch Bale updates
Calls Bale's Bot API (`getUpdates`) — a long-polling endpoint that returns every message the bot has seen since it was last called. Bale's bot API is essentially a clone of Telegram's, so this behaves the same way: it returns *new* activity, not full channel history.
### 5. Filter matches
Another Code node. Loops through the fetched messages, and for each one:
- Checks whether it's a PDF document or a photo (matching `file_type`)
- Checks whether the caption or filename contains the requested `keyword`
- If both match, records the file's `file_id` and real `file_name` for the next steps
This is where "understanding the request" turns into "acting on the request" — the filtering logic itself needs no AI, just the structured output the LLM already produced.
### 6. Get file path → Download file
Two calls to Bale's API mirroring Telegram's own two-step file download: `getFile` resolves a `file_id` into a temporary `file_path`, then a second request downloads the actual bytes from that path.
### 7. Save to disk
Writes the downloaded binary to a folder on the n8n host, using the real original filename (not Bale's internal file token) so the output is something a human would recognize.
## Why it's built this way
- **LLM only where it's needed.** Intent parsing is genuinely a language task; filtering, fetching, and downloading are not. Using an LLM for the whole thing would be slower, more expensive, and harder to debug than necessary.
- **Deterministic filtering.** The match logic is plain code, so it's predictable and cheap to test — you can reason about exactly why a file did or didn't match.
- **Small, inspectable steps.** Each node does one clear thing, so a failure (like a bad file path, or an expired long-poll) is easy to isolate — you can see exactly which stage produced bad data by clicking through node outputs in n8n's UI.
## What a production version would add
- A **persistent index** of channel content (log every incoming file to a small database or sheet as it arrives via webhook), so requests aren't limited to whatever `getUpdates` happens to still be holding.
- **Retry logic** on the LLM call for transient network blips.
- A proper **credential store** in n8n instead of hardcoded tokens/keys.
- Possibly a **semantic match** (embeddings or a second LLM pass) instead of plain substring matching on captions, so "grab the devops stuff" also catches a file captioned "infrastructure automation" even without the literal word "devops."