Удаленный запуск скриптов через Телеграм

Здесь выкладываем скрипты
Правила форума
Уважаемые Пользователи форума, обратите внимание!
Ни при каких обстоятельствах, Администрация форума, не несёт ответственности за какой-либо, прямой или косвенный, ущерб причиненный в результате использования материалов, взятых на этом Сайте или на любом другом сайте, на который имеется гиперссылка с данного Сайта. Возникновение неисправностей, потерю программ или данных в Ваших устройствах, даже если Администрация будет явно поставлена в известность о возможности такого ущерба.
Просим Вас быть предельно осторожными и внимательными, в использовании материалов раздела. Учитывать не только Ваши пожелания, но и границы возможностей вашего оборудования.
Ответить
Аватара пользователя
drpioneer
Сообщения: 142
Зарегистрирован: 30 май 2013, 10:20

Добрый день.

Какое-то время назад меня посетила идея скрещивания скриптов оповещения ( viewtopic.php?p=81726#p81726 ) и удалённого запуска ( viewtopic.php?p=78085#p78085 ) в Телеграм в один могучий скрипт-комбайн, который объединил бы в себе возможности обоих скриптов.
Попытался воплотить идею в жизнь.
Вот что из этого получилось:

Код: Выделить всё



# Combined notification script and script launch via Telegram  by drPioneer
# https://forummikrotik.ru/viewtopic.php?p=81726#p81726
# tested on ROS 6.49
# updated 2021/10/25

:do {
    :local botID    "botXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
    :local myChatID "-XXXXXXXXX";

    # Function of searching comments for MAC-address by Virtue
    # https://forummikrotik.ru/viewtopic.php?p=73994#p73994
    :local FindMacAddr do={
        :if ($1 ~"[0-F][0-F]:[0-F][0-F]:[0-F][0-F]:[0-F][0-F]:[0-F][0-F]:[0-F][0-F]") do={
            :foreach idx in=[ /ip dhcp-server lease find dynamic=no disabled=no; ] do={
                :local mac  [ /ip dhcp-server lease get $idx mac-address; ];
                :if ($1 ~"$mac") do={ :return ("$1 [$[ /ip dhcp-server lease get $idx comment; ]]."); } 
            }
            :foreach idx in=[ /interface bridge host find; ] do={
                :local mac  [ /interface bridge host get $idx mac-address; ];
                :if ($1 ~"$mac") do={ :return ("$1 [$[ /interface bridge host get $idx on-interface; ]]."); }
            }
        }
        :return ($1);
    }

    # Function of converting SPACE to CODE by Sertik
    # https://forummikrotik.ru/viewtopic.php?p=81481#p81481
    :local SpaceToCode do={
        :local char   "";
        :local string "";
        :for idx from=0 to=([len $1]-1) do={
            :set $char [:pick $1 $idx]
            :if ($char=" ") do={ :set $char "%20"; }
            :if ($char="\a" || $char="\b" || $char="\f" || $char="\n" || $char="\r" || $char="\t" || $char="\v") do={ :set $char ""; }
            :set $string ($string.$char);
        }
        :return ($string);
    }

    # Telegram messenger response parsing function by Dimonw
    # https://habr.com/ru/post/482802/
    :local RespParser do={
        :local variaMod ("\"".$2);
        :local startLoc ([:find $1 $variaMod -1] + [:len $variaMod] + 2);
        :local commaLoc ([:find $1 "," $startLoc]);
        :local brakeLoc ([:find $1 "}" $startLoc]);
        :local endLoc $commaLoc;
        :local startSymbol [:pick $1 $startLoc]; 
        :if ($brakeLoc != 0 and ($commaLoc = 0 or $brakeLoc < $commaLoc)) do={ :set endLoc $brakeLoc; };
        :if ($startSymbol = "{") do={ :set endLoc ($brakeLoc + 1); };
        :if ($3 = true) do={
            :set startLoc ($startLoc + 1);
            :set endLoc   ($endLoc   - 1);
        }
        :if ($endLoc < $startLoc) do={ :set endLoc ($startLoc + 1); };
        :return ([:pick $1 $startLoc $endLoc]);
    }
    
    # Time translation function to UNIX-time by Jotne
    # https://forum.mikrotik.com/viewtopic.php?t=75555#p790745
    :local EpochTime do={
        :local ds [ /system clock get date; ];
        :local ts [ /system clock get time; ];
        :if ([:len $1] > 8) do={
            :set ds "$[:pick $1 0 6]/$[:pick $ds 7 11]";
            :set ts [:pick $1 7 15];
        }
        :local yesterday false;
        :if ([:len $1] = 8) do={
            :if ([:totime $1] > ts) do={ :set yesterday (true); }
            :set ts $1;
        }
        :local months;
        :if ((([:pick $ds 9 11]-1)/4) != (([:pick $ds 9 11])/4)) do={
            :set months {"an"=0;"eb"=31;"ar"=60;"pr"=91;"ay"=121;"un"=152;"ul"=182;"ug"=213;"ep"=244;"ct"=274;"ov"=305;"ec"=335};
        } else={
            :set months {"an"=0;"eb"=31;"ar"=59;"pr"=90;"ay"=120;"un"=151;"ul"=181;"ug"=212;"ep"=243;"ct"=273;"ov"=304;"ec"=334};
        }
        :set ds (([:pick $ds 9 11]*365)+(([:pick $ds 9 11]-1)/4)+($months->[:pick $ds 1 3])+[:pick $ds 4 6]);
        :set ts (([:pick $ts 0 2]*3600)+([:pick $ts 3 5]*60)+[:pick $ts 6 8]);
        :if (yesterday) do={ :set ds ($ds-1); }
        :return ($ds*86400 + $ts + 946684800 - [ /system clock get gmt-offset; ]);
    }

    # Main body of the script
    :global timeAct;
    :global timeLog;
    :local  nameID [ /system identity get name; ];
    :put ("$[$EpochTime] sec - current Unix-time of $nameID router.");
    if ([:len $timeAct] > 0) do={ :put ("$timeAct sec - time of checking the last script run."); }
    if ([:len $timeLog] > 0) do={ :put ("$timeLog sec - time of the last log check."); }
    
    # Part of the script body for running scripts via Telegram by drPioneer
    # https://forummikrotik.ru/viewtopic.php?p=78085
    :local  timeStamp [$EpochTime];
    :local  urlString "";
    :put ("... Stage of running scripts via Telegram:");
    :if ([:len $timeAct] > 0) do={
        :set urlString ("https://api.telegram.org/$botID/getUpdates\?offset=-1&limit=1&allowed_updates=message");
        :local httpResp [ /tool fetch url=$urlString as-value output=user; ];
        :local content ($httpResp->"data");
        :if ([:len $content] > 30) do={
            :local msgTxt   [$RespParser $content "text" true];
            :set   msgTxt  ([:pick $msgTxt ([:find $msgTxt "/"] + 1) ([:len $msgTxt])]);
            :local chat     [$RespParser $content "chat"];
            :local chatId   [$RespParser $chat    "id"];
            :local userName [$RespParser $content "username"];
            :set  timeStamp [$RespParser $content "date"];
            :if (($chatId = $myChatID) && ($timeAct < $timeStamp) && ([ /system script find name=$msgTxt; ] != "")) do={ 
                :put (">Found command '$msgTxt' from user $userName in $timeStamp sec.");
                :set timeAct ($timeStamp);
                :log warning ("Telegram user $userName activated script '$msgTxt' in $timeStamp sec.");                 
                /system script run $msgTxt;
            } else={ :put ("Nothing to run."); }
        } else={ :put ("No response from Telegram."); }
    } else={
        :put ("Time of the last script activation was not found. Forced to generate.");
        :set timeAct [$EpochTime];
    }

    # Part of the script body for notifications in Telegram by Alice Tails
    # https://www.reddit.com/r/mikrotik/comments/onusoj/sending_log_alerts_to_telegram/
    :local outMsg "";
    :local logGet [ :toarray [ /log find ($topics ~"warning" || $topics ~"error" || $topics ~"critical" || $topics ~"caps" || $topics ~"wireless" || $message ~"logged in"); ]];
    :local logCnt [ :len $logGet ];
    :put ("... Stage of sending notifications to Telegram:");

    :if ([:len $timeLog] < 1) do={ 
        :put ("Time of the last log entry was not found. Forced to generate.");
        :set outMsg (">$[ /system clock get time; ] Telegram notification started.");
    }
    :if ($logCnt > 0) do={
        :local lastTime [$EpochTime [ /log get [:pick $logGet ($logCnt-1)] time; ]];
        :local index 0;
        :local tempTime;
        :local tempMessage;
        :local tempTopic;
        :local unixTime;
        :do {
            :set index        ($index + 1); 
            :set tempTime     [ /log get [:pick $logGet ($logCnt - $index)]    time; ];
            :set tempTopic    [ /log get [:pick $logGet ($logCnt - $index)]  topics; ];
            :set tempMessage  [ /log get [:pick $logGet ($logCnt - $index)] message; ];
            :set tempMessage  (">".$tempTime." ".$tempMessage);
            :local findMacMsg ([$FindMacAddr $tempMessage]);
            :set unixTime [$EpochTime $tempTime];
            :if (($unixTime > $timeLog) && (!(($tempTopic ~"caps" || $tempTopic ~"wireless" || $tempTopic ~"dhcp") && ($tempMessage != $findMacMsg)))) do={
                :put $findMacMsg;
                :set outMsg ($findMacMsg."%0A".$outMsg);
            }
        } while=(($unixTime > $timeLog) && ($index < $logCnt));
        :if (([:len $timeLog] < 1) || (([:len $timeLog] > 0) && ($timeLog != $lastTime) && ([:len $outMsg] > 8) )) do={
            :set timeLog $lastTime;
            :local urlString ("https://api.telegram.org/$botID/sendmessage\?chat_id=$myChatID&text=$nameID:%0A$outMsg");
            :set urlString [$SpaceToCode $urlString];
            :put ("Generated string for Telegram:\r\n".$urlString);
            /tool fetch url=$urlString as-value output=user;
        } else={ :put ("Nothing to send."); }
    } else={ :put ("Necessary log entries were not found."); }
} on-error={ :put ("Script error: something went wrong when sending a request to Telegram."); }



При написании скрипта попутно избавил его от жёсткой привязки ко времени запуска, вырезал функцию, которая периодически подкидывала сюрпризы со временем и дополнил функцию преобразования пробелов возможностью отрезания спецсимволов для лучшего взаимодействия с Telegram.
Уверен, что в коде ещё таятся косяки и недоработки. :-):
Предлагаю заинтересованным погонять этот скрипт и сообщить о найденных проблемах.
Как всегда, конструктивная критика и усовершенствования только приветствуются.
Последний раз редактировалось drpioneer 25 окт 2021, 15:48, всего редактировалось 1 раз.


Sertik
Сообщения: 1598
Зарегистрирован: 15 сен 2017, 09:03

Спасибо автору за новый скрипт. Тестирую, пока ошибок не замечал.
Для себя я убрал из скрипта функцию обработки пробелов и вставил туда свою улучшенную функцию преобразования символов русского языка и некоторых спец. символов, печать которых напрямую не поддерживает Телеграмм, в UTF-8. Теперь скрипт нормально парсит не только английсие, но и русские error и warning сообщения из лога (которые формируют другие мои скрипты и функции). То есть теперь можно не беспокоиться - скрипт кинул ошибку в лог на русском или английском языках, новый парсер её обязательно пошлёт в Телеграмм. То же с информационными сообщениями синим шрифтом (warning).


фрагменты скриптов, готовые работы, статьи, полезные приемы, ссылки
viewtopic.php?f=14&t=13947
vovvw
Сообщения: 20
Зарегистрирован: 25 янв 2021, 10:18

Sertik писал(а): 25 окт 2021, 11:37 Спасибо автору за новый скрипт. Тестирую, пока ошибок не замечал.
То есть теперь можно не беспокоиться - скрипт кинул ошибку в лог на русском или английском языках, новый парсер её обязательно пошлёт в Телеграмм.
А выложить этот вариант можно?


Аватара пользователя
drpioneer
Сообщения: 142
Зарегистрирован: 30 май 2013, 10:20

vovvw писал(а): 25 окт 2021, 17:16
Sertik писал(а): 25 окт 2021, 11:37 То есть теперь можно не беспокоиться - скрипт кинул ошибку в лог на русском или английском языках, новый парсер её обязательно пошлёт в Телеграмм.
А выложить этот вариант можно?
Вариант с кириллицей может выглядеть так:

Код: Выделить всё




# Combined notification script and script launch via Telegram  by drPioneer
# https://forummikrotik.ru/viewtopic.php?p=81945#p81945
# tested on ROS 6.49
# updated 2021/11/08

