Activation à distance des scripts Mikrotik depuis Telegram

Alexander Koryukin m'a poussé à cette mise en œuvre GeXoGen avec sa publicationAllumer l'ordinateur à distance gratuitement, sans SMS et sans nuages, en utilisant Mikrotik«.

Et un commentaire dans l'un des groupes VK de Kirill Kazakov :

Oui, ce n'est pas sécurisé du tout. Je préférerais écrire un bot télégramme qui n'accepte que les commandes d'activation de mon compte.

J'ai décidé d'écrire un tel bot.

Donc, la première chose à faire est de créer un bot dans Telegram.

  • On trouve dans la recherche un compte nommé @botfather
  • Cliquez sur le bouton Démarrer en bas de l'écran
  • Puis on lui écrit la commande / newbot

Ensuite, nous répondons à 2 questions simples :

  • La première question est le nom du bot à créer. MonMikrotikROUter
  • La deuxième question est le surnom du bot en cours de création (doit se terminer par bot) MikrotikROuter_bot

En réponse, nous recevrons le jeton de notre bot, dans mon cas c'est :

Utilisez ce jeton pour accéder à l'API HTTP : 265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4

Activation à distance des scripts Mikrotik depuis Telegram
Ensuite, vous devez trouver notre bot dans la recherche par nom @MikrotikROuter_bot et appuyez sur le bouton Démarrer.

Après cela, vous devez ouvrir le navigateur et saisir la ligne suivante :

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

Où XXXXXXXXXXXXXXXXXX est le jeton de votre bot.

Une page semblable à la suivante s'ouvrira :

Activation à distance des scripts Mikrotik depuis Telegram

On y trouve le texte suivant :

"chat":{"id":631290,

Ainsi, nous avons toutes les informations nécessaires à l'écriture de scripts pour Mikrotik, à savoir :

Jeton de robot : 265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4

Chat ID où il doit écrire : 631290

Pour vérifier, on peut passer par le navigateur :

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

Devrait obtenir le résultat :

Activation à distance des scripts Mikrotik depuis Telegram

Pour notre commodité, nous ajouterons immédiatement des commandes pour le bot :

Trouver un compte avec un nom @botpère
Puis nous lui écrivons une commande / setcommands

  • Il demandera quel bot

Nous écrivons:
@MikrotikROuter_bot

Ajoutez des commandes :

  • helloworld< — Message de test sur le chat 1
  • itsworking-Test Message sur le chat 2
  • wolmypc-réveille mon PC

Maintenant, si vous tapez "/" dans le chat, vous devriez obtenir :

Activation à distance des scripts Mikrotik depuis Telegram

Passons maintenant à MikroTik.

RouterOS dispose d'un utilitaire de console pour copier des fichiers via ftp ou http / https, l'utilitaire s'appelle fetch, c'est ce que nous allons utiliser.

Ouvrir terminal et entrez :

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

Veuillez noter que MikroTik a besoin de "» pour échapper au signe «?' dans l'URL.

Devrait obtenir le résultat :

Activation à distance des scripts Mikrotik depuis Telegram

Passons maintenant aux scripts :

Bonjour le monde

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}

ça marche

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}

louppc

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"

N'oubliez pas de spécifier le bon mac et le nom de l'interface, ainsi que le bot-token et le chat_id.

Maintenant, je vais vous expliquer un peu ce qu'ils font :

Le script "helloworld" envoie un message : "Hello, world!" à notre chat avec le bot.
Le script "itsworking" envoie un message : "Test OK, it's Working!" à notre chat avec le bot.
Ces scripts sont à des fins de démonstration.
J'ai ajouté le script "wolmypc" comme l'une des implémentations possibles.
Lors de l'exécution du script, le bot écrira "wol OK" dans le chat.
En fait, vous pouvez exécuter absolument n'importe quel script.

Créez une tâche :

Télégramme.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

Vue lisibleon ne sait pas pourquoi, mais à partir du script de travail, il ne divulgue pas de données globales, a ajouté le script au démarrage du système.
Démarrage du télégramme

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

Comment ça marche

Téléchargez nos messages "getUpdates" toutes les 30 secondes, puis analysez-les pour le savoir update_id (numéro de message) et texte (nos équipes) et chat_id . Par défaut, getUpdates affiche de 1 à 100 messages, pour plus de commodité, après lecture de la commande, on supprime le message. Telegram api dit que pour lire un message, vous avez besoin du numéro de message + 1

/getUpdates?offset=update_id + 1

Tous testés sur Mikrotik rb915 RouterOS 6.37.1
Si vous envoyez plusieurs commandes à la fois, elles seront toutes exécutées à tour de rôle avec un intervalle de 30 secondes.

PS Un grand merci à Kirill Kazakov pour l'idée et à mon ami Alexander pour son aide avec les scripts.

références

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

upd:

03:11:16

Scénarios améliorés :

Vérification ajoutée pour chat_id
À la recherche d'un imbécile, si quelqu'un écrit à notre bot, il lui répondra : "Je ne peux pas te parler. », nous répondra de même s'il ne reconnaît pas la commande.
Après avoir exécuté la commande, le bot se désabonne du chat (voir script wolmypc)

UPD

Trouvé avec 7Cascadeur7 qu'un fichier avec plus de ~14 messages n'est plus traité par la commande find (limitations de Mikrotik). Par conséquent, à l'avenir, je changerai le script en lua, merci 7Cascadeur7 pour cela, je ne connaissais pas lua.

UPD 08.12.2016

dans Telegram, apparemment, ils ont légèrement modifié "l'échappement" de getUpdate. maintenant dans le script principal, vous devez corriger le décalage du message de 2 à 1

changements

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

заменить на :

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

Source: habr.com