Compare commits

...

20 commits

Author SHA1 Message Date
Christian Hesse
4db0a0d4f0 DEBUG: fix typo 2025-05-21 22:15:19 +02:00
Christian Hesse
5b5e3d47b6 telegram-chat: support debug output for updates in JSON 2025-05-21 22:15:19 +02:00
Christian Hesse
828c93bd66 telegram-chat: support trusted group chat ids
But be warned: Adding a person to a trusted group will give
her/him administrative control over the device(s) - without
changes on the device itself!

On the other hand... Removing permissions is easily done by removing
a person from a group.

Closes: https://github.com/eworm-de/routeros-scripts/issues/101
2025-05-21 22:15:19 +02:00
Christian Hesse
0576fbc532 mod/notification-telegram: fix indention 2025-05-21 22:15:19 +02:00
Christian Hesse
9d94d69677 fw-addr-lists: for IPv6 the CIDR is always expected 2025-05-21 22:15:19 +02:00
Christian Hesse
3e404027f6 mod/notification-email: add the link symbol 2025-05-21 22:15:19 +02:00
Christian Hesse
de9e726661 mod/notification-email: properly truncate the body
Truned out that the size limit for e-mail message/body is anywhere just
below 64kB... So truncate  at about 62.000 bytes.
2025-05-21 22:15:19 +02:00
Christian Hesse
68c38df755 mod/notification-email: add error handling when sending mail 2025-05-21 22:15:19 +02:00
Christian Hesse
6209f52962 mod/inspectvar: replace only when matching 2025-05-21 22:15:19 +02:00
Christian Hesse
616e9f244a mod/inspectvar: remove CR, replace LF 2025-05-21 22:15:19 +02:00
Christian Hesse
02531d5fae mod/inspectvar: print the length for strings 2025-05-21 22:15:19 +02:00
Christian Hesse
bd700b8e75 mod/inspectvar: use $CharacterMultiply 2025-05-21 22:15:19 +02:00
Christian Hesse
1a782018bb Merge branch 'onerror' into next 2025-05-21 22:15:19 +02:00
Christian Hesse
fee409f0ba update-tunnelbroker: :do ... on-error=... -> :onerror ... do=... 2025-05-21 22:15:19 +02:00
Christian Hesse
7e58ee3fdb unattended-lte-firmware-upgrade: :do ... on-error=... -> :onerror ... do=... 2025-05-21 22:15:19 +02:00
Christian Hesse
37b417369e telegram-chat: :do ... on-error=... -> :onerror ... do=... 2025-05-21 22:15:19 +02:00
Christian Hesse
70b10dd2a6 sms-forward: :do ... on-error=... -> :onerror ... do=... 2025-05-21 22:15:19 +02:00
Christian Hesse
a6f9e6c6be netwatch-notify: :do ... on-error=... -> :onerror ... do=... 2025-05-21 22:15:19 +02:00
Christian Hesse
e138cd0ab9 netwatch-dns: :do ... on-error=... -> :onerror ... do=... 2025-05-21 22:15:19 +02:00
Christian Hesse
fc1cde98f2 mod/ssh-keys-import: :do ... on-error=... -> ... well... - fix error condition 🥴 2025-05-21 22:14:22 +02:00
12 changed files with 96 additions and 67 deletions

View file

