Fjärraktivering av Mikrotik-skript från Telegram

Alexander Koryukin drev mig till denna implementering GeXoGeN med hans publiceringFjärrstarta datorn gratis, utan SMS och utan moln, med Mikrotik".

Och en kommentar i en av VK-grupperna av Kirill Kazakov:

Ja, det är inte säkert alls. Jag skulle hellre skriva en telegrambot som bara accepterar aktiveringskommandon från mitt konto.

Jag bestämde mig för att skriva en sådan bot.

Så det första du ska göra är att skapa en bot i telegram.

  • Vi hittar i sökningen ett konto som heter @botfather
  • Klicka på Start-knappen längst ner på skärmen
  • Sedan skriver vi kommandot / newbot till honom

Sedan svarar vi på 2 enkla frågor:

  • Den första frågan är namnet på boten som ska skapas. MyMikrotikROuter
  • Den andra frågan är smeknamnet på boten som skapas (ska sluta med bot) MikrotikROuter_bot

Som svar kommer vi att få token för vår bot, i mitt fall är det:

Använd denna token för att komma åt HTTP API: 265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4

Fjärraktivering av Mikrotik-skript från Telegram
Sedan måste du hitta vår bot i sökningen efter namn @MikrotikROuter_bot och tryck på Start-knappen.

Efter det måste du öppna webbläsaren och ange följande rad:

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

Där XXXXXXXXXXXXXXXXXX är din bots token.

En sida som liknar följande öppnas:

Fjärraktivering av Mikrotik-skript från Telegram

Vi hittar följande text på den:

"chat":{"id":631290,

Så vi har all nödvändig information för att skriva manus för Mikrotik, nämligen:

Bot-token: 265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4

Chatt-ID där han ska skriva: 631290

För att kontrollera kan vi gå igenom webbläsaren:

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

Bör få resultatet:

Fjärraktivering av Mikrotik-skript från Telegram

För vår bekvämlighet kommer vi omedelbart att lägga till kommandon för boten:

Hitta ett konto med ett namn @botfader
Sedan skriver vi ett kommando till honom / setcommands

  • Han kommer att fråga vilken bot

Vi skriver:
@MikrotikROuter_bot

Lägg till kommandon:

  • helloworld< — Testmeddelande på chatt 1
  • itsworking-Testmeddelande på chatt 2
  • wolmypc-väcka upp min dator

Om du nu skriver "/" i chatten bör du få:

Fjärraktivering av Mikrotik-skript från Telegram

Låt oss nu gå vidare till MikroTik.

RouterOS har ett konsolverktyg för att kopiera filer via ftp eller http/https, verktyget heter fetch, vilket är vad vi kommer att använda.

öppna terminala och skriv in:

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

Observera att MikroTik behöver "» att undkomma tecknet «?' i URL:en.

Bör få resultatet:

Fjärraktivering av Mikrotik-skript från Telegram

Låt oss nu gå vidare till skript:

Hej världen

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}

det fungerar

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"

Glöm inte att ange rätt mac- och gränssnittsnamn, samt bot-token och chat_id.

Nu ska jag förklara lite vad de gör:

"helloworld"-skriptet skickar ett meddelande: "Hej, värld!" till vår chatt med boten.
Skriptet "itsworking" skickar ett meddelande: "Testa OK, det fungerar!" till vår chatt med boten.
Dessa skript är för demonstrationsändamål.
Jag lade till "wolmypc"-skriptet som en av de möjliga implementeringarna.
När skriptet körs kommer boten att skriva "wol OK" till chatten.
Faktum är att du kan köra absolut vilket skript som helst.

Skapa en uppgift:

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

Läsbar vydet är inte klart varför, men från arbetsskriptet avslöjar det inte globala data, lade skriptet till när systemet startar.
Uppstart av Telegram

: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; 
} 

Hur fungerar den här

Ladda ner våra "getUpdates"-meddelanden var 30:e sekund och analysera sedan för att ta reda på det update_id (meddelandenummer) och text (våra lag) och chat_id . Som standard visar getUpdates från 1 till 100 meddelanden, för enkelhetens skull tar vi bort meddelandet efter att ha läst kommandot. Telegram api säger att för att läsa ett meddelande behöver du meddelandenumret + 1

/getUpdates?offset=update_id + 1

Alla testade på Mikrotik rb915 RouterOS 6.37.1
Om du skickar många kommandon samtidigt kommer de alla att utföras i tur och ordning med ett intervall på 30 sekunder.

PS Stort tack till Kirill Kazakov för idén och min vän Alexander för hjälp med manus.

referenser

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

upd:

03:11:16

Förbättrade skript:

Lade till check för chat_id
För att leta efter en dåre, om någon skriver till vår bot, kommer han att svara honom: "Jag kan inte prata med dig. ", kommer att svara oss på samma sätt om den inte känner igen kommandot.
Efter att ha utfört kommandot avslutar boten prenumerationen på chatten (se wolmypc-skriptet)

UPD

Hittade med 7 Stuntman7 att en fil med över ~14 meddelanden inte längre bearbetas av find-kommandot (Mikrotik-begränsningar). Därför kommer jag i framtiden att ändra manuset till lua, tack 7 Stuntman7 för detta visste jag inte om lua.

UPD 08.12.2016/XNUMX/XNUMX

i Telegram ändrade de tydligen "avgaserna" på getUpdate något. nu i huvudskriptet måste du korrigera meddelandeförskjutningen från 2 till 1

förändringar

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

заменить на :

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

Källa: will.com