diff options
Diffstat (limited to 'mod/notification-email.rsc')
-rw-r--r-- | mod/notification-email.rsc | 130 |
1 files changed, 89 insertions, 41 deletions
diff --git a/mod/notification-email.rsc b/mod/notification-email.rsc index e266201..7b89d98 100644 --- a/mod/notification-email.rsc +++ b/mod/notification-email.rsc @@ -1,11 +1,15 @@ #!rsc by RouterOS # RouterOS script: mod/notification-email -# Copyright (c) 2013-2023 Christian Hesse <mail@eworm.de> -# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md +# Copyright (c) 2013-2025 Christian Hesse <mail@eworm.de> +# https://rsc.eworm.de/COPYING.md +# +# requires RouterOS, version=7.15 +# requires device-mode, email, scheduler # # send notifications via e-mail -# https://git.eworm.de/cgit/routeros-scripts/about/doc/mod/notification-email.md +# https://rsc.eworm.de/doc/mod/notification-email.md +:global EMailGenerateFrom; :global FlushEmailQueue; :global LogForwardFilterLogForwarding; :global NotificationEMailSubject; @@ -15,43 +19,73 @@ :global SendEMail; :global SendEMail2; +# generate from-property with display name +:set EMailGenerateFrom do={ + :global Identity; + + :global CleanName; + + :local From [ /tool/e-mail/get from ]; + + :if ($From ~ "<.*>\$") do={ + :return $From; + } + + :return ([ $CleanName $Identity ] . " via routeros-scripts <" . $From . ">"); +} + # flush e-mail queue -:set FlushEmailQueue do={ +:set FlushEmailQueue do={ :do { :global EmailQueue; :global EitherOr; + :global EMailGenerateFrom; :global IsDNSResolving; :global IsTimeSync; - :global LogPrintExit2; + :global LogPrint; :local AllDone true; :local QueueLen [ :len $EmailQueue ]; - :local Scheduler [ /system/scheduler/find where name=$0 ]; - - :if ([ :len $Scheduler ] > 0 && [ /system/scheduler/get $Scheduler interval ] < 1m) do={ + :local Scheduler [ /system/scheduler/find where name="_FlushEmailQueue" ]; + + :if ([ :len $Scheduler ] > 0 && $QueueLen = 0) do={ + $LogPrint warning $0 ("Flushing E-Mail messages from scheduler, but queue is empty."); + /system/scheduler/remove $Scheduler; + :return false; + } + + :if ($QueueLen = 0) do={ + :return true; + } + + :if ([ :len $Scheduler ] < 0) do={ + /system/scheduler/add name="_FlushEmailQueue" interval=1m start-time=startup \ + comment="Doing initial checks..." on-event=(":global FlushEmailQueue; \$FlushEmailQueue;"); + :set Scheduler [ /system/scheduler/find where name="_FlushEmailQueue" ]; + } + + :local SchedVal [ /system/scheduler/get $Scheduler ]; + :if (($SchedVal->"interval") < 1m) do={ /system/scheduler/set interval=1m comment="Doing initial checks..." $Scheduler; } :if ([ /tool/e-mail/get last-status ] = "in-progress") do={ - $LogPrintExit2 debug $0 ("Sending mail is currently in progress, not flushing.") false; + $LogPrint debug $0 ("Sending mail is currently in progress, not flushing."); :return false; } :if ([ $IsTimeSync ] = false) do={ - $LogPrintExit2 debug $0 ("Time is not synced, not flushing.") false; + $LogPrint debug $0 ("Time is not synced, not flushing."); :return false; } - :if ([ :typeof [ :toip [ /tool/e-mail/get address ] ] ] != "ip" && [ $IsDNSResolving ] = false) do={ - $LogPrintExit2 debug $0 ("Server address is a DNS name and resolving fails, not flushing.") false; + :local EMailSettings [ /tool/e-mail/get ]; + :if ([ :typeof [ :toip ($EMailSettings->"server") ] ] != "ip" && [ $IsDNSResolving ] = false) do={ + $LogPrint debug $0 ("Server address is a DNS name and resolving fails, not flushing."); :return false; } - :if ([ :len $Scheduler ] > 0 && $QueueLen = 0) do={ - $LogPrintExit2 warning $0 ("Flushing E-Mail messages from scheduler, but queue is empty.") false; - } - - /system/scheduler/set interval=([ $EitherOr $QueueLen 1 ] . "m") comment="Sending..." $Scheduler; + /system/scheduler/set interval=($QueueLen . "m") comment="Sending..." $Scheduler; :foreach Id,Message in=$EmailQueue do={ :if ([ :typeof $Message ] = "array" ) do={ @@ -61,11 +95,11 @@ :if ([ :len [ /file/find where name=$File ] ] = 1) do={ :set Attach ($Attach, $File); } else={ - $LogPrintExit2 warning $0 ("File '" . $File . "' does not exist, can not attach.") false; + $LogPrint warning $0 ("File '" . $File . "' does not exist, can not attach."); } } - /tool/e-mail/send to=($Message->"to") cc=($Message->"cc") subject=($Message->"subject") \ - body=($Message->"body") file=$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; @@ -90,10 +124,20 @@ :if ($AllDone = true && $QueueLen = [ :len $EmailQueue ]) do={ /system/scheduler/remove $Scheduler; :set EmailQueue; - } else={ - /system/scheduler/set interval=1m comment="Waiting for retry..." $Scheduler; + :return true; } -} + + :if ([ :len [ /system/scheduler/find where name="_FlushEmailQueue" ] ] = 0 && \ + [ :typeof $EmailQueue ] = "nothing") do={ + $LogPrint info $0 ("Queue was purged? Exiting."); + :return false; + } + + /system/scheduler/set interval=(($SchedVal->"run-count") . "m") \ + comment="Waiting for retry..." $Scheduler; +} on-error={ + :global ExitError; $ExitError false $0; +} } # generate filter for log-forward :set LogForwardFilterLogForwarding do={ @@ -130,20 +174,21 @@ :global EitherOr; :global IfThenElse; + :global NotificationEMailSignature; :global NotificationEMailSubject; :local To [ $EitherOr ($EmailGeneralToOverride->($Notification->"origin")) $EmailGeneralTo ]; :local Cc [ $EitherOr ($EmailGeneralCcOverride->($Notification->"origin")) $EmailGeneralCc ]; :local EMailSettings [ /tool/e-mail/get ]; - :if ([ :len $To ] = 0 || ($EMailSettings->"address") = "0.0.0.0" || ($EMailSettings->"from") = "<>") do={ + :if ([ :len $To ] = 0 || ($EMailSettings->"server") = "0.0.0.0" || ($EMailSettings->"from") = "<>") do={ :return false; } :if ([ :typeof $EmailQueue ] = "nothing") do={ :set EmailQueue ({}); } - :local Signature [ /system/note/get note ]; + :local Signature [ $EitherOr [ $NotificationEMailSignature ] [ /system/note/get note ] ]; :set ($EmailQueue->[ :len $EmailQueue ]) { to=$To; cc=$Cc; subject=[ $NotificationEMailSubject ($Notification->"subject") ]; @@ -151,8 +196,8 @@ [ $IfThenElse ([ :len ($Notification->"link") ] > 0) ("\n\n" . ($Notification->"link")) "" ] . \ [ $IfThenElse ([ :len $Signature ] > 0) ("\n-- \n" . $Signature) "" ]); \ 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 \ + :if ([ :len [ /system/scheduler/find where name="_FlushEmailQueue" ] ] = 0) do={ + /system/scheduler/add name="_FlushEmailQueue" interval=1s start-time=startup \ comment="Queuing new mail..." on-event=(":global FlushEmailQueue; \$FlushEmailQueue;"); } } @@ -161,7 +206,7 @@ :set PurgeEMailQueue do={ :global EmailQueue; - /system/scheduler/remove [ find where name="\$FlushEmailQueue" ]; + /system/scheduler/remove [ find where name="_FlushEmailQueue" ]; :set EmailQueue; } @@ -169,27 +214,28 @@ :global QuotedPrintable do={ :local Input [ :tostr $1 ]; + :global CharacterMultiply; + :if ([ :len $Input ] = 0) do={ :return $Input; } :local Return ""; - :local Chars ("\80\81\82\83\84\85\86\87\88\89\8A\8B\8C\8D\8E\8F\90\91\92\93\94\95\96\97" . \ - "\98\99\9A\9B\9C\9D\9E\9F\A0\A1\A2\A3\A4\A5\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3" . \ - "\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\C0\C1\C2\C3\C4\C5\C6\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"); - :local Hex { "0"; "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; "9"; "A"; "B"; "C"; "D"; "E"; "F" }; + :local Chars ( \ + "\00\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" . \ + [ $CharacterMultiply ("\00") 29 ] . "=\00?" . [ $CharacterMultiply ("\00") 63 ] . "\7F" . \ + "\80\81\82\83\84\85\86\87\88\89\8A\8B\8C\8D\8E\8F\90\91\92\93\94\95\96\97\98\99\9A\9B\9C\9D\9E\9F" . \ + "\A0\A1\A2\A3\A4\A5\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF" . \ + "\C0\C1\C2\C3\C4\C5\C6\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"); + :local Hex "0123456789ABCDEF"; :for I from=0 to=([ :len $Input ] - 1) do={ :local Char [ :pick $Input $I ]; :local Replace [ :find $Chars $Char ]; - :if ($Char = "=") do={ - :set Char "=3D"; - } :if ([ :typeof $Replace ] = "num") do={ - :set Char ("=" . ($Hex->($Replace / 16 + 8)) . ($Hex->($Replace % 16))); + :set Char ("=" . [ :pick $Hex ($Replace / 16)] . [ :pick $Hex ($Replace % 16) ]); } :set Return ($Return . $Char); } @@ -202,11 +248,13 @@ } # send notification via e-mail - expects at least two string arguments -:set SendEMail do={ +:set SendEMail do={ :do { :global SendEMail2; - $SendEMail2 ({ subject=$1; message=$2; link=$3 }); -} + $SendEMail2 ({ origin=$0; subject=$1; message=$2; link=$3 }); +} on-error={ + :global ExitError; $ExitError false $0; +} } # send notification via e-mail - expects one array argument :set SendEMail2 do={ |