从 Telegram 远程激活 Mikrotik 脚本

Alexander Koryukin 推动我实现了这个 GeXoGeN 与他的出版物使用 Mikrotik 免费远程打开计算机,无需短信且无需云«。

基里尔·卡扎科夫 (Kirill Kazakov) 在 VK 群组之一中发表评论:

是的,这根本不安全。 我宁愿编写一个仅接受来自我的帐户的激活命令的电报机器人。

我决定写一个这样的机器人。

因此,首先要做的就是在 telegram 中创建一个机器人。

  • 我们在搜索中发现一个名为@botfather的帐户
  • 单击屏幕底部的“开始”按钮
  • 然后我们给他写命令 / newbot

然后我们回答2个简单的问题:

  • 第一个问题是要创建的机器人的名称。 MyMikrotikRouter
  • 第二个问题是正在创建的机器人的昵称(应以机器人结尾) MikrotikROuter_bot

作为响应,我们将收到机器人的令牌,在我的例子中是:

使用此令牌访问 HTTP API: 265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4

从 Telegram 远程激活 Mikrotik 脚本
然后,您需要在搜索中按名称找到我们的机器人 @MikrotikROuter_bot 并按开始按钮。

之后,您需要打开浏览器并输入以下行:

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

其中 XXXXXXXXXXXXXXXXXX 是您的机器人的令牌。

将打开类似于以下内容的页面:

从 Telegram 远程激活 Mikrotik 脚本

我们在上面找到以下文字:

“聊天”:{“id”:631290,

因此,我们拥有为 Mikrotik 编写脚本的所有必要信息,即:

机器人令牌: 265373548:AAFyGCqJCei9mvcxvXOWBfnjSt1p3sX1XH4

聊天 ID 应在其中写入: 631290

为了检查,我们可以通过浏览器来检查:

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

应该得到结果:

从 Telegram 远程激活 Mikrotik 脚本

为了方便起见,我们将立即为机器人添加命令:

查找有名字的帐户 @botfather
然后我们给他写一个命令 / setcommands

  • 他会问哪个机器人

我们写:
@MikrotikROuter_bot

添加命令:

  • helloworld< — 聊天 1 上的测试消息
  • itworking-测试聊天消息 2
  • wolmypc-唤醒我的电脑

现在,如果您在聊天中输入“/”,您应该得到:

从 Telegram 远程激活 Mikrotik 脚本

现在让我们转向 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 需要“» 逃避标志 «?' 在网址中。

应该得到结果:

从 Telegram 远程激活 Mikrotik 脚本

现在让我们继续讨论脚本:

你好,世界

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}

沃尔米电脑

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”脚本发送一条消息:“Hello, world!” 到我们与机器人的聊天。
“itsworking”脚本发送一条消息:“测试正常,工作正常!” 到我们与机器人的聊天。
这些脚本用于演示目的。
我添加了“wolmypc”脚本作为可能的实现之一。
执行脚本后,机器人将在聊天中写入“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

可读视图目前尚不清楚为什么,但从工作脚本来看,它没有公开全局数据,而是在系统启动时添加了脚本。
电报启动

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

怎么开动这个

每 30 秒下载一次“getUpdates”消息,然后进行解析以找出答案 更新ID (消息编号)和 文本 (我们的团队)和 聊天ID 。 默认情况下,getUpdates 显示 1 到 100 条消息,为了方便,读完命令后,我们删除该消息。 Telegram api 表示要阅读消息,您需要消息号 + 1

/getUpdates?offset=update_id + 1

全部在 Mikrotik rb915 RouterOS 6.37.1 上测试
如果一次发送多条命令,则会依次执行,间隔30秒。

PS 非常感谢基里尔·卡扎科夫(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/手册:脚本

UPD:

03:11:16

改进的脚本:

添加了对 chat_id 的检查
检查傻瓜,如果有人写信给我们的机器人,他会回答他:“我不能和你说话。 “,如果它不识别该命令,也会类似地回答我们。
执行命令后,机器人取消订阅聊天(请参阅 wolmypc 脚本)

UPD

发现与 7特技演员7 find 命令不再处理包含超过 14 条消息的文件(Mikrotik 限制)。 所以,以后我会把脚本改成lua,谢谢 7特技演员7 为此,我不了解lua。

UPD 08.12.2016

显然,在 Telegram 中,他们稍微改变了 getUpdate 的“排气”。 现在在主脚本中您需要将消息偏移量从 2 更正为 1

变化

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

заменить на :

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

来源: habr.com