Найти тему
Smart home Russia

Mikrotik и Telegram. Уведомление о заданном событии.

В прошлом году я задумался над тем, чтобы контролировать все входы пользователей на роутер. Идея была хороша, реализация прекрасна, но обнаружились нюансы☺.

Translation to English is here. Также основной канал в telegram.

Данная публикация является частью серии:

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

Давайте просмотрим внимательно на первую часть кода:

:local DeviceName [/system identity get name];
:local Time [/system clock get time];
:local Date [/system clock get date];
:local TelegramMessageText;
:global ParseLogAccountEndArrayID;
:local IDsEventsAccount [/log find where topics ~ "account"];

В этой части мы объявляем переменные и указываем их содержимое.

Первые три строчки - чисто информация служебная.
Следующая строчка - просто объявили переменную.
Строка №5 очень интересная. Все переменные, кроме этой - обрабатываются внутри скрипта и живут там же, а вот переменная ParseLogAccountEndArrayID живет в глобальной памяти роутера и не обнуляется после выполнения скрипта. Это память событий. Это требовалось для того, чтобы не присылать одни и те же события дважды.
Следующая строка - первая важная строка. В нее мы помещаем ID события, которая соответствует нашим критериям. Критерием для нас был топик "account". В этот топик помещаются события по входу в роутер.

По сути, мы находили все сообщения в этом топике и слали их в telegram. Дальнейший код отвечает за нахождение всех сообщений после последнего отосланного и если они есть, то через http метод сообщение отправлялось боту.

Теперь, когда мы примерно понимаем, что происходит, мы можем написать свой код, основанный на прошлом. Но, нужно помнить, что глобальная переменная, она живет во всех скриптах сразу и выполняется также в каждом, поэтому если мы будем использовать переменную :global ParseLogAccountEndArrayID; повторно, то сломаем все остальные скрипты, где используется эта же переменная. Поэтому в нашем новом скрипте, назовем переменную, например, ParseLogAccountEndArrayID;
Да, с фантазией у меня не очень ☺. Все эти переменные можно всегда посмотреть в специальной вкладке "environment" в том же разделе system → Scripts. Там же можно посмотреть содержимое, значение этих переменных.

Дальше в коде есть поиск ключа, триггера. Это строчка

:local IDsEventsAccount [/log find where topics ~ "account"];

Если нам нужно находить все сообщения в топике, то все супер, нас это устраивает, а если нет? Например, я хочу найти все сообщения пользователя "user123". Это условный пользователь и у меня такого конечно же нет, но, а вдруг... Команда выше нам для этого уже не подойдет. Поизучав мануал, была найдена команда

[/log find where message ~ "user123"];

Эта волшебная команда поищет в логе упоминание про user123 и запишет ID сообщения, а потом просто выведет ее полностью. Тут стоит отметить. что мы можем искать и другие ключи, например "authentication failed" или "192.168.2.78" или "MAC адрес уструйства". Чтобы мы не выбрали, скрипт проверит это и выполнит отсылку данного сообщения. Что же, осталось подправить скрипт и добавить его в планировщик. Итоговый код ниже:

:local DeviceName [/system identity get name];
:local Time [/system clock get time];
:local Date [/system clock get date];
:local TelegramMessageText;
:global ParseLogAccountEndArrayID2;
:local IDsEventsAccount [/log find where message ~ "
user123"];
:local LenArrayIDs [:len $IDsEventsAccount];
:local StartArrayID [:find $IDsEventsAccount $ParseLogAccountEndArrayID2];
:local EndArrayID ($IDsEventsAccount -> ($LenArrayIDs-1));
:if ($EndArrayID != $ParseLogAccountEndArrayID2 and [:tobool $ParseLogAccountEndArrayID2] ) do={
:local StartArray [:find $IDsEventsAccount $ParseLogAccountLastRunID2];
:for KeyArray from=($StartArrayID+1) to=($LenArrayIDs-1) do={
:local IDMessage ($IDsEventsAccount ->$KeyArray );
:set TelegramMessageText "$TelegramMessageText %0D%0A $[/log get number=$IDMessage time] - $[/log get number=$IDMessage message];";
}
:local BotToken "Тут токен бота";
:local ChatID "ID чата";
:local ParseMode "html";
:local DisableWebPagePreview True;
:local SendText "\F0\9F\94\93 <b>$DeviceName: AUTH</b> $TelegramMessageText";
:local tgUrl "https://api.telegram.org/bot$BotToken/sendMessage?chat_id=$ChatID&text=$SendText&parse_mode=$ParseMode&disable_web_page_preview=$DisableWebPagePreview";
/tool fetch http-method=get url=$tgUrl keep-result=no;
}
:set ParseLogAccountEndArrayID2 $EndArrayID;

Результатом данного скрипта станут все действия пользователя, а не только вход/выход.

-2

Теперь вы можете создать скрипты с уведомлениями на любые топики и на любые ключевые слова. Удачи и безопасности Вам!

Подпишитесь, чтобы не пропускать контент. Нажмите лайк, если интересно, так я пойму какие публикации больше нужны моей публике. Также публикации можно найти на других площадках: Instagram, telegram (RU, EN, DE), Medium, LiveJournal, YouTube.