@ -42,7 +42,7 @@ Other actions (`disk`, `email`, `remote` or `support`) can be used as
well. I do not recommend using `echo` - use [debug output](#debug-output)
instead.
Disable or remote that setting to restore regular logging.
Disable or remove that setting to restore regular logging.
## Verbose output

View file

@ -114,8 +114,8 @@
:error true;
}
:if ($Address ~ "^[0-9a-zA-Z]*:[0-9a-zA-Z:\\.]+(/[0-9]{1,3})?\$") do={
:if ($Address ~ "/128\$") do={
:set Address [ :pick $Address 0 ([ :len $Address ] - 4) ];
:if ([ :typeof [ :find $Address "/" ] ] = "nil") do={
:set Address ($Address . "/128");
}
:set ($IPv6Addresses->$Branch->$Address) $TimeOut;
:error true;

View file

@ -25,6 +25,7 @@
:local Input $1;
:local Level (0 + [ :tonum $2 ]);
:global CharacterReplace;
:global IfThenElse;
:global InspectVarReturn;
@ -33,14 +34,13 @@
:local Value [ :tostr $2 ];
:local Level [ :tonum $3 ];
:local Indent "";
:for I from=1 to=$Level step=1 do={
:set Indent ($Indent . " ");
}
:return ($Indent . "-" . $Prefix . "-> " . $Value);
:global CharacterMultiply;
:return ([ $CharacterMultiply " " $Level ] . "-" . $Prefix . "-> " . $Value);
}
:local TypeOf [ :typeof $Input ];
:local Len [ :len $Input ];
:local Return [ $IndentReturn "type" $TypeOf $Level ];
:if ($TypeOf = "array") do={
@ -50,6 +50,16 @@
[ $InspectVarReturn $Value ($Level + 2) ]);
}
} else={
:if ($TypeOf = "str") do={
:set $Return ($Return . "\n" . \
[ $IndentReturn "len" $Len $Level ]);
:if ([ :typeof [ :find $Input ("\r") ] ] = "num") do={
:set Input [ $CharacterReplace $Input ("\r") "" ];
}
:if ([ :typeof [ :find $Input ("\n") ] ] = "num") do={
:set Input [ $CharacterReplace $Input ("\n") " " ];
}
}
:if ($TypeOf != "nothing") do={
:set $Return ($Return . "\n" . \
[ $IndentReturn "value" [ $IfThenElse ([ :len $Input ] > 80) \

View file

@ -89,35 +89,40 @@
:foreach Id,Message in=$EmailQueue do={
:if ([ :typeof $Message ] = "array" ) do={
:local Attach ({});
:while ([ /tool/e-mail/get last-status ] = "in-progress") do={ :delay 1s; }
:foreach File in=[ :toarray [ $EitherOr ($Message->"attach") "" ] ] do={
:if ([ :len [ /file/find where name=$File ] ] = 1) do={
:set Attach ($Attach, $File);
} else={
$LogPrint warning $0 ("File '" . $File . "' does not exist, can not attach.");
}
}
/tool/e-mail/send from=[ $EMailGenerateFrom ] to=($Message->"to") cc=($Message->"cc") \
subject=($Message->"subject") body=($Message->"body") file=$Attach;
:local Wait true;
:do {
:delay 1s;
:local Status [ /tool/e-mail/get last-status ];
:if ($Status = "succeeded") do={
:set ($EmailQueue->$Id);
:set Wait false;
:if (($Message->"remove-attach") = true) do={
:foreach File in=$Attach do={
/file/remove $File;
}
:onerror Err {
:local Attach ({});
:foreach File in=[ :toarray [ $EitherOr ($Message->"attach") "" ] ] do={
:if ([ :len [ /file/find where name=$File ] ] = 1) do={
:set Attach ($Attach, $File);
} else={
$LogPrint warning $0 ("File '" . $File . "' does not exist, can not attach.");
}
}
:if ($Status = "failed") do={
:set AllDone false;
:set Wait false;
}
} while=($Wait = true);
/tool/e-mail/send from=[ $EMailGenerateFrom ] to=($Message->"to") cc=($Message->"cc") \
subject=($Message->"subject") body=($Message->"body") file=$Attach;
:local Wait true;
:do {
:delay 1s;
:local Status [ /tool/e-mail/get last-status ];
:if ($Status = "succeeded") do={
:set ($EmailQueue->$Id);
:set Wait false;
:if (($Message->"remove-attach") = true) do={
:foreach File in=$Attach do={
/file/remove $File;
}
}
}
:if ($Status = "failed") do={
:set AllDone false;
:set Wait false;
}
} while=($Wait = true);
} do={
$LogPrint warning $0 ("Sending queued mail failed: " . $Err);
:set AllDone false;
}
}
}
@ -176,6 +181,7 @@
:global IfThenElse;
:global NotificationEMailSignature;
:global NotificationEMailSubject;
:global SymbolForNotification;
:local To [ $EitherOr ($EmailGeneralToOverride->($Notification->"origin")) $EmailGeneralTo ];
:local Cc [ $EitherOr ($EmailGeneralCcOverride->($Notification->"origin")) $EmailGeneralCc ];
@ -188,13 +194,23 @@
:if ([ :typeof $EmailQueue ] = "nothing") do={
:set EmailQueue ({});
}
:local Truncated false;
:local Body ($Notification->"message");
:if ([ :len $Body ] > 62000) do={
:set Body ([ :pick $Body 0 62000 ] . "...");
:set Truncated true;
}
:local Signature [ $EitherOr [ $NotificationEMailSignature ] [ /system/note/get note ] ];
:set Body ($Body . "\n" . \
[ $IfThenElse ([ :len ($Notification->"link") ] > 0) \
("\n" . [ $SymbolForNotification "link" ] . ($Notification->"link")) ] . \
[ $IfThenElse ($Truncated = true) ("\n" . [ $SymbolForNotification "scissors" ] . \
"The message was too long and has been truncated!") ] . \
[ $IfThenElse ([ :len $Signature ] > 0) ("\n-- \n" . $Signature) "" ]);
:set ($EmailQueue->[ :len $EmailQueue ]) {
to=$To; cc=$Cc;
subject=[ $NotificationEMailSubject ($Notification->"subject") ];
body=(($Notification->"message") . \
[ $IfThenElse ([ :len ($Notification->"link") ] > 0) ("\n\n" . ($Notification->"link")) "" ] . \
[ $IfThenElse ([ :len $Signature ] > 0) ("\n-- \n" . $Signature) "" ]); \
body=$Body; \
attach=($Notification->"attach"); remove-attach=($Notification->"remove-attach") };
:if ([ :len [ /system/scheduler/find where name="_FlushEmailQueue" ] ] = 0) do={
/system/scheduler/add name="_FlushEmailQueue" interval=1s start-time=startup \

View file

@ -189,7 +189,7 @@
:local HTTPData ("chat_id=" . $ChatId . "&disable_notification=" . ($Notification->"silent") . \
"&reply_to_message_id=" . ($Notification->"replyto") . "&message_thread_id=" . $ThreadId . \
"&disable_web_page_preview=true&parse_mode=MarkdownV2");
"&disable_web_page_preview=true&parse_mode=MarkdownV2");
:onerror Err {
:if ([ $CertificateAvailable "Go Daddy Root Certificate Authority - G2" ] = false) do={
$LogPrint warning $0 ("Downloading required certificate failed.");

View file

@ -94,9 +94,7 @@
:foreach KeyVal in=[ :deserialize $Keys delimiter=" " from=dsv options=dsv.plain ] do={
:local Continue false;
:if ($KeyVal->0 = "ssh-ed25519" || $KeyVal->0 = "ssh-rsa") do={
:do {
$SSHKeysImport ($KeyVal->0 . " " . $KeyVal->1 . " " . $KeyVal->2) $User;
} on-error={
:if ([ $SSHKeysImport ($KeyVal->0 . " " . $KeyVal->1 . " " . $KeyVal->2) $User ] = false) do={
$LogPrint warning $0 ("Failed importing key for user '" . $User . "'.");
}
:set Continue true;

View file

@ -118,15 +118,15 @@
}
:local Data false;
:do {
:onerror Err {
:set Data ([ /tool/fetch check-certificate=yes-without-crl output=user \
http-header-field=({ "accept: application/dns-message" }) \
url=(($DohServer->"doh-url") . "?dns=" . [ :convert to=base64 ([ :rndstr length=2 ] . \
"\01\00" . "\00\01" . "\00\00" . "\00\00" . "\00\00" . "\09doh-check\05eworm\02de\00" . \
"\00\10" . "\00\01") ]) as-value ]->"data");
} on-error={
$LogPrint warning $ScriptName ("Request to DoH server failed (network or certificate issue): " . \
($DohServer->"doh-url"));
} do={
$LogPrint warning $ScriptName ("Request to DoH server " . ($DohServer->"doh-url") . \
" failed: " . $Err);
}
:if ($Data != false) do={

View file

@ -38,10 +38,10 @@
:global ValidateSyntax;
:if ([ $ValidateSyntax $Hook ] = true) do={
:do {
onerror Err {
[ :parse $Hook ];
} on-error={
$LogPrint warning $ScriptName ("The " . $State . "-hook for " . $Type . " '" . $Name . "' failed to run.");
} do={
$LogPrint warning $ScriptName ("The " . $State . "-hook for " . $Type . " '" . $Name . "' failed to run: " . $Err);
:return ("The hook failed to run.");
}
} else={
@ -107,7 +107,7 @@
:if ([ :typeof ($HostInfo->"resolve") ] = "str") do={
:if ([ $IsDNSResolving ] = true) do={
:do {
:onerror Err {
:local Resolve [ :resolve type=[ $IfThenElse ([ :typeof ($HostVal->"host") ] = "ip") \
"ipv4" "ipv6" ] ($HostInfo->"resolve") ];
:if ($Resolve != $HostVal->"host") do={
@ -121,13 +121,13 @@
:set ($HostVal->"status") "unknown";
}
}
} on-error={
} do={
:set ($Metric->"resolve-failcnt") ($Metric->"resolve-failcnt" + 1);
:if ($Metric->"resolve-failcnt" = 3) do={
$LogPrint [ $IfThenElse ($HostInfo->"no-resolve-fail" != true) warning debug ] \
$ScriptName ("Resolving name '" . $HostInfo->"resolve" . [ $IfThenElse \
($HostInfo->"resolve" != $HostInfo->"name") ("' for " . $Type . " '" . \
$HostInfo->"name") "" ] . "' failed.");
$HostInfo->"name") "" ] . "' failed: " . $Err);
}
}
}

View file

@ -74,12 +74,12 @@
:if ($Phone~($Hook->"allowed-number") && ($SmsVal->"message")~($Hook->"match")) do={
:if ([ $ValidateSyntax ($Hook->"command") ] = true) do={
$LogPrint info $ScriptName ("Running hook '" . $Hook->"match" . "': " . $Hook->"command");
:do {
:onerror Err {
:local Command [ :parse ($Hook->"command") ];
$Command Phone=$Phone Message=($SmsVal->"message");
:set Messages ($Messages . "\n\nRan hook '" . $Hook->"match" . "':\n" . $Hook->"command");
} on-error={
$LogPrint warning $ScriptName ("The code for hook '" . $Hook->"match" . "' failed to run!");
} do={
$LogPrint warning $ScriptName ("The code for hook '" . $Hook->"match" . "' failed to run: " . $Err);
}
} else={
$LogPrint warning $ScriptName ("The code for hook '" . $Hook->"match" . "' failed syntax validation!");

View file

@ -33,6 +33,7 @@
:global GetRandom20CharAlNum;
:global IfThenElse;
:global LogPrint;
:global LogPrintVerbose;
:global MAX;
:global MIN;
:global MkDir;
@ -70,14 +71,14 @@
:local Data false;
:for I from=1 to=4 do={
:if ($Data = false) do={
:do {
:onerror Err {
:set Data ([ /tool/fetch check-certificate=yes-without-crl output=user \
("https://api.telegram.org/bot" . $TelegramTokenId . "/getUpdates?offset=" . \
$TelegramChatOffset->0 . "&allowed_updates=%5B%22message%22%5D") as-value ]->"data");
:set TelegramRandomDelay [ $MAX 0 ($TelegramRandomDelay - 1) ];
} on-error={
} do={
:if ($I < 4) do={
$LogPrint debug $ScriptName ("Fetch failed, " . $I . ". try.");
$LogPrint debug $ScriptName ("Fetch failed, " . $I . ". try: " . $Err);
:set TelegramRandomDelay [ $MIN 15 ($TelegramRandomDelay + 5) ];
:delay (($I * $I) . "s");
}
@ -96,6 +97,8 @@
:local Uptime [ /system/resource/get uptime ];
:foreach Update in=($JSON->"result") do={
:set UpdateID ($Update->"update_id");
$LogPrintVerbose debug $ScriptName ("Update " . $UpdateID . ": " . [ :serialize to=json $Update ]);
:local Message ($Update->"message");
:local IsReply ([ :typeof ($Message->"reply_to_message") ] = "string");
:local IsMyReply ($TelegramMessageIDs->[ :tostr ($Message->"reply_to_message"->"message_id") ]);
@ -107,7 +110,9 @@
:local ThreadId [ $IfThenElse ($Message->"is_topic_message") ($Message->"message_thread_id") "" ];
:foreach IdsTrusted in=($TelegramChatId, $TelegramChatIdsTrusted) do={
:if ($From->"id" = $IdsTrusted || $From->"username" = $IdsTrusted) do={
:if ($From->"id" = $IdsTrusted || \
$From->"username" = $IdsTrusted || \
$Chat->"id" = $IdsTrusted) do={
:set Trusted true;
}
}

View file

@ -12,10 +12,10 @@
:foreach Interface in=[ /interface/lte/find where running ] do={
:local Firmware;
:local IntName [ /interface/lte/get $Interface name ];
:do {
:onerror Err {
:set Firmware [ /interface/lte/firmware-upgrade $Interface as-value ];
} on-error={
:log debug ("Could not get latest LTE firmware version for interface " . $IntName . ".");
} do={
:log debug ("Could not get latest LTE firmware version for interface " . $IntName . ": " . $Err);
}
:if ([ :typeof $Firmware ] = "array") do={
@ -27,7 +27,7 @@
:set LTEFirmwareUpgrade;
/system/scheduler/remove ($1 . "-firmware-upgrade");
:do {
:onerror Err {
/interface/lte/firmware-upgrade $1 upgrade=yes;
:log info ("LTE firmware upgrade on '" . $1 . "' finished, waiting for reset.");
:delay 240s;
@ -36,8 +36,8 @@
($Firmware->"installed") != ($Firmware->"latest")) do={
:log warning ("LTE firmware versions still differ. Upgrade failed anyway?");
}
} on-error={
:log error ("LTE firmware upgrade on '" . $1 . "' failed.");
} do={
:log error ("LTE firmware upgrade on '" . $1 . "' failed: " . $Err);
}
}

View file

@ -41,12 +41,12 @@
:for I from=2 to=0 do={
:if ($Data = false) do={
:do {
:onerror Err {
:set Data ([ /tool/fetch check-certificate=yes-without-crl \
("https://ipv4.tunnelbroker.net/nic/update?hostname=" . $Comment->"id") \
user=($Comment->"user") password=($Comment->"pass") output=user as-value ]->"data");
} on-error={
$LogPrint debug $ScriptName ("Failed downloading, " . $I . " retries pending.");
} do={
$LogPrint debug $ScriptName ("Failed downloading: " . $Err . " - " . $I . " retries pending.");
:delay 2s;
}
}