Ativação remota de scripts Mikrotik via Telegram

Esta implementação foi inspirada por Alexander Koryukin GeXoGeN com sua publicação «Ativação remota do computador gratuitamente, sem SMS e sem nuvens, usando Mikrotik«.

E um comentário em um dos grupos do VK de Kirill Kazakov:

Pois é, realmente não é seguro. Eu preferiria escrever um bot do Telegram que aceitasse comandos de ativação apenas da minha conta.

Decidi escrever tal bot.

Então, a primeira coisa a fazer é criar um bot no Telegram.

  • Buscamos o perfil com o nome @botfather
  • Clicamos no botão Iniciar na parte inferior da tela
  • Depois, escrevemos o comando /newbot

Em seguida, respondemos a 2 perguntas simples:

  • A primeira pergunta é o nome do bot a ser criado MyMikrotikROuter
  • A segunda pergunta é o apelido do bot a ser criado (deve terminar com bot) MikrotikROuter_bot

Em resposta, receberemos o token do nosso bot, no meu caso é:

Use este token para acessar a API HTTP: 265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4

Ativação remota de scripts Mikrotik via Telegram
Então, precisamos encontrar nosso bot buscando pelo nome @MikrotikROuter_bot e clicar no botão Iniciar.

Depois disso, devemos abrir o navegador e digitar a seguinte linha:

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

Onde XXXXXXXXXXXXXXXXXX é o token do seu bot.

Uma página semelhante aparecerá:

Ativação remota de scripts Mikrotik via Telegram

Buscamos o seguinte texto nela:

«chat»:{«id»:631290,

Assim, temos todas as informações necessárias para escrever scripts para o Mikrotik, a saber:

Token do bot: 265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4

ID do chat para onde ele deve enviar mensagens: 631290

Para verificar, podemos acessar pelo navegador:

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

Deve-se obter o resultado:

Ativação remota de scripts Mikrotik via Telegram

Para nossa conveniência, vamos adicionar comandos para o bot:

Buscamos o perfil com o nome @botfather
Depois, escrevemos o comando /setcommands

  • Ele perguntará para qual bot

Escrevemos:
@MikrotikROuter_bot

Adicionamos os comandos:

  • helloworld< — Mensagem de teste no chat 1
  • itsworking — Mensagem de teste no chat 2
  • wolmypc — ativar meu PC

Agora, se digitarmos «/» no chat, devemos obter:

Ativação remota de scripts Mikrotik via Telegram

Agora vamos para o MikroTik.

No RouterOS, existe uma utilidade de console para copiar arquivos via ftp ou http/https, chamada fetch, que é a que vamos usar.

Abrimos terminal e digitamos:

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

Observe que no MikroTik é necessário usar «» para escapar o caractere «?» na URL.

Deve-se obter o resultado:

Ativação remota de scripts Mikrotik via Telegram

Agora vamos para os 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 do sistema adicionar nome="wolmypc" política=leitura fonte="/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" manter-resul
    t=no"

Não se esqueça de indicar o MAC e o nome da interface corretos, assim como o bot-token e o chat_id.

Agora vou explicar um pouco sobre o que eles fazem:

O script "helloworld" envia a mensagem: "Olá, mundo!" para nosso chat com o bot.
O script "itsworking" envia a mensagem: "Teste OK, está Funcionando!" para nosso chat com o bot.
Esses scripts são para demonstrar o funcionamento.
O script "wolmypc" eu adicionei como uma das possíveis implementações.
Após a execução do script, o bot escreverá no chat "wol OK".
Na verdade, é possível executar qualquer script.

Criamos uma tarefa:

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

Visualização legívelnão está claro por que, mas o script em funcionamento não revela dados globais, adicionei o script ao iniciar o sistema.
Telegram-startup

:delay 5
:global botID "botXXXXXXXXXXXXXXXXXX" ;   token do 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=Não posso falar com você. ") manter-resul=no} ;
:tool fetch url=("https://api.telegram.org/".$botID."/getUpdates?offset=$messageId") manter-resul=no; 
} 

Como funciona

Estamos baixando nossas mensagens "getUpdates" a cada 30 segundos, depois fazemos parse para saber update_id (número da mensagem) e ntext (nossas comandos) e chat_id . Por padrão, getUpdates retorna de 1 a 100 mensagens; para conveniência, após a leitura dos comandos, removemos a mensagem. No API do Telegram está dito que para ler uma mensagem é necessário o número da mensagem + 1.

/getUpdates?offset=update_id + 1

Tudo testado no Mikrotik rb915 RouterOS 6.37.1.
Se muitos comandos forem enviados de uma só vez, todos serão executados um após o outro com um intervalo de 30 segundos.

P.S. Um grande obrigado ao Kirill Kazakov pela ideia e ao meu amigo Alexander pela ajuda com os scripts.

Links

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

Aperfeiçoei os scripts:

Adicionei verificação em chat_id
Verificação para impedir que, se alguém escrever para nosso bot, ele responda: » Não posso falar com você. «, da mesma forma responderá se não reconhecer o comando.
Após a execução do comando, o bot envia uma mensagem no chat (veja o script wolmypc)

ATUALIZAÇÃO

Encontramos com 7Stuntman7 que o arquivo com mais de ~ 14 mensagens para de ser processado pelo comando find (limitações do Mikrotik). Por isso, no futuro, vou reescrever o script em lua. Obrigado 7Stuntman7 por isso, não sabia sobre lua.

UPD 08.12.2016

no Telegram aparentemente mudaram um pouco a saída do getUpdate. agora no script principal é necessário corrigir o deslocamento da mensagem de 2 para 1

mudanças

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

substituir por:

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

Fonte: habr.com

Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster