Activación remota de scripts de Mikrotik desde Telegram

Alexander Koryukin me empujó a esta implementación GeXoGen con su publicaciónEncendido remoto de la computadora gratis, sin SMS y sin nubes, usando Mikrotik«.

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

Sí, no es seguro en absoluto. Prefiero escribir un bot de Telegram que solo acepte comandos de activación de mi cuenta.

Decidí escribir tal bot.

Entonces, lo primero que debe hacer es crear un bot en Telegram.

  • Encontramos en la búsqueda una cuenta llamada @botfather
  • Haga clic en el botón Inicio en la parte inferior de la pantalla
  • Luego le escribimos el comando /newbot

Luego respondemos 2 simples preguntas:

  • La primera pregunta es el nombre del bot a crear. MiMikrotikROuter
  • La segunda pregunta es el apodo del bot que se está creando (debe terminar con bot) MikrotikROuter_bot

Como respuesta recibiremos el token de nuestro bot, en mi caso es:

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

Activación remota de scripts de Mikrotik desde Telegram
Luego, necesitas encontrar nuestro bot en la búsqueda por nombre @MikrotikROuter_bot y presione el botón Inicio.

Después de eso, debe abrir el navegador e ingresar la siguiente línea:

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

Donde XXXXXXXXXXXXXXXXXX es el token de tu bot.

Se abrirá una página similar a la siguiente:

Activación remota de scripts de Mikrotik desde Telegram

En él encontramos el siguiente texto:

"chat":{"id":631290,

Entonces, tenemos toda la información necesaria para escribir guiones para Mikrotik, a saber:

Ficha de bot: 265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4

ID de chat donde debe escribir: 631290

Para comprobarlo, podemos pasar por el navegador:

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

Debería obtener el resultado:

Activación remota de scripts de Mikrotik desde Telegram

Para nuestra comodidad, agregaremos inmediatamente comandos para el bot:

Encontrar una cuenta con un nombre @botpadre
Luego le escribimos un comando / setcommands

  • Él preguntará qué bot

Nosotros escribimos:
@MikrotikROuter_bot

Agregar comandos:

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

Ahora, si escribes "/" en el chat, deberías obtener:

Activación remota de scripts de Mikrotik desde Telegram

Ahora pasemos a MikroTik.

RouterOS tiene una utilidad de consola para copiar archivos vía ftp o http/https, la utilidad se llama fetch, que es la que usaremos.

Abrir terminal e ingrese:

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

Tenga en cuenta que MikroTik necesita "» para escapar de la señal «?' en la URL.

Debería obtener el resultado:

Activación remota de scripts de Mikrotik desde Telegram

Ahora pasemos a los scripts:

Hola Mundo

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}

esta funcionando

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"

No olvide especificar el mac correcto y el nombre de la interfaz, así como bot-token y chat_id.

Ahora te explico un poco lo que hacen:

El script "helloworld" envía un mensaje: "¡Hola, mundo!" a nuestro chat con el bot.
El script "itsworking" envía un mensaje: "¡Prueba OK, está funcionando!" a nuestro chat con el bot.
Estos scripts son para fines de demostración.
Agregué el script "wolmypc" como una de las posibles implementaciones.
Tras la ejecución del script, el bot escribirá "wol OK" en el chat.
De hecho, puede ejecutar absolutamente cualquier script.

Crear una tarea:

Telegrama.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 está claro por qué, pero desde el script de trabajo no revela datos globales, agregó el script cuando se inicia el sistema.
inicio de telegramas

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

¿Cómo funciona esto

Descargue nuestros mensajes "getUpdates" cada 30 segundos, luego analice para averiguarlo actualizar_id (número de mensaje) y texto (nuestros equipos) y id_chat . Por defecto, getUpdates muestra de 1 a 100 mensajes, para mayor comodidad, después de leer el comando, borramos el mensaje. Telegram api dice que para leer un mensaje necesitas el número de mensaje + 1

/getUpdates?offset=update_id + 1

Todo probado en Mikrotik rb915 RouterOS 6.37.1
Si envía muchos comandos a la vez, todos se ejecutarán a la vez con un intervalo de 30 segundos.

PD: Muchas gracias a Kirill Kazakov por la idea ya mi amigo Alexander por ayudarme con los guiones.

referencias

habrahabr.ru/post/313794
1spla.ru/index.php/blog/telegram_bot_for_mikrotik
core.telegram.org/bots/api
wiki.mikrotik.com/wiki/Manual:Secuencias de comandos

actualizacion:

03:11:16

Guiones mejorados:

Verificación agregada para chat_id
Buscando un tonto, si alguien le escribe a nuestro bot, le responderá: "No puedo hablar contigo. “, igualmente nos responderá si no reconoce el comando.
Después de ejecutar el comando, el bot cancela la suscripción al chat (ver script wolmypc)

UPD

Encontrado con 7doble7 que un archivo con más de ~14 mensajes ya no es procesado por el comando de búsqueda (limitaciones de Mikrotik). Por lo tanto, en el futuro cambiaré el script a lua, gracias. 7doble7 para esto, no sabia de lua.

UPD 08.12.2016

en Telegram, aparentemente, cambiaron ligeramente el "escape" de getUpdate. ahora, en el script principal, debe corregir el desplazamiento del mensaje de 2 a 1

cambios

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

заменить на :

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

Fuente: habr.com