Skip to content

Instantly share code, notes, and snippets.

@l0ser140
Last active January 16, 2024 22:03
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save l0ser140/cde4916b038bb14a5388bca00ce496be to your computer and use it in GitHub Desktop.
Save l0ser140/cde4916b038bb14a5388bca00ce496be to your computer and use it in GitHub Desktop.
Mikrotik Telegram bot
#Schedule run every ~30sec.
:global botID;
:global myChatID;
:local parse do={
:local startLoc ([:find $content $variable -1] + [:len $variable] + 2);
:local commaLoc ([:find $content "," $startLoc] - 1 + 1);
:local braceLoc ([:find $content "}" $startLoc] - 1 + 1);
:local endLoc $commaLoc;
:local startSymbol [:pick $content $startLoc]
:if ($braceLoc != 0 and ($commaLoc = 0 or $braceLoc < $commaLoc)) do={
:set endLoc $braceLoc;
};
:if ($startSymbol = "{") do={
:set endLoc ($braceLoc + 1);
};
:if ($quotas = true) do={
:set startLoc ($startLoc + 2);
:set endLoc ($endLoc - 1);
}
:if ($endLoc < $startLoc) do={
:set endLoc ($startLoc + 1);
};
:local value [:pick $content $startLoc $endLoc]
:log debug message="Telegram: parsed $variable : $value";
:return $value;
}
:local content [/tool fetch url=("https://api.telegram.org/".$botID."/getUpdates?limit=1&allowed_updates=message") as-value output=user];
:set content ($content ->"data");
:if ([:len $content] > 23 ) do={
:local updateId [$parse content=$content variable="update_id"]
:local chat [$parse content=$content variable="chat"]
:local chatId [$parse content=$chat variable="id"]
:if ($chatId = $myChatID) do={
:local message [$parse content=$content variable="text" quotas=true] ;
:log warn message="Command $message received" ;
:if ([/system script find name=$message] != "") do={
:system script run $message ;
} else={
:tool fetch url=("https://api.telegram.org/".$botID."/sendmessage\?chat_id=".$chatId."&text=Wrong command.") keep-result=no ;
};
} else={
:tool fetch url=("https://api.telegram.org/".$botID."/sendmessage\?chat_id=".$chatId."&text=I can't talk with you.") keep-result=no ;
};
:set updateId ($updateId +1) ;
:tool fetch url=("https://api.telegram.org/".$botID."/getUpdates\?offset=$updateId") keep-result=no ;
};
#Schedule run at startup.
#Telegram API keys for use in another scripts.
:global botID "botXXXXXX:XXXXXXX" ;
:global myChatID "XXXXXXXX" ;
#Example script.
:local scriptName "wolmypc";
:global botID;
:global myChatID;
#Start usefull script part
/tool wol mac=XX:XX:XX:XX:XX:XX interface=ifname ;
#End usefull script part
:log debug message="$scriptName Executed" ;
/tool fetch url=("https://api.telegram.org/".$botID."/sendmessage\?chat_id=".$myChatID."&text=".$scriptName." Executed") keep-result=no ;
@2030515
Copy link

2030515 commented Jun 28, 2022

Добрый день. Полезный скрипт, спасибо.
Пытаюсь его немного переделать, чтобы бот мог общаться с несколькими контактами.
В переменную myChatID загоняю несколько айдишников чатов через запятую

111111,222222

и меняю проверку на возможность управления ботом вот так

:if ([:find "$myChatID" "$chatId"] !="") do={

У меня бот начинает принимать команды вообще от всех подряд.
Хотя при отладке в терминале микротика такое условие работает
Если chatId есть в переменной myChatID, то find выводит номер позиции этого элемента в массиве.
Если chatId отсутствует в myChatID, то терминал отдает пустую строку.

Если есть возможность прошу помочь в вопросе.

@l0ser140
Copy link
Author

Попробуй такое условие

:if ( :typeof [:find "$myChatID" "$chatId"] >= 0 ) do={
    :put "$chatId is acceptable"
}

@2030515
Copy link

2030515 commented Jun 28, 2022

Работает! Спасибо!

@aVitomin
Copy link

Перебрал хуеву тучу говна в инете пока на это не наткнулся, завелось за 5 минут
Большое спасибо!

@dspanc
Copy link

dspanc commented Jun 15, 2023

Спасибо большое за скрипт
Есть маленький вопрос, как уже писали выше, иногда необходимо, что бы скрипт общался с несколькими контактами телеграм
Но как сделать отправку текста, после выполнения wolmypc.rsc , именно в тот чат, откуда пришла команда
В wolmypc.rsc используется $myChatID, и текст приходит первому в списке.

@l0ser140
Copy link
Author

@dspanc либо передавать ID нужного чата внутрь выполняемого скрипта через глобальные переменные, либо перенести отправление ответного сообщения в основной скрипт проверки телеграма.

@Papso
Copy link

Papso commented Oct 19, 2023

Пишет постоянно I can't talk with you, не понимаю, что сделал не так.

@aVitomin
Copy link

Пишет постоянно I can't talk with you, не понимаю, что сделал не так.

:global myChatID "XXXXXXXX" ;
неверный ChatID

@dspanc
Copy link

dspanc commented Jan 16, 2024

В новой версии RouterOS 7.13, добавили:
*) log - added "fetch" topic;

Теперь при каждом срабатывании скрипта, идет запись в лог, у меня скрипт срабатывает раз в 2 минуты - получается не кислый такой спам в логах:
Download from https://api.telegram.org/bot####:###/getUpdates?limit=1&allowed_updates=message to RAM FINISHED

Вот обсуждение:
https://forummikrotik.ru/viewtopic.php?t=12659&start=120

Думаю исправить это можно так:

/system logging
set 0 topics=info,!debug

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment