Deze implementatie werd me aangereikt door Alexander Koryukin met zijn publicatie ««.
En een opmerking in een van de VK-groepen van Kirill Kazakov:
Ja, dat is echt niet veilig. Ik zou liever een Telegram-bot schrijven die alleen commando's van mijn account accepteert voor inschakeling.
Ik besloot zo'n bot te schrijven.
Dus, het eerste wat je moet doen – is een bot creëren in Telegram.
- Zoek naar het account met de naam @botfather
- Klik op de knop Start onderaan het scherm
- Daarna typ je het commando /newbot
Vervolgens beantwoorden we 2 eenvoudige vragen:
- De eerste vraag – de naam van de te creëren bot MyMikrotikROuter
- De tweede vraag – de gebruikersnaam van de te creëren bot (moet eindigen op bot) MikrotikROuter_bot
Als antwoord krijgen we de token van onze bot, in mijn geval is dit:
Gebruik deze token om toegang te krijgen tot de HTTP API: 265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4

Zoek vervolgens onze bot op met de naam @MikrotikROuter_boten klik op de knop Start.
Daarna moet je de browser openen en de volgende regel invoeren:
https://api.telegram.org/botXXXXXXXXXXXXXXXXXX/getUpdates
Waarbij XXXXXXXXXXXXXXXXXX – jouw bot-token is.
Een pagina zal ongeveer als volgt openen:

Zoek naar de volgende tekst:
«chat»:{«id»:631290,
Dus, we hebben alle benodigde informatie om scripts voor Mikrotik te schrijven, namelijk:
Token van de bot: 265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4
ID van de chat, waar deze naar moet schrijven: 631290
Ter controle kunnen we via de browser gaan:
https://api.telegram.org/bot265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4/sendmessage?chat_id=631290&text=test
We zouden resultaat moeten krijgen:

Voor ons gemak voegen we meteen commando's toe voor de bot:
Zoek naar het account met de naam @botfather
Daarna geven we hem het commando /setcommands
- Hij zal vragen om welke bot
We schrijven:
@MikrotikROuter_bot
Voeg de volgende commando's toe:
- helloworld< — Testbericht op chat 1
- itsworking — Testbericht op chat 2
- wolmypc — zet mijn PC aan
Nu, als we «/» in de chat invoeren, zouden we moeten krijgen:

Nu gaan we verder met MikroTik.
In RouterOS is er een console-tool voor het kopiëren van bestanden via ftp of http/https, de tool heet fetch, die gaan we gebruiken.
Open terminal en voer in:
/tool fetch url="https://api.telegram.org/bot265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4/sendmessage?chat_id=631290&text=test " keep-result=no
Let op, in MikroTik is een «» nodig om het teken «?» in de URL te escapen.
We zouden resultaat moeten krijgen:

Nu gaan we verder met de scripts:
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"
Vergeet niet het juiste mac-adres en interface-naam op te geven, evenals de bot-token en chat_id.
Laat me nu kort uitleggen wat ze doen:
Het script "helloworld" verstuurt een bericht: "Hello, world!" naar onze chat met de bot.
Het script "itsworking" verstuurt een bericht: "Test OK, het werkt!" naar onze chat met de bot.
Deze scripts dienen ter demonstratie.
Ik heb het script "wolmypc" toegevoegd als een van de mogelijke implementaties.
Na het uitvoeren van het script zal de bot in de chat "wol OK" schrijven.
In principe kun je absoluut elk script uitvoeren.
We maken een taak aan:
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
Leesbare weergaveHet is onduidelijk waarom, maar het werkende script geeft geen globale gegevens vrij, ik heb het script toegevoegd bij het opstarten van het systeem.
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=Ik kan niet met je praten.") keep-result=no} ;
:tool fetch url=("https://api.telegram.org/".$botID."/getUpdates?offset=$messageId") keep-result=no;
}
Hoe het werkt
We downloaden onze berichten "getUpdates" iedere 30 seconden en parseren dan om te weten update_id (berichtnummer) en text (onze commando's) en chat_id . Standaard geeft getUpdates 1 tot 100 berichten weer; om het gemakkelijker te maken, verwijderen we het bericht eenmaal gelezen. In de Telegram API staat dat om een bericht te lezen, je het berichtnummer + 1 nodig hebt.
/getUpdates?offset=update_id + 1
Alles is getest op Mikrotik rb915 RouterOS 6.37.1
Als je veel opdrachten tegelijk verstuurt, worden ze allemaal na elkaar uitgevoerd met een interval van 30 seconden.
P.S. Een grote dank aan Kirill Kazakov voor het idee en mijn vriend Alexander voor de hulp met de scripts.
Links
:Scripting
upd:
03:11:16
Scripts aangepast:
Controle op chat_id toegevoegd
Een controle om te voorkomen dat iemand met onze bot communiceert, hij antwoordt: » Ik kan niet met jou praten. «, hij zal ook ons antwoorden als hij de opdracht niet herkent.
Na het uitvoeren van de opdracht, rapporteert de bot in de chat (zie script wolmypc)
UPD
We hebben gevonden met dat een bestand met meer dan ~ 14 berichten stopt met reageren op de opdracht find (beperkingen Mikrotik). Daarom zal ik het script in de toekomst herschrijven naar lua, bedankt daarvoor, ik wist niets over lua.
UPD 08.12.2016
in Telegram is blijkbaar een beetje veranderd hoe getUpdate werkt. nu moet in het hoofdschema de offset van het bericht van 2 naar 1 worden aangepast
wijzigingen
:local message [:pick $content ($startLoc + 2) $endLoc] ;
vervangen door :
:local message [:pick $content ($startLoc + 1) $endLoc] ;
Bron: habr.com
