Тази реализация беше вдъхновена от Александър Корюкин с публикацията си ««.
И коментар в една от групите на ВК на Кирил Казаков:
Да, наистина не е много сигурно. По-добре бих написала Telegram бот, който приема команди за включване само от моя акаунт.
Реших да напиша такъв бот.
И така, първото нещо, което трябва да направим, е да създадем бот в Telegram.
- Намираме в търсенето акаунт с името @botfather
- Натискаме бутона Start в долната част на екрана
- След това му пишем командата /newbot
След това отговаряме на 2 несложни въпроса:
- Първият въпрос – името на създавания бот MyMikrotikROuter
- Вторият въпрос – никнейм на създавания бот (трябва да завършва на bot) MikrotikROuter_bot
В отговор ще получим токена на нашия бот, в моя случай това е:
Използвайте този токен, за да достъпите HTTP API: 265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4

След това, трябва да намерим нашия бот в търсенето по име @MikrotikROuter_boт и да натиснем бутона Start.
След това трябва да отворим браузър и да въведем следния ред:
https://api.telegram.org/botXXXXXXXXXXXXXXXXXX/getUpdates
Където XXXXXXXXXXXXXXXXXX – токенът на вашия бот.
Ще се открие страница, подобна на следната:

Намираме на нея следния текст:
«chat»:{«id»:631290,
И така, имаме всяка необходима информация за написване на скриптове за Mikrotik, а именно:
Токен на бота: 265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4
ID на чата, в който трябва да пише: 631290
За проверка можем да влезем през браузъра:
https://api.telegram.org/bot265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4/sendmessage?chat_id=631290&text=test
Трябва да получим резултат:

За наше удобство, веднага добавяме команди за бота:
Намираме акаунт с името @botfather
След което му пишем командата /setcommands
- Той ще попита за кой бот
Пишем:
@MikrotikROuter_bot
Добавяме командите:
- helloworld< — Тестово съобщение в чата 1
- itsworking — Тестово съобщение в чата 2
- wolmypc — събуди моя компютър
Сега, ако напишем в чата «/», трябва да получим:

Сега преминаваме към MikroTik.
В RouterOS има конзолна утилита за копиране на файлове през ftp или http/https, утилитата се нарича fetch, именно нея ще използваме.
Отваряме terminal и въвеждаме:
/tool fetch url="https://api.telegram.org/bot265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4/sendmessage?chat_id=631290&text=test " keep-result=no
Обърнете внимание, че в MikroTik е необходим «» за екраниране на знака «?» в URL.
Трябва да получим резултат:

Сега преминаваме към скриптовете:
helloworld
system script add name="helloworld" policy=read source={/tool fetch url="https://api.telegram.org/bot265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4/sendmessage?chat_id=631290&text=Hello,world! " keep-result=no}
itsworking
system script add name="itsworking" policy=read source={/tool fetch url="https://api.telegram.org/bot265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4/sendmessage?chat_id=631290&text=Test OK, it's Working " keep-result=no}
wolmypc
system script add name="wolmypc" policy=read source="/tool wol mac=XX:XX:XX:XX:XX:XX interface=ifnamer
n/tool fetch url="https://api.telegram.org/boXXXXXXXXXXXXXXXXXXX?chat_id=631290&text=wol OK" keep-result=no"
Не забравяйте да посочите правилния MAC адрес и име на интерфейса, както и bot-token и chat_id.
Сега ще обясня какво правят те:
Скриптът «helloworld» изпраща съобщение: » Hello, world!» в нашия чат с бота.
Скриптът «itsworking» изпраща съобщение: » Test OK, it’s Working !» в нашия чат с бота.
Тези скриптове са за демонстрация на работата.
Скриптът «wolmypc» добавих като една от възможните реализации.
След изпълнението на скрипта ботът ще напише в чата «wol OK».
Всъщност можете да стартирате абсолютно всеки скрипт.
Създаваме задача:
Telegram.src
/system scheduler
add interval=30s name=Telegram on-event=":tool fetch url=("https://api.telegr
am.org/".$botID."/getUpdates") ;r
n:global content [/file get [/file find name=getUpdates] contents] ;r
n:global startLoc 0;r
n:global endLoc 0;r
nr
n:if ( [/file get [/file find name=getUpdates] size] > 50 ) do={r
nr
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:#log info message="updateID $messageId" ;r
nr
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:#log info message="message $message ";r
nr
n:set startLoc [:find $content "chat" $lastEnd ] ;r
n:set startLoc ( $startLoc + 12 ) ;r
n:local endLoc [:find $content "," $startLoc] ;r
n:local chatId ([:pick $content $startLoc $endLoc]);r
n:put [$chatId] ;r
n:#log info message="chatID $chatId ";r
nr
n:if (($chatId = $myChatID) and (:put [/system script find name=$messa
ge] != "")) do={r
n:system script run $message} else={:tool fetch url=("https://api.teleg
ram.org/".$botID."/sendmessage?chat_id=".$chatId."&text=I can't t
alk with you. ") keep-result=no} ;r
n:tool fetch url=("https://api.telegram.org/".$botID."/getUpdates?
offset=$messageId") keep-result=no; r
n} r
n" policy=
ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon
start-date=nov/02/2010 start-time=00:00:00
add name=Telegram-startup on-event=":delay 5r
n:global botID "botXXXXXXXXXXXXXXXXXX" ;r
n:global myChatID "631290" ;r
n:global startLoc 0;r
n:global endLoc 0;r
n:tool fetch url=("https://api.telegram.org/".$botID."/getUpdates")
;" policy=
ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon
start-time=startup
Читаем видне е ясно защо, но от работещия скрипт не се извеждат глобални данни, добавих скрипт при зареждане на системата.
Telegram-startup
:delay 5
:global botID "botXXXXXXXXXXXXXXXXXX" ; token бот
:global myChatID "xxxxxx" ; chat_id
:global startLoc 0;
:global endLoc 0;
:tool fetch url=("https://api.telegram.org/".$botID."/getUpdates") ;
Telegram
:tool fetch url=("https://api.telegram.org/".$botID."/getUpdates") ;
:global content [/file get [/file find name=getUpdates] contents] ;
:global startLoc 0;
:global endLoc 0;
:if ( [/file get [/file find name=getUpdates] size] > 50 ) 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] ;
#:log info message="updateID $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] ;
#:log info message="message $message ";
:set startLoc [:find $content "chat" $lastEnd ] ;
:set startLoc ( $startLoc + 12 ) ;
:local endLoc [:find $content "," $startLoc] ;
:local chatId ([:pick $content $startLoc $endLoc]);
:put [$chatId] ;
#:log info message="chatID $chatId ";
:if (($chatId = $myChatID) and (:put [/system script find name=$message] != "")) do={
:system script run $message} else={:tool fetch url=("https://api.telegram.org/".$botID."/sendmessage?chat_id=".$chatId."&text=I can't talk with you. ") keep-result=no} ;
:tool fetch url=("https://api.telegram.org/".$botID."/getUpdates?offset=$messageId") keep-result=no;
}
Как работи
Сваляме нашите съобщения «getUpdates» на всеки 30 секунди, след това парсваме, за да разберем update_id (номер на съобщението) и ntext (нашите команди) и chat_id . По подразбиране getUpdates извежда от 1 до 100 съобщения, за удобство след прочитане на командата, съобщението се изтрива. В Telegram API е посочено, че за да прочетете съобщение, е необходимо номерът на съобщението + 1.
/getUpdates?offset=update_id + 1
Всичко е проверено на Mikrotik rb915 RouterOS 6.37.1.
Ако изпратите веднага много команди, те ще се изпълняват една след друга с интервал от 30 секунди.
P.S. Огромно благодаря на Кирил Казаков за идеята и на моя приятел Александър за помощта със скриптовете.
Връзки
:Скрипт
upd:
03:11:16
Усовершенствовал скрипты:
Добавил проверку на chat_id
Проверка на дурака: если кто-то напишет нашему боту, он ответит: «Я не могу с вами говорить», аналогично ответит, если не распознает команду.
После выполнения команды бот отправляет ответ в чат (см. Скрипт wolmypc)
UPD
Нашли с что файл с более чем ~ 14 сообщений перестает обрабатываться командой find (ограничение Mikrotik). Поэтому в будущем я переделаю скрипт на lua, спасибо. за это, о lua я не знал.
UPD 08.12.2016
в Telegram, видимо, немного изменили «выхлоп» getUpdate. теперь в основном скрипте нужно поправить смещение сообщения с 2 на 1
промени
:local message [:pick $content ($startLoc + 2) $endLoc];
заменить на:
:local message [:pick $content ($startLoc + 1) $endLoc];
Източник: habr.com