:do {
    :local botID    "botXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
    :local myChatID "-XXXXXXXXX";

    # Function of searching comments for MAC-address by Virtue
    # https://forummikrotik.ru/viewtopic.php?p=73994#p73994
    :local FindMacAddr do={
        :if ($1 ~"[0-F][0-F]:[0-F][0-F]:[0-F][0-F]:[0-F][0-F]:[0-F][0-F]:[0-F][0-F]") do={
            :foreach idx in=[ /ip dhcp-server lease find dynamic=no disabled=no; ] do={
                :local mac  [ /ip dhcp-server lease get $idx mac-address; ];
                :if ($1 ~"$mac") do={ 
                    :return ("$1 [$[ /ip dhcp-server lease get $idx address; ]/\
                        $[ /ip dhcp-server lease get $idx comment; ]]."); 
                } 
            }
            :foreach idx in=[ /interface bridge host find; ] do={
                :local mac  [ /interface bridge host get $idx mac-address; ];
                :if ($1 ~"$mac") do={ :return ("$1 [$[ /interface bridge host get $idx on-interface; ]]."); }
            }
        }
        :return ($1);
    }

    # Function of converting CP1251 to UTF8 by Sertik
    # https://forummikrotik.ru/viewtopic.php?p=81457#p81457
    :local CP1251toUTF8 do={
        :local cp1251 [:toarray {"\20";"\01";"\02";"\03";"\04";"\05";"\06";"\07";"\08";"\09";"\0A";"\0B";"\0C";"\0D";"\0E";"\0F"; \
                                 "\10";"\11";"\12";"\13";"\14";"\15";"\16";"\17";"\18";"\19";"\1A";"\1B";"\1C";"\1D";"\1E";"\1F"; \
                                 "\21";"\22";"\23";"\24";"\25";"\26";"\27";"\28";"\29";"\2A";"\2B";"\2C";"\2D";"\2E";"\2F";"\3A"; \
                                 "\3B";"\3C";"\3D";"\3E";"\3F";"\40";"\5B";"\5C";"\5D";"\5E";"\5F";"\60";"\7B";"\7C";"\7D";"\7E"; \
                                 "\C0";"\C1";"\C2";"\C3";"\C4";"\C5";"\C7";"\C7";"\C8";"\C9";"\CA";"\CB";"\CC";"\CD";"\CE";"\CF"; \
                                 "\D0";"\D1";"\D2";"\D3";"\D4";"\D5";"\D6";"\D7";"\D8";"\D9";"\DA";"\DB";"\DC";"\DD";"\DE";"\DF"; \
                                 "\E0";"\E1";"\E2";"\E3";"\E4";"\E5";"\E6";"\E7";"\E8";"\E9";"\EA";"\EB";"\EC";"\ED";"\EE";"\EF"; \
                                 "\F0";"\F1";"\F2";"\F3";"\F4";"\F5";"\F6";"\F7";"\F8";"\F9";"\FA";"\FB";"\FC";"\FD";"\FE";"\FF"; \
                                 "\A8";"\B8";"\B9"}];
        :local utf8   [:toarray {"0020";"0020";"0020";"0020";"0020";"0020";"0020";"0020";"0020";"0020";"000A";"0020";"0020";"000D";"0020";"0020"; \
                                 "0020";"0020";"0020";"0020";"0020";"0020";"0020";"0020";"0020";"0020";"0020";"0020";"0020";"0020";"0020";"0020"; \
                                 "0021";"0022";"0023";"0024";"0025";"0026";"0027";"0028";"0029";"002A";"002B";"002C";"002D";"002E";"002F";"003A"; \
                                 "003B";"003C";"003D";"003E";"003F";"0040";"005B";"005C";"005D";"005E";"005F";"0060";"007B";"007C";"007D";"007E"; \
                                 "D090";"D091";"D092";"D093";"D094";"D095";"D096";"D097";"D098";"D099";"D09A";"D09B";"D09C";"D09D";"D09E";"D09F"; \
                                 "D0A0";"D0A1";"D0A2";"D0A3";"D0A4";"D0A5";"D0A6";"D0A7";"D0A8";"D0A9";"D0AA";"D0AB";"D0AC";"D0AD";"D0AE";"D0AF"; \
                                 "D0B0";"D0B1";"D0B2";"D0B3";"D0B4";"D0B5";"D0B6";"D0B7";"D0B8";"D0B9";"D0BA";"D0BB";"D0BC";"D0BD";"D0BE";"D0BF"; \
                                 "D180";"D181";"D182";"D183";"D184";"D185";"D186";"D187";"D188";"D189";"D18A";"D18B";"D18C";"D18D";"D18E";"D18F"; \
                                 "D001";"D191";"2116"}];
        :local convStr ""; 
        :local code    "";
        :for i from=0 to=([:len $1]-1) do={
            :local symb [:pick $1 $i ($i+1)]; 
            :local idx  [:find $cp1251 $symb];
            :local key  ($utf8->$idx);
            :if ([:len $key] != 0) do={
                :set $code ("%$[:pick ($key) 0 2]%$[:pick ($key) 2 4]");
                :if ([pick $code 0 3] = "%00") do={ :set $code ([:pick $code 3 6]); }
            } else={ :set code ($symb); }; 
            :set $convStr ($convStr.$code);
        }
        :return ($convStr);
    }

    # Telegram messenger response parsing function by Dimonw
    # https://habr.com/ru/post/482802/
    :local MsgParser do={
        :local variaMod ("\"".$2);
        :local startLoc ([:find $1 $variaMod -1] + [:len $variaMod] + 2);
        :local commaLoc ([:find $1 "," $startLoc]);
        :local brakeLoc ([:find $1 "}" $startLoc]);
        :local endLoc $commaLoc;
        :local startSymbol [:pick $1 $startLoc]; 
        :if ($brakeLoc != 0 and ($commaLoc = 0 or $brakeLoc < $commaLoc)) do={ :set endLoc $brakeLoc; };
        :if ($startSymbol = "{") do={ :set endLoc ($brakeLoc + 1); };
        :if ($3 = true) do={
            :set startLoc ($startLoc + 1);
            :set endLoc   ($endLoc   - 1);
        }
        :if ($endLoc < $startLoc) do={ :set endLoc ($startLoc + 1); };
        :return ([:pick $1 $startLoc $endLoc]);
    }
    
    # Time translation function to UNIX-time by Jotne
    # https://forum.mikrotik.com/viewtopic.php?t=75555#p790745
    :local EpochTime do={
        :local ds [ /system clock get date; ];
        :local ts [ /system clock get time; ];
        :if ([:len $1] > 8) do={
            :set ds "$[:pick $1 0 6]/$[:pick $ds 7 11]";
            :set ts [:pick $1 7 15];
        }
        :local yesterday false;
        :if ([:len $1] = 8) do={
            :if ([:totime $1] > ts) do={ :set yesterday (true); }
            :set ts $1;
        }
        :local months;
        :if ((([:pick $ds 9 11]-1)/4) != (([:pick $ds 9 11])/4)) do={
            :set months {"an"=0;"eb"=31;"ar"=60;"pr"=91;"ay"=121;"un"=152;"ul"=182;"ug"=213;"ep"=244;"ct"=274;"ov"=305;"ec"=335};
        } else={
            :set months {"an"=0;"eb"=31;"ar"=59;"pr"=90;"ay"=120;"un"=151;"ul"=181;"ug"=212;"ep"=243;"ct"=273;"ov"=304;"ec"=334};
        }
        :set ds (([:pick $ds 9 11]*365)+(([:pick $ds 9 11]-1)/4)+($months->[:pick $ds 1 3])+[:pick $ds 4 6]);
        :set ts (([:pick $ts 0 2]*3600)+([:pick $ts 3 5]*60)+[:pick $ts 6 8]);
        :if (yesterday) do={ :set ds ($ds-1); }
        :return ($ds*86400 + $ts + 946684800 - [ /system clock get gmt-offset; ]);
    }

    # Main body of the script
    :global timeAct;
    :global timeLog;
    :local  nameID [ /system identity get name; ];
    :put ("$[$EpochTime] sec - current Unix-time of $nameID router.");
    if ([:len $timeAct] > 0) do={ :put ("$timeAct sec - time of checking the last script run."); }
    if ([:len $timeLog] > 0) do={ :put ("$timeLog sec - time of the last log check."); }

    # Part of the script body for running scripts via Telegram by drPioneer
    # https://forummikrotik.ru/viewtopic.php?p=78085
    :local  timeStamp [$EpochTime];
    :local  urlString "https://api.telegram.org/$botID/getUpdates\?offset=-1&limit=1&allowed_updates=message";
    :put ("... Stage of running scripts via Telegram:");
    :if ([:len $timeAct] = 0) do={
        :put ("Time of the last script activation was not found.");
        :set timeAct $timeStamp;
    } else={
        :local httpResp [ /tool fetch url=$urlString as-value output=user; ];
        :local content ($httpResp->"data");
        :if ([:len $content] > 30) do={
            :local msgTxt   [$MsgParser $content "text" true];
            :set   msgTxt  ([:pick $msgTxt ([:find $msgTxt "/"] + 1) ([:len $msgTxt])]);
            :local chat     [$MsgParser $content "chat"];
            :local chatId   [$MsgParser $chat    "id"];
            :local userName [$MsgParser $content "username"];
            :set  timeStamp [$MsgParser $content "date"];
            :if (($chatId = $myChatID) && ($timeAct < $timeStamp) && ([ /system script find name=$msgTxt; ] != "")) do={ 
                :set timeAct ($timeStamp);
                :put ("$timeStamp sec - activated script '$msgTxt' from user $userName.");
                :log warning ("Telegram user $userName activated script '$msgTxt' in $timeStamp sec.");                 
                /system script run $msgTxt;
            } else={ :put ("Nothing to activated."); }
        } else={ :put ("Completion of response from Telegram."); }
    }

    # Part of the script body for notifications in Telegram by Alice Tails
    # https://www.reddit.com/r/mikrotik/comments/onusoj/sending_log_alerts_to_telegram/
    :local outMsg "";
    :local logGet [ :toarray [ /log find ($topics ~"warning" || $topics ~"error" || $topics ~"critical" || $topics ~"caps" || $topics ~"wireless" || $message ~"logged in"); ]];
    :local logCnt [ :len $logGet ];
    :put ("... Stage of sending notifications to Telegram:");
    :if ([:len $timeLog] = 0) do={ 
        :put ("Time of the last log entry was not found.");
        :set outMsg (">$[ /system clock get time; ] Telegram notification started.");
    }
    :if ($logCnt > 0) do={
        :local lastTime [$EpochTime [ /log get [:pick $logGet ($logCnt-1)] time; ]];
        :local index 0;
        :local tempTime;
        :local tempMessage;
        :local tempTopic;
        :local unixTime;
        :do {
            :set index        ($index + 1); 
            :set tempTime     [ /log get [:pick $logGet ($logCnt - $index)]    time; ];
            :set tempTopic    [ /log get [:pick $logGet ($logCnt - $index)]  topics; ];
            :set tempMessage  [ /log get [:pick $logGet ($logCnt - $index)] message; ];
            :set tempMessage  (">".$tempTime." ".$tempMessage);
            :local findMacMsg ([$FindMacAddr $tempMessage]);
            :set unixTime [$EpochTime $tempTime];
            :if (($unixTime > $timeLog) && (!(($tempTopic ~"caps" || $tempTopic ~"wireless" || $tempTopic ~"dhcp") && ($tempMessage != $findMacMsg)))) do={
                :put $findMacMsg;
                :set outMsg ($findMacMsg."\n".$outMsg);
            }
        } while=(($unixTime > $timeLog) && ($index < $logCnt));
        :if (([:len $timeLog] < 1) || (([:len $timeLog] > 0) && ($timeLog != $lastTime) && ([:len $outMsg] > 8) )) do={
            :set timeLog $lastTime;
            :set outMsg [$CP1251toUTF8 $outMsg];
            :local urlString ("https://api.telegram.org/$botID/sendmessage\?chat_id=$myChatID&text=$nameID:%0A$outMsg");
            :put ("Generated string for Telegram:\r\n".$urlString);
            /tool fetch url=$urlString as-value output=user;
        } else={ :put ("Nothing to send."); }
    } else={ :put ("Necessary log entries were not found."); }
} on-error={ :put ("Script error: something went wrong when sending a request to Telegram."); }



Последний раз редактировалось drpioneer 08 ноя 2021, 23:42, всего редактировалось 7 раз.


Аватара пользователя
Virtue
Сообщения: 142
Зарегистрирован: 07 мар 2014, 10:17

drpioneer писал(а): 26 окт 2021, 15:10 Вариант с кириллицей может выглядеть так:
одного не понимаю, кому нужна эта кирилица? столько проблем с ней.. да еще приходится громоздить скрипты такие.. :du_ma_et:


Sertik
Сообщения: 1598
Зарегистрирован: 15 сен 2017, 09:03

А что плохого в кириллице ? Во-первых не все отлично знают английский язык. Во-вторых (я уже как то высказывался) пусть враги русский учат. В третьих а патриотизм где же ? Лично я за смешанный язык сообщений - наша задача сделать так чтобы можно было как угодно отправить сообщение. Дальше выбор за пользователем.
Спасибо дорогой Dr.Pioneer, Вы ещё лучше написали перекодировщик ! Поздравляю и жму руку. Единственно Вы, кажется, не предусмотрели перекодировку некоторых спец. символов - таких, как кавычки, +, обратный слеш, скобки и некоторых других. Проверьте, пожалуйста и дополните скрипт если это так. Специально пробовал отправлять в Телеграмм например плюс (+) - плюс не хочет печатать, а минус (-) - пожалуйста Вам. Ну где же логика ? Непонятно.
Есть к Вам (Dr.Pioneer) предложение одно, созрею немного, напишу в личку.

Моя рабочая версия Вашего (по сути и вкладу) скрипта выглядит следующим образом:

Код: Выделить всё

# Combined notification script and script launch via Telegram 
# https://forummikrotik.ru/viewtopic.php?p=81877#p81877
# tested on ROS 6.48.3
# updated 2021/10/23

:do {
    :global botID;
    :global myChatID;

    # Function of searching comments for MAC-address by Virtue
    # https://forummikrotik.ru/viewtopic.php?p=73994#p73994
    :local FindMacAddr do={
        :if ($1 ~"[0-F][0-F]:[0-F][0-F]:[0-F][0-F]:[0-F][0-F]:[0-F][0-F]:[0-F][0-F]") do={
            :foreach idx in=[ /ip dhcp-server lease find dynamic=no disabled=no; ] do={
                :local mac  [ /ip dhcp-server lease get $idx mac-address; ];
                :if ($1 ~"$mac") do={ :return ("$1 [$[ /ip dhcp-server lease get $idx comment; ]]."); } 
            }
            :foreach idx in=[ /interface bridge host find; ] do={
                :local mac  [ /interface bridge host get $idx mac-address; ];
                :if ($1 ~"$mac") do={ :return ("$1 [$[ /interface bridge host get $idx on-interface; ]]."); }
            }
        }
        :return ($1);
    }

# the function of converting Russian and some other characters to UTF8
# by Sertik
:local FuncStrToTele do={
:local string; :set $string $1;
#  table of the codes of Russian letters UTF8 + some characters are not supported by Telegram
:local rsimv [:toarray {"А"="D090"; "Б"="D091"; "В"="D092"; "Г"="D093"; "Д"="D094"; "Е"="D095"; "Ж"="D096"; "З"="D097"; "И"="D098"; "Й"="D099"; "К"="D09A"; "Л"="D09B"; "М"="D09C"; "Н"="D09D"; "О"="D09E"; "П"="D09F"; "Р"="D0A0"; "С"="D0A1"; "Т"="D0A2"; "У"="D0A3"; "Ф"="D0A4"; "Х"="D0A5"; "Ц"="D0A6"; "Ч"="D0A7"; "Ш"="D0A8"; "Щ"="D0A9"; "Ъ"="D0AA"; "Ы"="D0AB"; "Ь"="D0AC"; "Э"="D0AD"; "Ю"="D0AE"; "Я"="D0AF"; "а"="D0B0"; "б"="D0B1"; "в"="D0B2"; "г"="D0B3"; "д"="D0B4"; "е"="D0B5"; "ж"="D0B6"; "з"="D0B7"; "и"="D0B8"; "й"="D0B9"; "к"="D0BA"; "л"="D0BB"; "м"="D0BC"; "н"="D0BD"; "о"="D0BE"; "п"="D0BF"; "р"="D180"; "с"="D181"; "т"="D182"; "у"="D183"; "ф"="D184"; "х"="D185"; "ц"="D186"; "ч"="D187"; "ш"="D188"; "щ"="D189"; "ъ"="D18A"; "ы"="D18B"; "ь"="D18C"; "э"="D18D"; "ю"="D18E"; "я"="D18F"; "Ё"="D001"; "ё"="D191"; "№"="0023"; " "="0020"; "&"="0026"; "`"="0027"; "+"="002B";"["="005B"; "\"="005C"; "]"="005D"; "_"="005F"; "'"="0060"}]
# encoding of the symbols and аssembly line
:local StrTele ""; :local code "";
:for i from=0 to=([:len $string]-1) do={:local keys [:pick $string $i (1+$i)]; :local key ($rsimv->$keys); if ([:len $key]!=0) do={:set $code ("%"."$[:pick ($rsimv->$keys) 0 2]"."%"."$[:pick ($rsimv->$keys) 2 4]"); :if ([pick $code 0 3] ="%00") do={:set $code [:pick $code 3 6]}} else={:set $code $keys}; :set $StrTele ("$StrTele"."$code")}
:return $StrTele;
}


    # Telegram messenger response parsing function by Dimonw
    # https://habr.com/ru/post/482802/
    :local RespParser do={
        :local variaMod ("\"".$2);
        :local startLoc ([:find $1 $variaMod -1] + [:len $variaMod] + 2);
        :local commaLoc ([:find $1 "," $startLoc]);
        :local brakeLoc ([:find $1 "}" $startLoc]);
        :local endLoc $commaLoc;
        :local startSymbol [:pick $1 $startLoc]; 
        :if ($brakeLoc != 0 and ($commaLoc = 0 or $brakeLoc < $commaLoc)) do={ :set endLoc $brakeLoc; };
        :if ($startSymbol = "{") do={ :set endLoc ($brakeLoc + 1); };
        :if ($3 = true) do={
            :set startLoc ($startLoc + 1);
            :set endLoc   ($endLoc   - 1);
        }
        :if ($endLoc < $startLoc) do={ :set endLoc ($startLoc + 1); };
        :return ([:pick $1 $startLoc $endLoc]);
    }
    
    # Time translation function to UNIX-time by Jotne
    # https://forum.mikrotik.com/viewtopic.php?t=75555#p790745
    :local EpochTime do={
        :local ds [ /system clock get date; ];
        :local ts [ /system clock get time; ];
        :if ([:len $1] > 8) do={
            :set ds "$[:pick $1 0 6]/$[:pick $ds 7 11]";
            :set ts [:pick $1 7 15];
        }
        :local yesterday false;
        :if ([:len $1] = 8) do={
            :if ([:totime $1] > ts) do={ :set yesterday (true); }
            :set ts $1;
        }
        :local months;
        :if ((([:pick $ds 9 11]-1)/4) != (([:pick $ds 9 11])/4)) do={
            :set months {"an"=0;"eb"=31;"ar"=60;"pr"=91;"ay"=121;"un"=152;"ul"=182;"ug"=213;"ep"=244;"ct"=274;"ov"=305;"ec"=335};
        } else={
            :set months {"an"=0;"eb"=31;"ar"=59;"pr"=90;"ay"=120;"un"=151;"ul"=181;"ug"=212;"ep"=243;"ct"=273;"ov"=304;"ec"=334};
        }
        :set ds (([:pick $ds 9 11]*365)+(([:pick $ds 9 11]-1)/4)+($months->[:pick $ds 1 3])+[:pick $ds 4 6]);
        :set ts (([:pick $ts 0 2]*3600)+([:pick $ts 3 5]*60)+[:pick $ts 6 8]);
        :if (yesterday) do={ :set ds ($ds-1); }
        :return ($ds*86400 + $ts + 946684800 - [ /system clock get gmt-offset; ]);
    }

    # Main body of the script
    :local  nameID [ /system identity get name; ];
    :put ("Current Unix-time on $nameID router: $[$EpochTime] sec.");

    # Part of the script body for running scripts via Telegram by drPioneer
    # https://forummikrotik.ru/viewtopic.php?p=78085
    :global timeAct;
    :local  timeStamp [$EpochTime];
    :local  urlString "";
    :put ("... Stage of running scripts via Telegram:");
    :if ([:len $timeAct] > 0) do={
        :set urlString ("https://api.telegram.org/$botID/getUpdates\?offset=-1&limit=1&allowed_updates=message");
        :local httpResp [ /tool fetch url=$urlString as-value output=user; ];
        :local content ($httpResp->"data");
        :if ([:len $content] > 30) do={
            :local msgTxt   [$RespParser $content "text" true];
            :set   msgTxt  ([:pick $msgTxt ([:find $msgTxt "/"] + 1) ([:len $msgTxt])]);
            :local chat     [$RespParser $content "chat"];
            :local chatId   [$RespParser $chat    "id"];
            :local userName [$RespParser $content "username"];
            :set  timeStamp [$RespParser $content "date"];
            :if (($chatId = $myChatID) && ($timeAct < $timeStamp) && ([ /system script find name=$msgTxt; ] != "")) do={ 
                :put (">Found command '$msgTxt' from user $userName in $timeStamp sec.");
                :set timeAct ($timeStamp);
#                :log warning ("Telegram user $userName activated script '$msgTxt' in $timeStamp sec.");                 
                /system script run $msgTxt;
            } else={ :put ("Nothing to run."); }
        } else={ :put ("No response from Telegram."); }
    } else={
        :put ("Time of the last script activation was not found.");
        :set timeAct [$EpochTime];
    }

    # Part of the script body for notifications in Telegram by Alice Tails
    # https://www.reddit.com/r/mikrotik/comments/onusoj/sending_log_alerts_to_telegram/
    :global timeLog;
    :local outMsg "";

    :local logGet [ :toarray [ /log find ($topics ~"warning" || $topics ~"error" || $topics ~"critical" || $topics ~"system" || $topics ~"connected" || $topics ~"login failure" || $topics ~"caps" || $topics ~"wireless" || $message ~"logged" || message~"[Ff]ailure"); ]];
    :local logCnt [ :len $logGet ];
    :put ("... Stage of sending notifications to Telegram:");
    :if ([:len $timeLog] < 1) do={ 
        :put ("Time of the last log entry was not found.");
        :set outMsg (">$[ /system clock get time; ] Telegram notification and runner started.");
    }
    :if ($logCnt > 0) do={
        :local lastTime [$EpochTime [ /log get [:pick $logGet ($logCnt-1)] time; ]];
        :local index 0;
        :local tempTime;
        :local tempMessage;
        :local tempTopic;
        :local unixTime;
        :do {
            :set index        ($index + 1); 
            :set tempTime     [ /log get [:pick $logGet ($logCnt - $index)]    time; ];
            :set tempTopic    [ /log get [:pick $logGet ($logCnt - $index)]  topics; ];
            :set tempMessage  [ /log get [:pick $logGet ($logCnt - $index)] message; ];
            :set tempMessage  (">".$tempTime." ".$tempMessage);
            :local findMacMsg ([$FindMacAddr $tempMessage]);
            :set unixTime [$EpochTime $tempTime];
            :if (($unixTime > $timeLog) && (!(($tempTopic ~"caps" || $tempTopic ~"wireless" || $tempTopic ~"dhcp") && ($tempMessage != $findMacMsg)))) do={
                :put $findMacMsg;
                :set outMsg ($findMacMsg."%0A".$outMsg);
            }
        } while=(($unixTime > $timeLog) && ($index < $logCnt));
        :if (([:len $timeLog] < 1) || (([:len $timeLog] > 0) && ($timeLog != $lastTime) && ([:len $outMsg] > 8) )) do={
            :set timeLog $lastTime;
             :set outMsg [$FuncStrToTele ("$Emoji "."$nameID".":"."%0A"."$outMsg")]
              :local urlString ("https://api.telegram.org/$botID/sendmessage\?chat_id=$myChatID&text=$outMsg");
#            :put ("Generated string for Telegram:\r\n".$urlString);
              /tool fetch url=$urlString as-value output=user;
        } else={ :put ("Nothing to send."); }
    } else={ :put ("Necessary log entries were not found."); }
} on-error={ :put ("Script error: check whether 'botID' & 'myChatID' variables are specified correctly."); }



фрагменты скриптов, готовые работы, статьи, полезные приемы, ссылки
viewtopic.php?f=14&t=13947
Аватара пользователя
drpioneer
Сообщения: 142
Зарегистрирован: 30 май 2013, 10:20

Sertik писал(а): 27 окт 2021, 17:17 ...
Вы, кажется, не предусмотрели перекодировку некоторых спец. символов - таких, как кавычки, +, обратный слеш, скобки и некоторых других. Проверьте, пожалуйста и дополните скрипт если это так. Специально пробовал отправлять в Телеграмм например плюс (+) - плюс не хочет печатать, а минус (-) - пожалуйста Вам. Ну где же логика ? Непонятно.
...
Действительно, часть спецсимволов не перекодировалась.
Удалось определиться с причиной такого поведения скрипта: согласно правилам формирования URI, спецсимволы являются зарезервированными символами-делителями, которые участвуют в формировании URI. Для передачи таких символов в качестве текста нужно применять процентное кодирование (см. https://habr.com/ru/post/232385/).
С учётом этого обстоятельства скрипт вновь был модифицирован: viewtopic.php?p=81945#p81945


vovvw
Сообщения: 20
Зарегистрирован: 25 янв 2021, 10:18

drpioneer писал(а): 27 окт 2021, 23:08 С учётом этого обстоятельства скрипт вновь был модифицирован: viewtopic.php?p=81945#p81945
Спасибо, все работает!
Имеется возможность указать конкретный микротик для выполнения скрипта?


Аватара пользователя
drpioneer
Сообщения: 142
Зарегистрирован: 30 май 2013, 10:20

Приветствую!
vovvw писал(а): 08 ноя 2021, 16:01 Имеется возможность указать конкретный микротик для выполнения скрипта?
Нет. Указать конкретный девайс для выполнения скрипта возможности не предусмотрено.
У себя этот вопрос я решаю путём уникального названия скриптов.
Например скрипт с именем "wol" на роутере: "device1" я назвал: "dev1wol".
Этот же скрипт для "device2" в моём случае будет называться: "dev2wol" и т.д.
На мой взгляд просто и понятно.


Аватара пользователя
drpioneer
Сообщения: 142
Зарегистрирован: 30 май 2013, 10:20

Добрый день.

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

Код: Выделить всё




# Combined notification script and script launch via Telegram  by drPioneer
# https://forummikrotik.ru/viewtopic.php?p=81945#p81945
# tested on ROS 6.49
# updated 2021/11/24

:do {
    :local botID    "botXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
    :local myChatID "-XXXXXXXXX";

    # Function of searching comments for MAC-address by Virtue
    # https://forummikrotik.ru/viewtopic.php?p=73994#p73994
    :local FindMacAddr do={
        :if ($1 ~"[0-F][0-F]:[0-F][0-F]:[0-F][0-F]:[0-F][0-F]:[0-F][0-F]:[0-F][0-F]") do={
            :foreach idx in=[ /ip dhcp-server lease find dynamic=no disabled=no; ] do={
                :local mac  [ /ip dhcp-server lease get $idx mac-address; ];
                :if ($1 ~"$mac") do={ 
                    :return ("$1 [$[ /ip dhcp-server lease get $idx address; ]/\
                        $[ /ip dhcp-server lease get $idx comment; ]]."); 
                } 
            }
            :foreach idx in=[ /interface bridge host find; ] do={
                :local mac  [ /interface bridge host get $idx mac-address; ];
                :if ($1 ~"$mac") do={ :return ("$1 [$[ /interface bridge host get $idx on-interface; ]]."); }
            }
        }
        :return ($1);
    }

    # Function of converting CP1251 to UTF8 by Sertik
    # https://forummikrotik.ru/viewtopic.php?p=81457#p81457
    :local CP1251toUTF8 do={
        :local cp1251 [:toarray {"\20";"\01";"\02";"\03";"\04";"\05";"\06";"\07";"\08";"\09";"\0A";"\0B";"\0C";"\0D";"\0E";"\0F"; \
                                 "\10";"\11";"\12";"\13";"\14";"\15";"\16";"\17";"\18";"\19";"\1A";"\1B";"\1C";"\1D";"\1E";"\1F"; \
                                 "\21";"\22";"\23";"\24";"\25";"\26";"\27";"\28";"\29";"\2A";"\2B";"\2C";"\2D";"\2E";"\2F";"\3A"; \
                                 "\3B";"\3C";"\3D";"\3E";"\3F";"\40";"\5B";"\5C";"\5D";"\5E";"\5F";"\60";"\7B";"\7C";"\7D";"\7E"; \
                                 "\C0";"\C1";"\C2";"\C3";"\C4";"\C5";"\C7";"\C7";"\C8";"\C9";"\CA";"\CB";"\CC";"\CD";"\CE";"\CF"; \
                                 "\D0";"\D1";"\D2";"\D3";"\D4";"\D5";"\D6";"\D7";"\D8";"\D9";"\DA";"\DB";"\DC";"\DD";"\DE";"\DF"; \
                                 "\E0";"\E1";"\E2";"\E3";"\E4";"\E5";"\E6";"\E7";"\E8";"\E9";"\EA";"\EB";"\EC";"\ED";"\EE";"\EF"; \
                                 "\F0";"\F1";"\F2";"\F3";"\F4";"\F5";"\F6";"\F7";"\F8";"\F9";"\FA";"\FB";"\FC";"\FD";"\FE";"\FF"; \
                                 "\A8";"\B8";"\B9"}];
        :local utf8   [:toarray {"0020";"0020";"0020";"0020";"0020";"0020";"0020";"0020";"0020";"0020";"000A";"0020";"0020";"000D";"0020";"0020"; \
                                 "0020";"0020";"0020";"0020";"0020";"0020";"0020";"0020";"0020";"0020";"0020";"0020";"0020";"0020";"0020";"0020"; \
                                 "0021";"0022";"0023";"0024";"0025";"0026";"0027";"0028";"0029";"002A";"002B";"002C";"002D";"002E";"002F";"003A"; \
                                 "003B";"003C";"003D";"003E";"003F";"0040";"005B";"005C";"005D";"005E";"005F";"0060";"007B";"007C";"007D";"007E"; \
                                 "D090";"D091";"D092";"D093";"D094";"D095";"D096";"D097";"D098";"D099";"D09A";"D09B";"D09C";"D09D";"D09E";"D09F"; \
                                 "D0A0";"D0A1";"D0A2";"D0A3";"D0A4";"D0A5";"D0A6";"D0A7";"D0A8";"D0A9";"D0AA";"D0AB";"D0AC";"D0AD";"D0AE";"D0AF"; \
                                 "D0B0";"D0B1";"D0B2";"D0B3";"D0B4";"D0B5";"D0B6";"D0B7";"D0B8";"D0B9";"D0BA";"D0BB";"D0BC";"D0BD";"D0BE";"D0BF"; \
                                 "D180";"D181";"D182";"D183";"D184";"D185";"D186";"D187";"D188";"D189";"D18A";"D18B";"D18C";"D18D";"D18E";"D18F"; \
                                 "D001";"D191";"2116"}];
        :local convStr ""; 
        :local code    "";
        :for i from=0 to=([:len $1]-1) do={
            :local symb [:pick $1 $i ($i+1)]; 
            :local idx  [:find $cp1251 $symb];
            :local key  ($utf8->$idx);
            :if ([:len $key] != 0) do={
                :set $code ("%$[:pick ($key) 0 2]%$[:pick ($key) 2 4]");
                :if ([pick $code 0 3] = "%00") do={ :set $code ([:pick $code 3 6]); }
            } else={ :set code ($symb); }; 
            :set $convStr ($convStr.$code);
        }
        :return ($convStr);
    }

    # Telegram messenger response parsing function by Dimonw
    # https://habr.com/ru/post/482802/
    :local MsgParser do={
        :local variaMod ("\"".$2);
        :local startLoc ([:find $1 $variaMod -1] + [:len $variaMod] + 2);
        :local commaLoc ([:find $1 "," $startLoc]);
        :local brakeLoc ([:find $1 "}" $startLoc]);
        :local endLoc $commaLoc;
        :local startSymbol [:pick $1 $startLoc]; 
        :if ($brakeLoc != 0 and ($commaLoc = 0 or $brakeLoc < $commaLoc)) do={ :set endLoc $brakeLoc; };
        :if ($startSymbol = "{") do={ :set endLoc ($brakeLoc + 1); };
        :if ($3 = true) do={
            :set startLoc ($startLoc + 1);
            :set endLoc   ($endLoc   - 1);
        }
        :if ($endLoc < $startLoc) do={ :set endLoc ($startLoc + 1); };
        :return ([:pick $1 $startLoc $endLoc]);
    }
    
    # Time translation function to UNIX-time by Jotne
    # https://forum.mikrotik.com/viewtopic.php?t=75555#p790745
    :local EpochTime do={
        :local ds [ /system clock get date; ];
        :local ts [ /system clock get time; ];
        :if ([:len $1] > 8) do={
            :set ds "$[:pick $1 0 6]/$[:pick $ds 7 11]";
            :set ts [:pick $1 7 15];
        }
        :local yesterday false;
        :if ([:len $1] = 8) do={
            :if ([:totime $1] > ts) do={ :set yesterday (true); }
            :set ts $1;
        }
        :local months;
        :if ((([:pick $ds 9 11]-1)/4) != (([:pick $ds 9 11])/4)) do={
            :set months {"an"=0;"eb"=31;"ar"=60;"pr"=91;"ay"=121;"un"=152;"ul"=182;"ug"=213;"ep"=244;"ct"=274;"ov"=305;"ec"=335};
        } else={
            :set months {"an"=0;"eb"=31;"ar"=59;"pr"=90;"ay"=120;"un"=151;"ul"=181;"ug"=212;"ep"=243;"ct"=273;"ov"=304;"ec"=334};
        }
        :set ds (([:pick $ds 9 11]*365)+(([:pick $ds 9 11]-1)/4)+($months->[:pick $ds 1 3])+[:pick $ds 4 6]);
        :set ts (([:pick $ts 0 2]*3600)+([:pick $ts 3 5]*60)+[:pick $ts 6 8]);
        :if (yesterday) do={ :set ds ($ds-1); }
        :return ($ds*86400 + $ts + 946684800 - [ /system clock get gmt-offset; ]);
    }

    # Main body of the script
    :global timeAct;
    :global timeLog;
    :local  nameID [ /system identity get name; ];
    :put ("$[$EpochTime] sec - current Unix-time of $nameID router.");
    if ([:len $timeAct] > 0) do={ :put ("$timeAct sec - time of checking the last script run."); }
    if ([:len $timeLog] > 0) do={ :put ("$timeLog sec - time of the last log check."); }

    # Part of the script body for running scripts via Telegram by drPioneer
    # https://forummikrotik.ru/viewtopic.php?p=78085
    :local  timeStamp [$EpochTime];
    :local  urlString "https://api.telegram.org/$botID/getUpdates\?offset=-1&limit=1&allowed_updates=message";
    :put ("... Stage of running scripts via Telegram:");
    :if ([:len $timeAct] = 0) do={
        :put ("Time of the last script activation was not found.");
        :set timeAct $timeStamp;
    } else={
        :local httpResp [ /tool fetch url=$urlString as-value output=user; ];
        :local content ($httpResp->"data");
        :if ([:len $content] > 30) do={
            :local msgTxt   [$MsgParser $content "text" true];
            :set   msgTxt  ([:pick $msgTxt ([:find $msgTxt "/"] + 1) ([:len $msgTxt])]);
            :local chat     [$MsgParser $content "chat"];
            :local chatId   [$MsgParser $chat    "id"];
            :local userName [$MsgParser $content "username"];
            :set  timeStamp [$MsgParser $content "date"];
            :if (($chatId = $myChatID) && ($timeAct < $timeStamp) && ([ /system script find name=$msgTxt; ] != "")) do={ 
                :set timeAct ($timeStamp);
                :put ("$timeStamp sec - activated script '$msgTxt' from user $userName.");
                :log warning ("Telegram user $userName activated script '$msgTxt' in $timeStamp sec.");                 
                /system script run $msgTxt;
            } else={ :put ("Nothing to activated."); }
        } else={ :put ("Completion of response from Telegram."); }
    }

    # Part of the script body for notifications in Telegram by Alice Tails
    # https://www.reddit.com/r/mikrotik/comments/onusoj/sending_log_alerts_to_telegram/
    :local outMsg "";
    :local logGet [ :toarray [ /log find ($topics ~"warning" || $topics ~"error" || $topics ~"critical" || $topics ~"caps" || $topics ~"wireless" || $message ~"logged in"); ]];
    :local logCnt [ :len $logGet ];
    :put ("... Stage of sending notifications to Telegram:");
    :if ([:len $timeLog] = 0) do={ 
        :put ("Time of the last log entry was not found.");
        :set outMsg (">$[ /system clock get time; ] Telegram notification started.");
    }
    :if ($logCnt > 0) do={
        :local lastTime [$EpochTime [ /log get [:pick $logGet ($logCnt-1)] time; ]];
        :local index 0;
        :local tempTime;
        :local tempMessage;
        :local tempTopic;
        :local unixTime;
        :do {
            :set index        ($index + 1); 
            :set tempTime     [ /log get [:pick $logGet ($logCnt - $index)]    time; ];
            :set tempTopic    [ /log get [:pick $logGet ($logCnt - $index)]  topics; ];
            :set tempMessage  [ /log get [:pick $logGet ($logCnt - $index)] message; ];
            :set tempMessage  (">".$tempTime." ".$tempMessage);
            :local findMacMsg ([$FindMacAddr $tempMessage]);
            :set unixTime [$EpochTime $tempTime];
            :if (($unixTime > $timeLog) && (!(($tempTopic ~"caps" || $tempTopic ~"wireless" || $tempTopic ~"dhcp") && ($tempMessage != $findMacMsg)))) do={
                :put $findMacMsg;
                :set outMsg ($findMacMsg."\n".$outMsg);
            }
        } while=(($unixTime > $timeLog) && ($index < $logCnt));
        :if (([:len $timeLog] < 1) || (([:len $timeLog] > 0) && ($timeLog != $lastTime) && ([:len $outMsg] > 8) )) do={
            :set timeLog $lastTime;
            if ([:len $outMsg] > 4096) do={ :set outMsg ([:pick $outMsg 0 4096]); }
            :set outMsg [$CP1251toUTF8 $outMsg];
            :local urlString ("https://api.telegram.org/$botID/sendmessage\?chat_id=$myChatID&text=$nameID:%0A$outMsg");
            :put ("Generated string for Telegram:\r\n".$urlString);
            /tool fetch url=$urlString as-value output=user;
        } else={ :put ("Nothing to send."); }
    } else={ :put ("Necessary log entries were not found."); }
} on-error={ :put ("Script error: something went wrong when sending a request to Telegram."); }





Ответить