# Bale File Agent — Setup Guide A demo n8n workflow that lets you type a natural-language request (e.g. "grab the devops pdfs") and have an agent fetch matching files from a Bale channel and save them to disk. ## 1. Create the Bale bot and channel 1. Open Bale and message **@Bot_Father** (same flow as Telegram's BotFather). 2. Create a new bot, name it, and save the bot token it gives you — looks like `1234567:AAbbCCddEE...`. 3. Create a private channel (this demo uses one called `lesson-source`). 4. Add your new bot to the channel and **promote it to admin**. This step is mandatory — a bot that's only a regular member will never receive `channel_post` updates. 5. Post a handful of test files into the channel with hashtag captions, e.g.: - `#ansible` on one PDF - `#linux` on another - `#devops` on another Mixed captions let you prove the filtering actually filters, rather than matching everything by accident. ## 2. Get a BazaarLink API key This workflow uses [BazaarLink](https://bazaarlink.ai) as an OpenAI-compatible LLM gateway, using the `auto:free` model (free, rate-limited — plenty for a demo where you're parsing short one-line commands). Grab an API key from your BazaarLink account and keep it handy for step 4. ## 3. Import the workflow into n8n 1. In n8n, go to **Workflows → Import from File**. 2. Import `bale-file-agent-chat.json`. 3. You'll see 7 nodes: a Chat Trigger, an LLM parser, a code node, three Bale API calls, and a disk-write node. ## 4. Fill in your credentials Open these two nodes and edit them directly (no n8n credential objects needed for this demo): - **Parse command (LLM)** — replace the placeholder in the `Authorization` header with `Bearer `. - **Fetch Bale updates**, **Get file path**, **Download file** — replace the bot token in each URL with your own (`bot` in the path). ## 5. Fix n8n's file-write allowlist n8n's Read/Write File node only allows writing to `/home/node/.n8n-files` by default — anywhere else gets rejected with "Access to the file is not allowed." To write to your own storage path, add this to your n8n service's environment in `docker-compose.yaml`: ```yaml environment: N8N_RESTRICT_FILE_ACCESS_TO: /mnt/storage ``` Then create the target folder and restart the container: ```bash mkdir -p /mnt/storage/bale-downloads docker compose up -d --force-recreate n8n ``` ## 6. Run it 1. Open the workflow, click the chat icon on the Chat Trigger node (or the **"Open Chat"** button) to bring up an inline chat panel. 2. Type something like `grab the devops pdfs`. 3. Watch it run through: parse → fetch → filter → download → save. 4. Confirm the file landed correctly: ```bash ls -la /mnt/storage/bale-downloads/ ``` ## Known limitations (worth knowing going in) - **`getUpdates` clears its queue on every call.** Once the workflow reads Bale's pending messages, they're gone from that endpoint until new ones arrive. If you run the workflow twice with no new channel activity in between, the second run will find zero files — not a bug, just how long-polling works. - **No historical scraping.** The bot only sees messages posted after it joined the channel. For files posted before the bot existed, you'd need a persistent index (log files into a database/sheet as they arrive) or a full client-level API integration — out of scope for this demo. - **Expression fields in n8n store a leading `=`.** If you ever copy/paste an expression into a field that's already in "expression mode," don't include your own leading `=` — n8n adds that internally, and a doubled-up `=` silently breaks the path.