1
Ноя

Удалённое включение скриптов Mikrotik из Telegrem

Содержание

На данную реализацию меня подтолкнул Кирилл GeXoGeN Казаков своей публикацией «Удалённое включение компьютера бесплатно, без SMS и без облаков, с помощью Mikrotik». А именно, вот эта его цитата:

Да уж, совсем не секьюрно. Я бы лучше написал телеграм бота, который принимает только с моего аккаунта команды на включение.

Я решил написать такого бота.

Итак, первое, что нужно сделать – это создать бота в telegram.

  • Находим в поиске аккаунт с именем @botfather
  • Нажимаем на кнопку Start в нижней части экрана
  • После чего пишем ему команду /newbot

Потом отвечаем на 2 несложных вопроса:

  • Первый вопрос – имя создаваемого бота MyMikrotikROuter
  • Второй вопрос – ник создаваемого бота (должен оканчиваться на bot) MikrotikROuter_bot

В ответ получим токен нашего бота, в моём случае это:

Use this token to access the HTTP API: 265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4

image

Затем, нужно найти нашего бота в поиске по имени @MikrotikROuter_bot и нажать на кнопку Start.

После этого нужно открыть браузер и ввести следующую строку:

<code class="bash hljs"> https://api.telegram.org/botXXXXXXXXXXXXXXXXXX/getUpdates

Где XXXXXXXXXXXXXXXXXX – токен вашего бота.

Откроется страница примерно следующего вида:

image

Находим на ней следующий текст:

