Files
n8n/backups/2025-12-27/MikroTik ↔ Telegram (Fixed Connections).json

1 line
13 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"updatedAt":"2025-12-08T20:59:27.678Z","createdAt":"2025-12-08T11:04:55.349Z","id":"WH2YAlOoEGwYhFVG","name":"MikroTik ↔ Telegram (Fixed Connections)","active":false,"isArchived":false,"nodes":[{"parameters":{"updates":["message","callback_query"],"additionalFields":{}},"name":"Telegram Trigger","type":"n8n-nodes-base.telegramTrigger","typeVersion":1,"position":[-1840,32],"id":"0dcb4cd8-48b0-475a-a1e8-2c21f3276d28","webhookId":"10e7c043-bcbd-4b2c-9994-41b32ed03127","credentials":{"telegramApi":{"id":"L9KHcMiteyKROF5r","name":"Telegram main n8n"}}},{"parameters":{"functionCode":"// === Получаем данные ===\nconst input = $input.all()[0].json;\nlet chatId, text = '', callbackData = '';\n\nif (input.callback_query) {\n callbackData = input.callback_query.data || '';\n chatId = input.callback_query.message.chat.id;\n} else if (input.message) {\n text = (input.message.text || '').trim();\n chatId = input.message.chat.id;\n}\n\n// === Меню ===\nif (text === '/menu' || text === '/start' || callbackData === 'menu') {\n return [{ json: { chatId, action: 'menu' } }];\n}\n\n// === Кнопки ===\nif (callbackData === 'add_ip') {\n return [{ json: { chatId, action: 'add_ip' } }];\n}\nif (callbackData === 'find_mode') {\n return [{ json: { chatId, action: 'find_mode' } }];\n}\n\n// === Перемещение и удаление ===\nif (callbackData.startsWith('to|') || callbackData.startsWith('del|')) {\n const parts = callbackData.split('|');\n const action = parts[0] === 'del' ? 'delete' : 'move';\n return [{ json: { chatId, entryId: parts[1], newList: parts[2], action } }];\n}\n\n// === КОМАНДА /addip (РАБОТАЕТ В ЛЮБОМ СЛУЧАЕ) ===\nif (text && text.toLowerCase().startsWith('/addip')) {\n const match = text.match(/\\/addip\\s+([\\d.]+)(?:\\s+([\\w-]+))?(?:\\s+([\\w\\d]+))?(?:\\s+\"?([^\"]+)\"?)?/i);\n if (match) {\n const [, ip, list = 'trusted', timeout = '30d', comment = 'Добавлено через Telegram'] = match;\n return [{\n json: {\n chatId,\n ip: ip.trim(),\n list: list.trim(),\n timeout: timeout.trim(),\n comment: (comment || 'Добавлено через Telegram').trim(),\n action: 'add_or_update'\n }\n }];\n } else {\n return [{ json: { chatId, action: 'add_ip' } }]; // если формат кривой — просим ещё раз\n }\n}\n\n// === /find или кнопка ===\nif (text.startsWith('/find ') || callbackData === 'find_mode') {\n const search = text.startsWith('/find ') ? text.slice(6).trim() : '';\n if (!search && text !== '/find') {\n return [{ json: { chatId, action: 'find_mode' } }];\n }\n return [{ json: { chatId, search, action: 'find' } }];\n}\n\nreturn [{ json: { chatId, action: 'menu' } }];"},"name":"Parse","type":"n8n-nodes-base.function","typeVersion":1,"position":[-1616,32],"id":"58d61cc2-c411-4c2e-91bd-b2827805deb8"},{"parameters":{"authentication":"genericCredentialType","genericAuthType":"httpBasicAuth","url":"http://10.33.33.1:8738/rest/ip/firewall/address-list","options":{}},"name":"Get All IPs","type":"n8n-nodes-base.httpRequest","typeVersion":2,"position":[-912,-32],"id":"6072ec58-eeb3-4596-872b-991416ebfbed","credentials":{"httpBasicAuth":{"id":"gBAUOrSceRAWqNfB","name":"mikrot api"}}},{"parameters":{"authentication":"genericCredentialType","genericAuthType":"httpBasicAuth","requestMethod":"={{ $json.action === 'delete' ? 'DELETE' : 'PATCH' }}","url":"http://10.33.33.1:8738/rest/ip/firewall/address-list/{{ $json.entryId }}","jsonParameters":true,"options":{},"bodyParametersJson":"={{ $json.action === 'delete' ? {} : { list: $json.newList } }}"},"name":"Move or Delete","type":"n8n-nodes-base.httpRequest","typeVersion":2,"position":[-912,496],"id":"c059b155-ff98-433a-82fb-2e4e883934bb","credentials":{"httpBasicAuth":{"id":"gBAUOrSceRAWqNfB","name":"mikrot api"}}},{"parameters":{"authentication":"genericCredentialType","genericAuthType":"httpBasicAuth","requestMethod":"POST","url":"http://10.33.33.1:8738/rest/ip/firewall/address-list/add","jsonParameters":true,"options":{},"bodyParametersJson":"={{\n {\n \"address\": $json.ip,\n \"list\": $json.list,\n \"timeout\": $json.timeout,\n \"comment\": $json.comment\n }\n}}"},"name":"Add or Update IP","type":"n8n-nodes-base.httpRequest","typeVersion":2,"position":[-912,288],"id":"1bf702a3-cafc-4d3e-b993-66620011481b","credentials":{"httpBasicAuth":{"id":"gBAUOrSceRAWqNfB","name":"mikrot api"}}},{"parameters":{"chatId":"={{ $json.chatId }}","text":"={{$json.text}}","replyMarkup":"inlineKeyboard","additionalFields":{}},"name":"Send Inline Results","type":"n8n-nodes-base.telegram","typeVersion":1,"position":[-416,-32],"id":"2c319907-41c4-420b-85f0-d6d3ae1b02fa","webhookId":"a698532b-1bce-4863-9bd5-5ab4ba641b64","credentials":{"telegramApi":{"id":"L9KHcMiteyKROF5r","name":"Telegram main n8n"}}},{"parameters":{"chatId":"={{ $json.chatId }}","text":"*Управление MikroTik через Telegram*","replyMarkup":"inlineKeyboard","inlineKeyboard":{"rows":[{"row":{"buttons":[{"text":"Добавить IP","additionalFields":{"callback_data":"add_ip"}},{"text":"Найти по комментарию","additionalFields":{"callback_data":"find_mode"}},{"text":"Обновить","additionalFields":{"callback_data":"menu"}}]}}]},"additionalFields":{}},"name":"Show Menu","type":"n8n-nodes-base.telegram","typeVersion":1,"position":[-912,-416],"id":"1bceeba2-7681-43d4-9d03-1aa72f147211","webhookId":"4ecab171-6694-4e92-85c2-bbc18f374ee2","credentials":{"telegramApi":{"id":"L9KHcMiteyKROF5r","name":"Telegram main n8n"}}},{"parameters":{"chatId":"={{ $json.chatId }}","text":"Отправь команду в формате: `/addip 1.2.3.4 ts01srv 7d \"Иван из офиса\"`","additionalFields":{}},"name":"Request Add","type":"n8n-nodes-base.telegram","typeVersion":1,"position":[-912,-256],"id":"f1c341dc-0dab-48ef-b901-289b3183608f","webhookId":"4ecab171-6694-4e92-85c2-bbc18f374ee2","credentials":{"telegramApi":{"id":"L9KHcMiteyKROF5r","name":"Telegram main n8n"}}},{"parameters":{"chatId":"={{ $json.chatId }}","text":"Напиши команду `/find часть_комментария`\nНапример: `/find Иван`","additionalFields":{}},"name":"Request Find","type":"n8n-nodes-base.telegram","typeVersion":1,"position":[-912,112],"id":"81974336-6d75-4cbe-9881-cbce4bb9b8d2","webhookId":"4ecab171-6694-4e92-85c2-bbc18f374ee2","credentials":{"telegramApi":{"id":"L9KHcMiteyKROF5r","name":"Telegram main n8n"}}},{"parameters":{"chatId":"={{ $('Telegram Trigger').item.json.message.from.id }}","text":"=IP {{ $('Parse').item.json.ip }} успешно добавлен в лист *{{ $('Parse').item.json.list }}*","additionalFields":{}},"name":"Add Success","type":"n8n-nodes-base.telegram","typeVersion":1,"position":[-672,288],"id":"63ab56fb-7f70-4aed-a8ea-a5ffed0885f1","webhookId":"a698532b-1bce-4863-9bd5-5ab4ba641b64","credentials":{"telegramApi":{"id":"L9KHcMiteyKROF5r","name":"Telegram main n8n"}}},{"parameters":{"chatId":"={{ $json.chatId }}","text":"{{ $json.action === 'delete' ? 'Запись удалена' : 'Лист изменён на *' + $json.newList + '*' }}","additionalFields":{}},"name":"Confirm Action","type":"n8n-nodes-base.telegram","typeVersion":1,"position":[-672,496],"id":"4c4442e9-cb91-473b-acb0-6dd0667604c9","webhookId":"a698532b-1bce-4863-9bd5-5ab4ba641b64","credentials":{"telegramApi":{"id":"L9KHcMiteyKROF5r","name":"Telegram main n8n"}}},{"parameters":{"dataType":"string","value1":"={{ $json.action }}","rules":{"rules":[{"value2":"menu"},{"value2":"add_ip","output":1},{"value2":"find_mode","output":2},{"value2":"find","output":3}]},"fallbackOutput":0},"name":"Router","type":"n8n-nodes-base.switch","typeVersion":1,"position":[-1344,-112],"id":"95298746-e82b-4f28-8938-75f2634caa11"},{"parameters":{"dataType":"string","value1":"={{ $json.action }}","rules":{"rules":[{"value2":"add_or_update"},{"value2":"delete","output":1},{"value2":"move","output":2}]}},"name":"Router1","type":"n8n-nodes-base.switch","typeVersion":1,"position":[-1344,160],"id":"08f0a7ac-b127-4721-949d-ff8d2c19096d"},{"parameters":{"jsCode":"// === 1. ПОЛУЧЕНИЕ И НОРМАЛИЗАЦИЯ ДАННЫХ ===\nconst rawItems = $input.all();\nlet items = [];\n\n// Распаковка массива (фикс для n8n)\nif (rawItems.length === 1 && Array.isArray(rawItems[0].json)) {\n items = rawItems[0].json.map(record => ({ json: record }));\n} else {\n items = rawItems;\n}\n\n// === 2. ПОЛУЧЕНИЕ ЗАПРОСА ===\nlet query = '';\nlet chatId = null;\n\ntry {\n const parseData = $('Parse').first().json;\n query = (parseData.search || '').toString().toLowerCase().trim();\n chatId = parseData.chatId;\n} catch (e) {\n if (rawItems.length > 0) chatId = rawItems[0].json.chatId;\n}\n\n// Если запроса нет — выходим\nif (!query) {\n return [{\n json: {\n chatId: chatId,\n text: \"⚠️ Ошибка: Нет поискового запроса.\",\n parse_mode: \"Markdown\"\n }\n }];\n}\n\n// === 3. ФИЛЬТРАЦИЯ (ТОЛЬКО ПО КОММЕНТАРИЯМ) ===\nconst matchedItems = items.filter(item => {\n const json = item.json || item;\n \n // Пропускаем пустые записи\n if (!json.address && !json.list) return false;\n\n // Берем значения полей\n const comment = (json.comment || '').toString().toLowerCase();\n const address = (json.address || '').toString().toLowerCase();\n \n // !!! ГЛАВНОЕ ИЗМЕНЕНИЕ ЗДЕСЬ !!!\n // Мы убрали \"list.includes(query)\", теперь поиск идет ТОЛЬКО по:\n // 1. Комментарию\n // 2. IP-адресу (это удобно оставить)\n return comment.includes(query) || address.includes(query);\n});\n\n// === 4. ЕСЛИ НИЧЕГО НЕ НАЙДЕНО ===\nif (matchedItems.length === 0) {\n return [{\n json: {\n chatId: chatId,\n text: `❌ *Ничего не найдено*\\n\\nПоиск по комментарию: \\`${query}\\`\\nПроверено записей: \\`${items.length}\\``,\n parse_mode: \"Markdown\"\n }\n }];\n}\n\n// === 5. РИСУЕМ КНОПКИ ===\nreturn matchedItems.map(item => {\n const e = item.json || item;\n const id = e['.id'] || e.id;\n \n const safeList = (e.list || 'нет').toString().replace(/_/g, '\\\\_').replace(/\\*/g, '\\\\*');\n const safeComment = (e.comment || '—').toString().replace(/_/g, '\\\\_').replace(/\\*/g, '\\\\*');\n \n return {\n json: {\n chatId: chatId,\n text: `*Комментарий:* ${safeComment}\\n*IP:* \\`${e.address}\\`\\n*Лист:* ${safeList}`, // Поменял порядок строк для удобства\n parse_mode: \"Markdown\",\n reply_markup: {\n inline_keyboard: [\n [\n { text: 'trusted', callback_data: `to|${id}|trusted` },\n { text: 'blocked', callback_data: `to|${id}|blocked` },\n { text: 'vpn', callback_data: `to|${id}|vpn` }\n ],\n [\n { text: 'Удалить', callback_data: `del|${id}` }\n ]\n ]\n }\n }\n };\n});"},"type":"n8n-nodes-base.code","typeVersion":2,"position":[-672,-32],"id":"90391b05-bda6-4703-9781-dcd9d365ca34","name":"Code in JavaScript"}],"connections":{"Telegram Trigger":{"main":[[{"node":"Parse","type":"main","index":0}]]},"Parse":{"main":[[{"node":"Router","type":"main","index":0},{"node":"Router1","type":"main","index":0}]]},"Get All IPs":{"main":[[{"node":"Code in JavaScript","type":"main","index":0}]]},"Move or Delete":{"main":[[{"node":"Confirm Action","type":"main","index":0}]]},"Add or Update IP":{"main":[[{"node":"Add Success","type":"main","index":0}]]},"Router":{"main":[[{"node":"Show Menu","type":"main","index":0}],[{"node":"Request Add","type":"main","index":0}],[{"node":"Request Find","type":"main","index":0}],[{"node":"Get All IPs","type":"main","index":0}]]},"Router1":{"main":[[{"node":"Add or Update IP","type":"main","index":0}],[{"node":"Move or Delete","type":"main","index":0}],[{"node":"Move or Delete","type":"main","index":0}]]},"Code in JavaScript":{"main":[[{"node":"Send Inline Results","type":"main","index":0}]]}},"settings":{"executionOrder":"v1"},"staticData":null,"meta":{"templateCredsSetupCompleted":true},"pinData":{},"versionId":"86cbc0e5-3898-4bec-acb4-b2d839b0a7f8","activeVersionId":null,"triggerCount":1,"shared":[{"updatedAt":"2025-12-08T11:04:55.349Z","createdAt":"2025-12-08T11:04:55.349Z","role":"workflow:owner","workflowId":"WH2YAlOoEGwYhFVG","projectId":"sYuiFAb87pAir6jV"}],"activeVersion":null,"tags":[]}