Απομακρυσμένη ενεργοποίηση σεναρίων Mikrotik από το Telegram

Ο Alexander Koryukin με ώθησε σε αυτήν την εφαρμογή GeXoGeN με τη δημοσίευσή τουΑπομακρυσμένη ενεργοποίηση του υπολογιστή δωρεάν, χωρίς SMS και χωρίς σύννεφα, χρησιμοποιώντας το Mikrotik".

Και ένα σχόλιο σε μια από τις ομάδες VK από τον Kirill Kazakov:

Ναι, δεν είναι καθόλου ασφαλές. Θα προτιμούσα να γράψω ένα bot telegram που δέχεται μόνο εντολές ενεργοποίησης από τον λογαριασμό μου.

Αποφάσισα να γράψω ένα τέτοιο bot.

Έτσι, το πρώτο πράγμα που πρέπει να κάνετε είναι να δημιουργήσετε ένα bot στο τηλεγράφημα.

  • Βρίσκουμε στην αναζήτηση έναν λογαριασμό με το όνομα @botfather
  • Κάντε κλικ στο κουμπί Έναρξη στο κάτω μέρος της οθόνης
  • Στη συνέχεια του γράφουμε την εντολή / newbot

Στη συνέχεια απαντάμε σε 2 απλές ερωτήσεις:

  • Η πρώτη ερώτηση είναι το όνομα του bot που θα δημιουργηθεί. MyMikrotikROuter
  • Η δεύτερη ερώτηση είναι το ψευδώνυμο του ρομπότ που δημιουργείται (θα πρέπει να τελειώνει με bot) MikrotikROuter_bot

Σε απάντηση, θα λάβουμε το διακριτικό του bot μας, στην περίπτωσή μου είναι:

Χρησιμοποιήστε αυτό το διακριτικό για πρόσβαση στο HTTP API: 265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4

Απομακρυσμένη ενεργοποίηση σεναρίων Mikrotik από το Telegram
Στη συνέχεια, πρέπει να βρείτε το bot μας στην αναζήτηση με το όνομα @MikrotikROuter_bot και πατήστε το κουμπί Έναρξη.

Μετά από αυτό, πρέπει να ανοίξετε το πρόγραμμα περιήγησης και να εισαγάγετε την ακόλουθη γραμμή:

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

Όπου το XXXXXXXXXXXXXXXXXX είναι το διακριτικό του bot σας.

Θα ανοίξει μια σελίδα παρόμοια με την παρακάτω:

Απομακρυσμένη ενεργοποίηση σεναρίων Mikrotik από το Telegram

Βρίσκουμε το ακόλουθο κείμενο σε αυτό:

"chat":{"id":631290,

Έτσι, έχουμε όλες τις απαραίτητες πληροφορίες για τη συγγραφή σεναρίων για το Mikrotik, και συγκεκριμένα:

Token bot: 265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4

Αναγνωριστικό συνομιλίας όπου πρέπει να γράψει: 631290

Για έλεγχο, μπορούμε να περάσουμε από το πρόγραμμα περιήγησης:

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

Πρέπει να πάρετε το αποτέλεσμα:

Απομακρυσμένη ενεργοποίηση σεναρίων Mikrotik από το Telegram

Για διευκόλυνσή μας, θα προσθέσουμε αμέσως εντολές για το bot:

Εύρεση λογαριασμού με όνομα @botfather
Μετά του γράφουμε μια εντολή / setcommands

  • Θα ρωτήσει ποιο bot

Γράφουμε:
@MikrotikROuter_bot

Προσθήκη εντολών:

  • helloworld< — Δοκιμαστικό μήνυμα στη συνομιλία 1
  • λειτουργεί-Μήνυμα δοκιμής στη συνομιλία 2
  • wolmypc-ξυπνήστε τον υπολογιστή μου

Τώρα αν πληκτρολογήσετε "/" στη συνομιλία, θα πρέπει να λάβετε:

Απομακρυσμένη ενεργοποίηση σεναρίων Mikrotik από το Telegram

Τώρα ας περάσουμε στο MikroTik.

Το RouterOS έχει ένα βοηθητικό πρόγραμμα κονσόλας για αντιγραφή αρχείων μέσω ftp ή http / https, το βοηθητικό πρόγραμμα ονομάζεται fetch, το οποίο θα χρησιμοποιήσουμε.

Ανοίξτε τερματικό και εισάγετε:

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

Σημειώστε ότι η MikroTik χρειάζεται "» να ξεφύγεις από το σημάδι «?' στη διεύθυνση URL.

Πρέπει να πάρετε το αποτέλεσμα:

Απομακρυσμένη ενεργοποίηση σεναρίων Mikrotik από το Telegram

Τώρα ας περάσουμε στα σενάρια:

Γειά σου Κόσμε

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}

