Fjernaktivering af Mikrotik scripts fra Telegram

Denne implementering blev inspireret af Alexander Koryukin GeXoGeN i sin publikation “Fjernaktivering af computeren gratis, uden SMS og uden cloud, ved hjælp af Mikrotik«.

Og en kommentar i en af Kirill Kazakovs VK grupper:

Ja, det er bestemt ikke særligt sikkert. Jeg ville hellere skrive en telegram-bot, der kun tager imod kommandoer til aktivering via min konto.

Jeg besluttede at skrive sådan en bot.

Så det første, du skal gøre, er at oprette en bot i Telegram.

  • Find kontoen med navnet @botfather i søgningen
  • Tryk på knappen Start i bunden af skærmen
  • Herefter skriver vi kommandoen /newbot

Så svarer vi på 2 enkle spørgsmål:

  • Det første spørgsmål er navnet på den bot, der skal oprettes MyMikrotikROuter
  • Det andet spørgsmål er brugernavnet på den bot, der skal oprettes (skal ende på bot) MikrotikROuter_bot

Som svar vil vi få token til vores bot, i mit tilfælde er det:

Brug dette token til at få adgang til HTTP API: 265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4

Fjernaktivering af Mikrotik scripts fra Telegram
Derefter skal vi finde vores bot i søgningen efter navn @MikrotikROuter_bot og trykke på knappen Start.

Herefter skal vi åbne en browser og indtaste følgende linje:

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

Hvor XXXXXXXXXXXXXXXXXX er token til din bot.

En side åbnes, der ligner følgende:

Fjernaktivering af Mikrotik scripts fra Telegram

Find følgende tekst:

"chat":{ "id":631290,

Så har vi al den nødvendige information til at skrive scripts til Mikrotik, nemlig:

Bot token: 265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4

Chat ID, hvor den skal skrive: 631290

Til kontrol kan vi gå ind via browseren:

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

Skal få resultatet:

Fjernaktivering af Mikrotik scripts fra Telegram

For vores bekvemmelighed tilføjer vi straks kommandoer til botten:

Find kontoen med navnet @botfather
Herefter skriver vi kommandoen /setcommands

  • Han vil spørge hvilken bot

Skriv:
@MikrotikROuter_bot

Tilføj kommandoer:

  • helloworld< — Testmeddelelse på chat 1
  • itsworking — Testmeddelelse på chat 2
  • wolmypc — væk min PC

Nu, hvis du indtaster "\/" i chatten, skal du få:

Fjernaktivering af Mikrotik scripts fra Telegram

Nu går vi videre til MikroTik.

I RouterOS er der et kommandolinjeværktøj til at kopiere filer via ftp eller http/https, værktøjet hedder fetch, og det er det, vi vil bruge.

Åbn terminal og indtast:

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

Bemærk, at i MikroTik er „” nødvendig for at escaper ” tegn i URL.?Nu går vi videre til scripts:

Skal få resultatet:

Fjernaktivering af Mikrotik scripts fra Telegram

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

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"

Husk at angive den rigtige mac og interface-navn, samt bot-token og chat_id.

Lad mig forklare, hvad de gør:

Scriptet "helloworld" sender beskeden: » Hello, world! » til vores chat med botten.
Scriptet "itsworking" sender beskeden: » Test OK, det virker! » til vores chat med botten.
Disse scripts er til demonstration af funktionaliteten.
Scriptet "wolmypc" har jeg tilføjet som en af de mulige implementeringer.
Når scriptet kører, vil botten skrive i chatten "wol OK".
I princippet kan man køre fuldstændig hvilket som helst script.

Vi opretter en opgave:

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 visningDet er uklart hvorfor, men fra det fungerende script afslører global data ikke, jeg tilføjede scriptet ved systemopstart.
Telegram-startup

: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=Jeg kan ikke tale med dig.") keep-result=no} ;
:tool fetch url=("https://api.telegram.org/".$botID."/getUpdates?offset=$messageId") keep-result=no; 
} 

Hvordan fungerer det

Vi downloader vores beskeder "getUpdates" hvert 30. sekund, og derefter parser vi for at finde ud af update_id (beskednummer) og text (vores kommandoer) og chat_id . Som standard viser getUpdates mellem 1 og 100 beskeder, for nemheds skyld fjerner vi beskeden efter has læst kommandoen. I Telegram API står der, at for at læse en besked skal man bruge beskednummeret + 1.

/getUpdates?offset=update_id + 1

Alt er testet på Mikrotik rb915 RouterOS 6.37.1
Hvis man sender mange kommandoer på én gang, vil de alle blive udført en ad gangen med 30 sekunders interval.

P.S. Stort tak til Kirill Kazakov for idéen og min ven Alexander for hjælpen med scripts.

Links

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

upd:

03:11:16

Jeg har forbedret scriptterne:

Tilføjet kontrol for chat_id
Sikring mod uheldige forespørgsler; hvis nogen skriver til vores bot, vil den svare: » Jeg kan ikke tale med dig. «, og den vil svare os, hvis den ikke genkender kommandoen.
Efter udførelse af kommandoen sender botten en besked i chatten (se scriptet wolmypc)

UPD

Vi fandt med 7Stuntman7 at filen med over ~ 14 beskeder stopper med at blive behandlet af find-kommandoen (Mikrotik begrænsninger). Derfor vil jeg i fremtiden revidere scriptet til lua, tak for det. 7Stuntman7 om lua vidste jeg ikke.

UPD 08.12.2016

i Telegram ser det ud til, at de lidt har ændret uddata fra getUpdate. nu skal hovedscriptet rette meddelelseforskydningen fra 2 til 1

Optimeringer

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

ændre til:

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

Kilde: habr.com

Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere 🔥 Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere | ProHoster