Skip to content

Instantly share code, notes, and snippets.

@l0ser140
Last active July 19, 2024 19:46
Show Gist options
  • 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

@burabaika
Copy link

burabaika commented Jul 19, 2024

Не работает.

Создал два шедулера, вставил туда Ваш код.

Заменил значения бота и чата на свои.
Обновление бота не работает.
Снимок

Если вставить скрипт обновления в терминал, показывает такую ошибку, подчеркивает букву C красным
:set content ($content ->"data");
syntax error (line 1 column 6)

RB750Gr3
Прошивка 7.15.2

@l0ser140
Copy link
Author

l0ser140 commented Jul 19, 2024

Код работает на RoS 6.
На 7 не тестировался и скорее всего требует правок.

@burabaika
Copy link

блин....и как быть?

@dspanc
Copy link

dspanc commented Jul 19, 2024

блин....и как быть?

все прекрасно работает на последних прошивках

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