Tento projekt mě přivedl Alexander Koryukin svou publikací „«.
A komentář v jedné z VK skupin Kirilla Kazakova:
No, rozhodně to není bezpečné. Raději bych napsal telegram bota, který přijímá příkazy na zapnutí pouze z mého účtu.
Rozhodl jsem se napsat takového bota.
Takže první věc, kterou musím udělat, je vytvořit bota v telegramu.
- Hledáme účet s uživatelským jménem @botfather
- Klikneme na tlačítko Start v dolní části obrazovky
- Poté mu napíšeme příkaz /newbot
Pak odpovíme na 2 jednoduché otázky:
- První otázka – jméno vytvářeného bota MyMikrotikROuter
- Druhá otázka – přezdívka vytvářeného bota (musí končit na bot) MikrotikROuter_bot
Dostaneme token našeho bota, v mém případě je to:
Použijte tento token pro přístup k HTTP API: 265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4

Pak musíme najít našeho bota ve vyhledávání podle jména @MikrotikROuter_bot a kliknout na tlačítko Start.
Poté otevřeme prohlížeč a zadáme následující řádek:
https://api.telegram.org/botXXXXXXXXXXXXXXXXXX/getUpdates
Kde XXXXXXXXXXXXXXXXXX – token vašeho bota.
Otevře se stránka přibližně takového vzhledu:

Hledáme na ní následující text:
„chat“:{„id“:631290,
Takže máme veškeré potřebné informace pro psaní skriptů pro Mikrotik, a to:
Token bota: 265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4
ID chatu, kam by měl psát: 631290
Pro kontrolu se můžeme podívat přes prohlížeč:
https://api.telegram.org/bot265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4/sendmessage?chat_id=631290&text=test
Měli bychom dostat výsledek:

Pro naše pohodlí ihned přidáme příkazy pro bota:
Hledáme účet s uživatelským jménem @botfather
Poté mu napíšeme příkaz /setcommands
- Zeptá se, kterému botu
Píšeme:
@MikrotikROuter_bot
Přidáváme příkazy:
- helloworld< — Testovací zpráva v chatu 1
- itsworking — Testovací zpráva v chatu 2
- wolmypc — probudím svůj počítač
Teď pokud napíšeme v chatu „/“, měli bychom dostat:

Teď přecházíme k MikroTik.
V RouterOS je konzolová utilita pro kopírování souborů přes ftp nebo http/https, utilita se nazývá fetch, a právě tu budeme používat.
Otevřete terminál a zadejte:
/tool fetch url="https://api.telegram.org/bot265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4/sendmessage?chat_id=631290&text=test " keep-result=no
Věnujte pozornost tomu, že v MikroTik je nezbytné „“ pro escapování znaku „?“ v URL.
Měli bychom dostat výsledek:

Teď přecházíme k skriptům:
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
/tool fetch url="https://api.telegram.org/boXXXXXXXXXXXXXXXXXXX?chat_id=631290&text=wol OK" keep-result=no"
Nezapomeňte uvést správný mac a název rozhraní, stejně jako bot-token a chat_id.
Teď trochu vysvětlím, co dělají:
Skript „helloworld“ odešle zprávu: » Ahoj, světe!« do našeho chatu s botem.
Skript „itsworking“ odešle zprávu: » Test OK, funguje to!« do našeho chatu s botem.
Tyto skripty slouží k demonstraci funkčnosti.
Skript „wolmypc“ jsem přidal jako jednu z možných realizací.
Po provedení skriptu bot napíše do chatu „wol OK“.
V podstatě lze spouštět jakýkoli skript.
Vytváříme úlohu:
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
Čitelný výstupnení jasné, proč, ale z pracovního skriptu neodhaluje globální data, přidal jsem skript při spuštění systému.
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=Nemohu s vámi komunikovat. ") keep-result=no} ;
:tool fetch url=("https://api.telegram.org/".$botID."/getUpdates?offset=$messageId") keep-result=no;
}
Jak to funguje
Stahujeme naše zprávy „getUpdates“ každých 30 sekund, poté je parsujeme, abychom zjistili update_id (číslo zprávy) a text (naše příkazy) a chat_id . Podle defaultu getUpdates vrací od 1 do 100 zpráv, pro pohodlí po přečtení příkazu zprávu odstraníme. V Telegram API je uvedeno, že pro přečtení zprávy je potřeba číslo zprávy + 1.
/getUpdates?offset=update_id + 1
Vše bylo otestováno na Mikrotik rb915 RouterOS 6.37.1
Pokud odešlete najednou mnoho příkazů, budou všechny vykonány postupně s intervalem 30 sekund.
P.S. Obrovské díky Kirillu Kazakovu za nápad a mému příteli Alexandru za pomoc se skripty.
Odkazy
:Scripting
upd:
03:11:16
Zlepšil jsem skripty:
Přidal jsem kontrolu na chat_id
Kontrola na nezbedu, pokud někdo napíše našemu botovi, odpoví mu: » Nemohu s tebou mluvit. «, podobně odpoví nám, pokud nerozpozná příkaz.
Po provedení příkazu bot zašle zprávu do chatu (viz Skript wolmypc)
UPD
Našli jsme s že soubor s více než ~ 14 zprávami přestává být zpracováván příkazem find (omezení Mikrotiku). Proto v budoucnu skript předělám na lua, díky za to, o lua jsem nevěděl.
UPD 08.12.2016
v Telegramu se zřejmě trochu změnil 'výstup' getUpdate. Teď je potřeba v hlavním skriptu opravit posun zprávy z 2 na 1
změny
:local message [:pick $content ($startLoc + 2) $endLoc] ;
nahraďte za :
:local message [:pick $content ($startLoc + 1) $endLoc] ;
Zdroj: habr.com
