Activación remota de scripts Mikrotik desde Telegram

Esta implementación fue impulsada por Alexander Koryukin GeXoGeN en su publicación «Activación remota de la computadora gratis, sin SMS y sin nubes, usando Mikrotik«.

Y un comentario en uno de los grupos de VK de Kirill Kazakov:

Ciertamente no es seguro. Preferiría escribir un bot de Telegram que acepte comandos solo desde mi cuenta para encender.

Decidí crear un bot de este tipo.

Así que lo primero que necesitamos hacer es crear un bot en Telegram.

  • Buscamos en la búsqueda la cuenta con el nombre @botfather
  • Hacemos clic en el botón Start en la parte inferior de la pantalla
  • Luego escribimos el comando /newbot

Después respondemos a 2 preguntas sencillas:

  • La primera pregunta es el nombre del bot que estamos creando MyMikrotikROuter
  • La segunda pregunta es el apodo del bot que debe terminar en bot MikrotikROuter_bot

A cambio, recibiremos el token de nuestro bot, en mi caso es:

Usa este token para acceder a la API HTTP: 265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4

Activación remota de scripts Mikrotik desde Telegram
Luego, necesitamos encontrar nuestro bot en la búsqueda por nombre @MikrotikROuter_bot y hacer clic en el botón Start.

Después de eso, necesitamos abrir el navegador y escribir la siguiente línea:

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

Donde XXXXXXXXXXXXXXXXXX es el token de tu bot.

Se abrirá una página que se verá más o menos así:

Activación remota de scripts Mikrotik desde Telegram

Buscamos el siguiente texto:

«chat»:{«id»:631290,

Así que tenemos toda la información necesaria para escribir scripts para Mikrotik, a saber:

Token del bot: 265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4

ID del chat al que debe escribir: 631290

Para verificar, podemos acceder a través del navegador:

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

Deberíamos obtener el resultado:

Activación remota de scripts Mikrotik desde Telegram

Para nuestra comodidad, agreguemos de inmediato los comandos para el bot:

Buscamos la cuenta con el nombre @botfather
Luego escribimos el comando /setcommands

  • Te preguntará a qué bot

Escribimos:
@MikrotikROuter_bot

Agregamos comandos:

  • helloworld< — Mensaje de prueba en el chat 1
  • itsworking — Mensaje de prueba en el chat 2
  • wolmypc — Despertar mi PC

Ahora, si escribimos en el chat «/», deberíamos obtener:

Activación remota de scripts Mikrotik desde Telegram

Ahora pasamos a MikroTik.

En RouterOS hay una utilidad de consola para copiar archivos a través de ftp o http/https, la utilidad se llama fetch, y la utilizaremos.

Abrimos terminal y escribimos:

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

Ten en cuenta que en MikroTik se necesita «» para escapar el carácter «?» en la URL.

Deberíamos obtener el resultado:

Activación remota de scripts Mikrotik desde Telegram

Ahora pasamos a los 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

script del sistema 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"

No olvidemos indicar la dirección MAC correcta y el nombre de la interfaz, así como el bot-token y el chat_id.

Ahora voy a explicar un poco lo que hacen:

El script «helloworld» envía el mensaje: » Hello,world!» a nuestro chat con el bot.
El script «itsworking» envía el mensaje: » Test OK, it’s Working !» a nuestro chat con el bot.
Estos scripts son para demostrar su funcionamiento.
El script «wolmypc» lo añadí como una de las posibles implementaciones.
Al ejecutar el script, el bot escribirá en el chat «wol OK».
En realidad, se puede ejecutar cualquier script.

Creamos la tarea:

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

Vista legibleNo sé por qué, pero el script en funcionamiento no revela los datos globales, añadí el script al cargar el sistema.
Telegram-startup

:delay 5
:global botID "botXXXXXXXXXXXXXXXXXX" ;   token del 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=No puedo hablar contigo.") keep-result=no};
:tool fetch url=("https://api.telegram.org/".$botID."/getUpdates?offset=$messageId") keep-result=no;
} 

¿Cómo funciona?

Descargamos nuestros mensajes «getUpdates» cada 30 segundos, luego analizamos para saber update_id (número del mensaje) y text (nuestros comandos) y chat_id . Por defecto, getUpdates devuelve de 1 a 100 mensajes, para mayor comodidad, después de leer el comando, eliminamos el mensaje. En la API de Telegram se dice que para leer un mensaje se necesita el número del mensaje + 1

/getUpdates?offset=update_id + 1

Todo comprobado en Mikrotik rb915 RouterOS 6.37.1
Si envías muchas órdenes de golpe, se ejecutarán una tras otra con un intervalo de 30 segundos.

P.D. Un enorme agradecimiento a Kirill Kazakov por la idea y a mi amigo Alexander por la ayuda con los scripts.

Enlaces

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

He mejorado los scripts:

Agregué la verificación de chat_id
Comprobación para evitar errores, si alguien escribe a nuestro bot, él responderá: » No puedo hablar contigo. «, igualmente responderá si no reconoce el comando.
Al ejecutar un comando, el bot informará en el chat (ver Script wolmypc)

UPD

Encontramos que 7Stuntman7 cuando el archivo supera ~ 14 mensajes, deja de procesar el comando find (limitaciones de Mikrotik). Por lo tanto, en el futuro modificaré el script a lua, gracias 7Stuntman7 por esto, no conocía lua.

UPD 08.12.2016

en Telegram aparentemente han cambiado un poco la salida de getUpdate. ahora en el script principal es necesario corregir el desplazamiento de mensaje de 2 a 1

cambios

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

sustituir por:

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

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster