оповещение в телегу

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

Sertik писал(а): 13 сен 2021, 14:33 не понимаю, почему тут у топикастеров возникают проблемы с отправкой на Телеграмм пробелов. Мои функции спокойно пересылают пробелы без всякой дополнительной их обработки.
Потому, что проблема не с " ", а с " h"


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

странно, но у меня с " h" работает всё нормально. Уточните, пожалуйста вариант когда не работает и приведите пример полностью, посмотрим что там такое.


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

Sertik писал(а): 13 сен 2021, 18:50 странно, но у меня с " h" работает всё нормально. Уточните, пожалуйста вариант когда не работает и приведите пример полностью, посмотрим что там такое.
Поправка, h должна быть заглавная.
например такая функция у меня выдаёт ошибку, а если H заменить на другую букву, то отрабатывает

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

:global telegram2 do={
:global bot
:global chat
:tool fetch url=("https://api.telegram.org/$bot/sendmessage\?chat_id=$chat&text= H") keep-result=no
}


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

Да, действительно сочетание пробела и заглавной H дает ошибку - Телеграмм не печатает такую строку.
Вариантов решения вижу три:
1. предложенный Вами вариант вторично пробегать по строке выданной $StrToTele и заменять пробелы на %20

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

set $StrTele [$SpaceToCode $StrTele]
:return $StrTele;
}

global SpaceToCode do={
local string ""
local char
put $1
for i from=0 to ([len $1]-1) step=1 do={
  #put $i
  set $char [pick $1 $i]
  #put $char
  if ($char=" ") do={set $char "%20"}
  set $string ($string . $char)
  #put $string
  }
return $string
}
2. второй вариант поставить в массив моей StrToTele элемент с ключом " " и его значением "0020" - проще всего, как мне кажется - " "="0020";

3. Ну и третий вариант в самой StrToTele проверять на наличие пробела и следующей за ним буквой H вот так, например:

:if (($keys=" ") and ([:pick $string ($i+1) ($i+2)]="H")) do={:set $code "%20"} else={ ...


Больше мне нравится вариант 3, вариант два самый простой, самый короткий, но костыльный с точки зрения программиста.
Варианты 1 и 2 заменяют все пробелы на %20, что удлиняет итоговый строку, вариант 3 вставляет код %20 только при сочетании " " и H


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

Sertik писал(а): 14 сен 2021, 14:00
Вариантов решения вижу три:
2. второй вариант поставить в массив моей StrToTele элемент с ключом " " и его значением "0020" - проще всего, как мне кажется - " "="0020";

3. Ну и третий вариант в самой StrToTele проверять на наличие пробела и следующей за ним буквой H вот так, например:

:if (($keys=" ") and ([:pick $string ($i+1) ($i+2)]="H")) do={:set $code "%20"} else={ ...


Больше мне нравится вариант 3, вариант два самый простой, самый короткий, но костыльный с точки зрения программиста.
Варианты 1 и 2 заменяют все пробелы на %20, что удлиняет итоговый строку, вариант 3 вставляет код %20 только при сочетании " " и H
С вашей функцией не разобрался, почему откуда во втором варианте "0020" если должно быть "%20"(как в варианте 3)?

P.S.
1)Я не знаю почему " H" вызывает ошибку. Поэтому я предпочту перестраховаться и заменить все пробелы, может ещё в каких-то ситуациях ошибка вылезет.
2)Я не уверен что вариант 2 длинне варианта 3. Хз как там строка кодируется. По хорошему надо снять трафик по варианту 2 и 3 и посмотреть где пакет короче.

UPD
Лучше менять все пробелы, объяснение тут
viewtopic.php?f=14&t=11996&start=30


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

C вашей функцией не разобрался, почему откуда во втором варианте "0020" если должно быть "%20"(как в варианте 3)?
Там первоначально в массиве хранится "0020", чтобы не менять алгоритм подстановки, а потом проверяется если образовалось %00%20, то менять это на %20 отсекая первые %00.

Если нужно скачайте заново универсальную функцию FuncTelegramSender, там все пробелы заменяются на %20.


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

Приветствую!

Почитал топик и решил изобразить очередную версию скрипта с учётом замечаний и наработок жителей этого форума. Получилось вот что:

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



# Telegram notification script by drPioneer
# https://forummikrotik.ru/viewtopic.php?p=81685#p81685
# tested on ROS 6.48.3
# updated 2021/10/01

:global oldString;

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

    # Function of converting UTF8 to codes by Sertik
    # https://forummikrotik.ru/viewtopic.php?p=81457#p81457
    :local Utf8Converter do={
        :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"; "^"="005E"}]
        :local convertString ""; 
        :local code          "";
        :for i from=0 to=([:len $1]-1) do={
            :local keys [:pick $1 $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 $convertString ($convertString.$code);
        }
    return $convertString;
    }

    # Main body of Telegram notification script by Virtue
    # https://forummikrotik.ru/viewtopic.php?p=73994#p73994
    :local nameID  [ /system identity get name; ];
    :local timeNow [ /system clock    get time; ];
    :local logs "";
    :if ([:pick $timeNow 0 2] < 03) do={
        :local date [ /system clock get date; ];
        :foreach h in=[ /log find; ] do={
            :local htime [ /log get $h time; ];
            :if (($htime ~[:pick $date 0 6]) && ([:pick $htime 7 15] > ($timeNow - 00:01:00))) do={ :set logs ($logs, $h); }
        }
    } else={ :set logs [ /log find time >= ($timeNow - 00:01:00) ]; }
    :if ([:len $logs] > 0 ) do={
        :local message "";
        :local presence false;
        :foreach i in=$logs do={
            :local imessage [ /log get $i message; ];
            :local topics   [ /log get $i topics; ];
            :if ($imessage ~"telnet" && $imessage ~"logged in") do={ } else={
                :if ($topics ~"caps" || $topics ~"wireless") do={
                    :if ($imessage ~"[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 k  in=[ /ip dhcp-server lease find dynamic=no disabled=no; ] do={
                            :local mac [ /ip dhcp-server lease get $k mac-address; ];
                            :if ($imessage ~"$mac") do={ :set presence true; }
                        }
                    }
                    :if (presence = false) do={
                        :local currentTime [ /log get $i time; ];
                        :set message ($message.$currentTime." ".$imessage."%0A%0A");
                    }
                }
                :if ($topics ~"warning" || $topics ~"error" || $topics ~"critical" || $imessage ~"logged in") do={
                    :if ($imessage ~"[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 k  in=[ /ip dhcp-server lease find dynamic=no disabled=no; ] do={
                            :local mac [ /ip dhcp-server lease get $k mac-address; ];
                            :if ($imessage ~"$mac") do={ :set imessage ($imessage." / ".[ /ip dhcp-server lease get $k comment; ]); }
                        }
                    }
                :local currentTime [ /log get $i time; ];
                :set message ($message.$currentTime." ".$imessage."%0A%0A");
                }
            }
        }
        :if ([:len $message] > 0 ) do={
            :local urlString ("https://api.telegram.org/$botID/sendmessage\?chat_id=$myChatID&text=$nameID:%0A$message");
            :set urlString [$Utf8Converter $urlString];
            :if ($urlString != $oldString) do={
                :put ("Generated string for Telegram:\r\n".$urlString);
                :set oldString ($urlString);
                /tool fetch keep-result=no url=$urlString;
            } else={ :put ("Message has already been sent."); }
        } else={ :put ("No necessary conditions for generating a message."); }
    } else={ :put ("No new log entries found."); }
}


Пробуйте...

Конструктивная критика и замечания, как всегда, приветствуются.


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

Приветствую. Пока детально не вникал, но на ум пришло две вещи:

1. Зачем в скрипте моя функция конвертер русского текста для Телеграмм ? Ведь всё логирование роутера Микротик построено на английском. Или Ваш скрипт пишет в Телеграмм и русские логи, появляющиеся в логе по :log info, log warning, log error ? Вероятно это так, надо будет попробовать.
Кстати хочу сказать, что моя функция предназначена именно для конвертации русских букв в utf-8 и не поддерживает многие специальные знаки (типа @#^~ ` и т.д...). Это следует учитывать и дополнить функцию поддержкой таковых.

2. Однако у меня очень давно на всех роутерах стоит вот такой скрипт оповещения событий роутера в Телеграмм, добытый где-то на просторах интернет. К сожалению не знаю автора, но скрипт работает чудесно, ни разу не подводил и сам очень короткий. Вот такой:

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

:global lastTime
:global output
:global mtIdentity [/system identity get name];
:global botID "botID" ;
:global myChatID "chatID" ;

:local LogGet [ :toarray [ /log find topics~"wireless" || message~"system" || message~"login failure" || message~"logged" || message~"connected" || message~"[Ff]ailure" ] ];
:local LogtLineCount [ :len $LogGet ] ;
if ($LogtLineCount > 0) do={
   :local currentTime "$[ /log get [ :pick $LogGet ($LogtLineCount -1) ] time ]";
   :if ([:len $currentTime] = 10 ) do={
      :set currentTime [ :pick $currentTime 0 10 ];
   }
   :set output "$currentTime - $[/log get [ :pick $LogGet ($LogtLineCount-1) ] message ]";
   :if (([:len $lastTime] < 1) || (([:len $lastTime] > 0) && ($lastTime != $currentTime))) do={
      :set lastTime $currentTime ;
         :tool fetch url=("https://api.telegram.org/$botID/sendmessage\?chat_id=$myChatID&text=%E2%9B%BA \"$mtIdentity\" :  $output") keep-result=no
   }
}


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

Sertik писал(а): 04 окт 2021, 13:31 и сам очень короткий
не одупляю вот эти строчки:

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

   :if ([:len $currentTime] = 10 ) do={
      :set currentTime [ :pick $currentTime 0 10 ];
где вы видели len time равной 10? оно всегда =8
и даже если предположить что это так, то непонятной становится вторая строка, которая якобы вырезает от 0 до 10, в итоге ничего не вырезает, выходит эти строки в любом случае бессмысленны
попробуйте их удалить, думаю ничего не изменится


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

Virtue писал(а): 06 окт 2021, 00:58 не одупляю вот эти строчки:

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

   :if ([:len $currentTime] = 10 ) do={
      :set currentTime [ :pick $currentTime 0 10 ];
Посмею предположить, что в условие закралась ошибка. Вероятно вместо "=" автор хотел поставить ">", в этом случае такая запись приобретает хоть какой-то смысл.


Ответить