{ "name": "Bale File Agent (demo)", "nodes": [ { "parameters": { "options": {} }, "id": "90a5fd0c-27ab-49be-ad12-87e53165df6a", "name": "When chat message received", "type": "@n8n/n8n-nodes-langchain.chatTrigger", "typeVersion": 1.1, "position": [ -80, 96 ], "webhookId": "fdae82fa-cb2d-4d9a-83ba-4ae9bddd0a6e" }, { "parameters": { "method": "POST", "url": "https://api.bazaarlink.ai/v1/chat/completions", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "Authorization", "value": "Bearer change-me-please" }, { "name": "Content-Type", "value": "application/json" } ] }, "sendBody": true, "specifyBody": "json", "jsonBody": "={{ JSON.stringify({ model: \"auto:free\", messages: [ { role: \"system\", content: \"You extract a file_type (pdf or image) and a keyword from a user's request. Reply with ONLY compact JSON like {\\\"file_type\\\":\\\"pdf\\\",\\\"keyword\\\":\\\"devops\\\"}. No prose, no markdown fences.\" }, { role: \"user\", content: $json.chatInput } ] }) }}", "options": {} }, "id": "64211cf6-e042-4e8b-a5ac-62d4e172c588", "name": "Parse command (LLM)", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ 368, 96 ] }, { "parameters": { "jsCode": "let raw = $input.first().json.choices[0].message.content.trim();\n// strip markdown fences if the model adds them anyway\nraw = raw.replace(/^```json\\s*/i, '').replace(/^```\\s*/i, '').replace(/```\\s*$/i, '');\nconst filters = JSON.parse(raw);\nreturn [{ json: filters }];" }, "id": "3aef64ed-d97c-4d23-b1d1-a06790ecf9f6", "name": "Extract filters", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 592, 96 ] }, { "parameters": { "url": "https://tapi.bale.ai/YOUR_BOT_ID:your-Bale-token/getUpdates", "options": {} }, "id": "639ac81a-f436-403c-8c4e-51ebb72b8547", "name": "Fetch Bale updates", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ 592, 336 ], "notes": "getUpdates clears its queue on each call - if you run this twice in a row with no new channel activity, the second run comes back empty." }, { "parameters": { "jsCode": "const filters = $('Extract filters').first().json;\nconst updates = $input.first().json.result || [];\n\nconst matches = [];\nfor (const u of updates) {\n const msg = u.message || u.channel_post;\n if (!msg) continue;\n\n const isPdf = msg.document && (msg.document.mime_type || '').includes('pdf');\n const isImage = !!msg.photo;\n const caption = (msg.caption || msg.document?.file_name || '').toLowerCase();\n\n const typeMatches =\n (filters.file_type === 'pdf' && isPdf) ||\n (filters.file_type === 'image' && isImage);\n const keywordMatches = !filters.keyword || caption.includes(filters.keyword.toLowerCase());\n\n if (typeMatches && keywordMatches) {\n const fileId = isPdf ? msg.document.file_id : msg.photo[msg.photo.length - 1].file_id;\n matches.push({ file_id: fileId, file_name: msg.document?.file_name || `${fileId}.bin`, caption, is_pdf: isPdf });\n }\n}\nreturn matches.map(m => ({ json: m }));" }, "id": "30f1df87-dce6-47c4-8110-51cfb5439feb", "name": "Filter matches", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 800, 208 ] }, { "parameters": { "url": "=https://tapi.bale.ai/YOUR_BOT_ID:chnage-me-please/getFile?file_id={{ $json.file_id }}", "options": {} }, "id": "3466c103-2079-4de3-b9a4-5fb1d034fa3a", "name": "Get file path", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ 1024, 208 ] }, { "parameters": { "url": "=https://tapi.bale.ai/file/YOUR_BOT_ID:chnage-me-please/{{ $json.result.file_path }}", "options": { "response": { "response": { "responseFormat": "file" } } } }, "id": "19a4caeb-3ea7-4386-8c26-caab0061c2e2", "name": "Download file", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ 1248, 208 ] }, { "parameters": { "operation": "write", "fileName": "=/mnt/storage/bale-downloads/{{ $('Filter matches').item.json.file_name }}", "options": {} }, "id": "eab3cb34-f7ae-48c3-8b87-842a1e5fb176", "name": "Save to disk", "type": "n8n-nodes-base.readWriteFile", "typeVersion": 1, "position": [ 1472, 208 ], "notes": "Change the folder path to wherever your n8n instance can write. Swap for a Google Drive node if you'd rather store there." } ], "pinData": {}, "connections": { "When chat message received": { "main": [ [ { "node": "Parse command (LLM)", "type": "main", "index": 0 } ] ] }, "Parse command (LLM)": { "main": [ [ { "node": "Extract filters", "type": "main", "index": 0 } ] ] }, "Extract filters": { "main": [ [ { "node": "Fetch Bale updates", "type": "main", "index": 0 } ] ] }, "Fetch Bale updates": { "main": [ [ { "node": "Filter matches", "type": "main", "index": 0 } ] ] }, "Filter matches": { "main": [ [ { "node": "Get file path", "type": "main", "index": 0 } ] ] }, "Get file path": { "main": [ [ { "node": "Download file", "type": "main", "index": 0 } ] ] }, "Download file": { "main": [ [ { "node": "Save to disk", "type": "main", "index": 0 } ] ] } }, "active": false, "settings": { "executionOrder": "v1", "binaryMode": "separate", "availableInMCP": false }, "versionId": "7098b660-f579-414b-bf83-6002d32cbff6", "meta": { "instanceId": "a8618b8efe9a0b8c68300d12dc12f140ace3ebe855b80198b7819ca3e0922fe9" }, "nodeGroups": [], "id": "tG4eEba8ODCbAcfX", "tags": [] }