Zdalna aktywacja skryptów Mikrotik z Telegrama

Alexander Koryukin popchnął mnie do tej realizacji GeXoGen z jego publikacjąZdalne włączanie komputera za darmo, bez SMS-ów i bez chmur, za pomocą Mikrotika".

I komentarz Kirilla Kazakowa w jednej z grup VK:

Tak, to wcale nie jest bezpieczne. Wolałbym napisać telegram bota, który przyjmuje tylko polecenia aktywacji z mojego konta.

Postanowiłem napisać takiego bota.

Pierwszą rzeczą do zrobienia jest utworzenie bota w telegramie.

  • W wyszukiwarce znajdujemy konto o nazwie @botfather
  • Kliknij przycisk Start u dołu ekranu
  • Następnie piszemy mu komendę /newbot

Następnie odpowiadamy na 2 proste pytania:

  • Pierwsze pytanie to nazwa bota, który ma zostać utworzony. MójMikrotikROuter
  • Drugie pytanie to nick tworzonego bota (powinno kończyć się na bot) MikrotikROuter_bot

W odpowiedzi otrzymamy token naszego bota, w moim przypadku jest to:

Użyj tego tokena, aby uzyskać dostęp do interfejsu HTTP API: 265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4

Zdalna aktywacja skryptów Mikrotik z Telegrama
Następnie musisz znaleźć naszego bota w wyszukiwaniu po nazwie @MikrotikROuter_boti naciśnij przycisk Start.

Następnie musisz otworzyć przeglądarkę i wprowadzić następujący wiersz:

 https://api.telegram.org/botXXXXXXXXXXXXXXXXXX/getUpdates

Gdzie XXXXXXXXXXXXXXXXXX to token twojego bota.

Otworzy się strona podobna do następującej:

Zdalna aktywacja skryptów Mikrotik z Telegrama

Znajdujemy na nim następujący tekst:

"czat":{"identyfikator":631290,

Mamy więc wszystkie niezbędne informacje do pisania skryptów dla Mikrotika, a mianowicie:

Token bota: 265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4

Identyfikator czatu, w którym powinien wpisać: 631290

Aby to sprawdzić, możemy przejść przez przeglądarkę:

https://api.telegram.org/bot265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4/sendmessage?chat_id=631290&text=test

Powinien otrzymać wynik:

Zdalna aktywacja skryptów Mikrotik z Telegrama

Dla naszej wygody od razu dodamy komendy dla bota:

Znalezienie konta z nazwą @ojciec
Następnie piszemy mu polecenie / setcommands

  • Zapyta, który bot

Piszemy:
@MikrotikROuter_bot

Dodaj polecenia:

  • helloworld< — Testowa wiadomość na czacie 1
  • itsworking-Test Wiadomość na czacie 2
  • wolmypc — obudź mój komputer

Teraz, jeśli wpiszesz „/” na czacie, powinieneś otrzymać:

Zdalna aktywacja skryptów Mikrotik z Telegrama

Przejdźmy teraz do MikroTika.

RouterOS ma narzędzie konsoli do kopiowania plików przez ftp lub http / https, narzędzie nazywa się fetch, z którego będziemy korzystać.

Otwarte terminal i wprowadź:

/tool fetch url="https://api.telegram.org/bot265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4/sendmessage?chat_id=631290&text=test " keep-result=no

Pamiętaj, że MikroTik potrzebuje „» uciec przed znakiem «?' w adresie URL.

Powinien otrzymać wynik:

Zdalna aktywacja skryptów Mikrotik z Telegrama

Przejdźmy teraz do skryptów:

Witaj świecie

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}

to działa

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-resul
    t=no"

Nie zapomnij podać poprawnej nazwy mac i interfejsu, a także bot-token i chat_id.

Teraz wyjaśnię trochę, co robią:

Skrypt „helloworld” wysyła wiadomość: „Witaj, świecie!” do naszego czatu z botem.
Skrypt „itsworking” wysyła wiadomość: „Test OK, działa!” do naszego czatu z botem.
Te skrypty służą do celów demonstracyjnych.
Dodałem skrypt „wolmypc” jako jedną z możliwych implementacji.
Po wykonaniu skryptu bot napisze na czacie „wol OK”.
W rzeczywistości możesz uruchomić absolutnie dowolny skrypt.

Utwórz zadanie:

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

Czytelny widoknie jest jasne, dlaczego, ale z działającego skryptu nie ujawnia globalnych danych, dodano skrypt podczas uruchamiania systemu.
Uruchomienie telegramu

:delay 5
:global botID "botXXXXXXXXXXXXXXXXXX" ;   token bot
: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; 
} 

Jak to działa

Pobierz nasze wiadomości „getUpdates” co 30 sekund, a następnie przeanalizuj, aby się dowiedzieć identyfikator_aktualizacji (numer wiadomości) i XNUMX (nasze zespoły) i identyfikator_czatu . Domyślnie getUpdates wyświetla od 1 do 100 wiadomości, dla wygody po przeczytaniu polecenia usuwamy wiadomość. Telegram api mówi, że aby przeczytać wiadomość, potrzebujesz numeru wiadomości + 1

/getUpdates?offset=update_id + 1

Wszystko przetestowane na Mikrotik rb915 RouterOS 6.37.1
Jeśli wyślesz wiele poleceń jednocześnie, wszystkie będą wykonywane po kolei w odstępie 30 sekund.

PS Wielkie dzięki dla Kirill Kazakov za pomysł i dla mojego przyjaciela Alexandra za pomoc przy scenariuszach.

referencje

habrahabr.ru/post/313794
1spla.ru/index.php/blog/telegram_bot_for_mikrotik
core.telegram.org/bots/api
wiki.mikrotik.com/wiki/Manual:Skryptowanie

aktualizacja:

03:11:16

Ulepszone skrypty:

Dodano sprawdzenie chat_id
Sprawdzając głupca, jeśli ktoś napisze do naszego bota, odpowie mu: „Nie mogę z tobą rozmawiać. „, podobnie odpowie nam, jeśli nie rozpozna polecenia.
Po wykonaniu polecenia bot wypisuje się z czatu (patrz skrypt wolmypc)

UPD

Znaleziono z 7Kaskader7 że plik z ponad ~14 komunikatami nie jest już przetwarzany przez polecenie find (ograniczenia Mikrotika). Dlatego w przyszłości zmienię skrypt na lua, dzięki 7Kaskader7 za to nie wiedziałem o lua.

UPD 08.12.2016

w Telegramie najwyraźniej nieznacznie zmienili „wyczerpanie” getUpdate. teraz w głównym skrypcie musisz poprawić przesunięcie komunikatu z 2 na 1

zmiany

:local message [:pick $content ($startLoc + 2) $endLoc] ;

заменить на :

:local message [:pick $content ($startLoc + 1) $endLoc] ;

Źródło: www.habr.com