«chat»:{«id»:631290,

Итак, у нас есть вся необходимая информация для написания скриптов для Mikrotik’а, а именно:

Токен бота: 265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4

ID чата, куда он должен писать: 631290

Для проверки можем зайти через браузер:

<code class="bash hljs">https://api.telegram.org/bot&lt;i&gt;&lt;b&gt;265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4&lt;/b&gt;&lt;/i&gt;/sendmessage?chat_id=&lt;i&gt;&lt;b&gt;631290&lt;/b&gt;&lt;/i&gt;&amp;text=&lt;b&gt;<span class="hljs-built_in">test</span>&lt;/b&gt;

Должны получить результат:

image

Для нашего удобства, сразу добавим команды для бота:

Находим аккаунт с именем @botfather
После чего пишем ему команду /setcommands

  • Он спросит какому боту

Пишем:
@MikrotikROuter_bot

Добавляем команды:

  • helloworld< — Test message on chat 1
  • itsworking — Test Message on chat 2
  • wolmypc — wake Up my PC

Теперь если набрать в чате «/», то должны получить:

image

Теперь переходим к MikroTik.

В RouterOS есть консольная утилита для копирования файлов через ftp или http/https, утилита называется fetch, именно ей мы и будем пользоваться.

Открываем terminal и вводим:

<code class="bash hljs">/tool fetch url=<span class="hljs-string">"https://api.telegram.org/bot265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4/sendmessage\?chat_id=631290&amp;text=test "</span> keep-result=no

Обратите внимание в MikroTik необходим «\» для экранирования знака «?» в URL.

Должны получить результат:

image

Теперь переходим к сриптам:

helloworld

<code class="bash hljs">system script add name=<span class="hljs-string">"helloworld"</span> policy=<span class="hljs-built_in">read</span> <span class="hljs-built_in">source</span>={/tool fetch url=<span class="hljs-string">"https://api.telegram.org/bot265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4/sendmessage\?chat_id=631290&amp;text=Hello,world! "</span> keep-result=no}

itsworking

<code class="bash hljs">system script add name=<span class="hljs-string">"itsworking"</span> policy=<span class="hljs-built_in">read</span> <span class="hljs-built_in">source</span>={/tool fetch url=<span class="hljs-string">"https://api.telegram.org/bot265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4/sendmessage\?chat_id=631290&amp;text=Test OK, it's Working "</span> keep-result=no}

wolmypc

<code class="bash hljs">system script add name=<span class="hljs-string">"wolmypc"</span> policy=<span class="hljs-built_in">read</span> <span class="hljs-built_in">source</span>={//tool wol mac=XX:XX:XX:XX:XX:XX interface=ifname}

Не забываем указать правильный mac и имя интерфейс.

Сейчас немного поясню что они делаю:

Скрипт «helloworld» отправляет сообщение: » Hello,world!» в наш чат с ботом.
Скрипт «itsworking» отправляет сообщение: » Test OK, it’s Working !» в наш чат с ботом.
Данные скрипты для демонстрации работы.
Скрипт «wolmypc» я добавил, как одну из возможных реализации.
По сути можно запускать абсолютно любой скрипт.

Создаем задание:

Telegram

<code class="bash hljs">/system scheduler add interval=30s name=Telegram on-event=<span class="hljs-string">":global botID \"bot265373548:AAFyGCqJCei9m\
    vcxvXOWBfnjSt1p3sX1XH4\"\r\
    \n:tool fetch url=(\"https://api.telegram.org/\".\$botID.\"/getUpdates\")\
    \r\
    \n:global content [/file get [/file find name=getUpdates] contents] ;\r\
    \n:global startLoc 0;\r\
    \n:do {\r\
    \n:set startLoc  [:find \$content \"update_id\" \$lastEnd ] ;\r\
    \n:set startLoc ( \$startLoc + 11 ) ;\r\
    \n:local endLoc [:find \$content \",\" \$startLoc] ;\r\
    \n:local messageId ([:pick \$content \$startLoc \$endLoc] + (1));\r\
    \n:put [\$messageId]\r\
    \n:set startLoc  [:find \$content \"text\" \$lastEnd ] ;\r\
    \n:set startLoc ( \$startLoc  + 7 ) ;\r\
    \n:local endLoc [:find \$content \",\" (\$startLoc)] ;\r\
    \n:set endLoc ( \$endLoc - 1 ) ;\r\
    \n:local message [:pick \$content (\$startLoc + 2) \$endLoc] ;\r\
    \n:put [\$message]\r\
    \n:system script run \$message\r\
    \n:tool fetch url=(\"https://api.telegram.org/\".\$botID.\"/getUpdates\\\?\
    offset=\$messageId\") keep-result=no\r\
    \n}\r\
    \n"</span> policy=\
    ftp,reboot,<span class="hljs-built_in">read</span>,write,policy,<span class="hljs-built_in">test</span>,password,sniff,sensitive,romon \
    start-date=nov/01/2016 start-time=00:00:00

 

Читаемый вид

:global botID «bot265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4» # Необходимо указать bot token
:tool fetch url=(«api.telegram.org».$botID.»/getUpdates»)
:global content [/file get [/file find name=getUpdates] contents];
:global startLoc 0;
:do {
:set startLoc [:find $content «update_id» $lastEnd ];
:set startLoc ( $startLoc + 11 );
:local endLoc [:find $content «,» $startLoc];
:local messageId ([:pick $content $startLoc $endLoc] + (1));
:put [$messageId]
:set startLoc [:find $content «text» $lastEnd ];
:set startLoc ( $startLoc + 7 );
:local endLoc [:find $content «,» ($startLoc)];
:set endLoc ( $endLoc — 1 );
:local message [:pick $content ($startLoc + 2) $endLoc];
:put [$message]
:system script run $message
:tool fetch url=(«api.telegram.org».$botID.»/getUpdates\?offset=$messageId») keep-result=no
}

 

Как это работает

Скачиваем наши сообщения «getUpdates» каждые 30 сек., затем парсим, чтобы узнать update_id (номер сообщения) и text (наши команды). По умолчанию getUpdates выводит от 1 до 100 сообщений, для удобства после прочтения команды, сообщение удаляем. в Telegram api сказано, чтобы прочесть сообщение необходимо номер сообщения + 1

/getUpdates?offset=update_id + 1

Все проверено на Mikrotik rb915 RouterOS 6.37.1
Если отправить сразу много команд, они все по очереди будут выполняться с интервалом 30 сек.

P.S. Огромное спасибо Кирилу Казакову за идею и Блажееву Александру за помощь со скриптами.