δουλεύει

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"

Μην ξεχάσετε να καθορίσετε το σωστό όνομα mac και διεπαφής, καθώς και το bot-token και το chat_id.

Τώρα θα εξηγήσω λίγο τι κάνουν:

Το σενάριο "helloworld" στέλνει ένα μήνυμα: "Γεια σου, κόσμο!" στη συνομιλία μας με το bot.
Το σενάριο "itsworking" στέλνει ένα μήνυμα: "Test OK, it's Working!" στη συνομιλία μας με το bot.
Αυτά τα σενάρια είναι για σκοπούς επίδειξης.
Πρόσθεσα το σενάριο "wolmypc" ως μία από τις πιθανές υλοποιήσεις.
Κατά την εκτέλεση του σεναρίου, το bot θα γράψει "wol OK" στη συνομιλία.
Στην πραγματικότητα, μπορείτε να εκτελέσετε απολύτως οποιοδήποτε σενάριο.

Δημιουργήστε μια εργασία:

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

Αναγνώσιμη προβολήδεν είναι ξεκάθαρο γιατί, αλλά από το σενάριο εργασίας δεν αποκαλύπτει καθολικά δεδομένα, προστέθηκε το σενάριο κατά την εκκίνηση του συστήματος.
Εκκίνηση 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; 
} 

Πώς λειτουργεί;

Κάντε λήψη των μηνυμάτων "getUpdates" κάθε 30 δευτερόλεπτα και, στη συνέχεια, αναλύστε για να μάθετε update_id (αριθμός μηνύματος) και κείμενο (οι ομάδες μας) και chat_id . Από προεπιλογή, το getUpdates εμφανίζει από 1 έως 100 μηνύματα, για ευκολία, αφού διαβάσουμε την εντολή, διαγράφουμε το μήνυμα. Το Telegram api λέει ότι για να διαβάσετε ένα μήνυμα χρειάζεστε τον αριθμό μηνύματος + 1

/getUpdates?offset=update_id + 1

Όλα δοκιμασμένα στο Mikrotik rb915 RouterOS 6.37.1
Εάν στείλετε πολλές εντολές ταυτόχρονα, θα εκτελεστούν όλες με τη σειρά τους με ένα διάστημα 30 δευτερολέπτων.

Υ.Γ Ευχαριστώ πολύ τον Kirill Kazakov για την ιδέα και τον φίλο μου Alexander για τη βοήθεια στα σενάρια.

παραπομπές

habrahabr.ru/post/313794
1spla.ru/index.php/blog/telegram_bot_for_mikrotik
core.telegram.org/bots/api
wiki.mikrotik.com/wiki/Manual: Σενάριο

ενημέρωση:

03:11:16

Βελτιωμένα σενάρια:

Προστέθηκε έλεγχος για chat_id
Έλεγχος για ανόητο, αν κάποιος γράψει στο bot μας, θα του απαντήσει: «Δεν μπορώ να μιλήσω μαζί σου. », θα μας απαντήσει ομοίως αν δεν αναγνωρίσει την εντολή.
Μετά την εκτέλεση της εντολής, το bot καταργεί την εγγραφή του στη συνομιλία (δείτε το σενάριο wolmypc)

UPD

Βρέθηκε με 7 Κασκαντέρ7 ότι ένα αρχείο με πάνω από ~14 μηνύματα δεν υποβάλλεται πλέον σε επεξεργασία από την εντολή εύρεσης (περιορισμοί Mikrotik). Επομένως, στο μέλλον, θα αλλάξω το σενάριο σε lua, ευχαριστώ 7 Κασκαντέρ7 για αυτό, δεν ήξερα για το lua.

UPD 08.12.2016/XNUMX/XNUMX

στο Telegram, προφανώς, άλλαξαν ελαφρώς την "εξάτμιση" του getUpdate. τώρα στο κύριο σενάριο πρέπει να διορθώσετε τη μετατόπιση του μηνύματος από το 2 στο 1

αλλαγές

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

заменить на :

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

Πηγή: www.habr.com