diff options
Diffstat (limited to 'mod/notification-email.rsc')
| -rw-r--r-- | mod/notification-email.rsc | 137 | 
1 files changed, 92 insertions, 45 deletions
| diff --git a/mod/notification-email.rsc b/mod/notification-email.rsc index 0d83d69..7c3a6ff 100644 --- a/mod/notification-email.rsc +++ b/mod/notification-email.rsc @@ -1,12 +1,13 @@  #!rsc by RouterOS  # RouterOS script: mod/notification-email -# Copyright (c) 2013-2024 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.12 +# 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; @@ -34,20 +35,39 @@  }  # flush e-mail queue -:set FlushEmailQueue do={ +:set FlushEmailQueue do={ :onerror Err {    :global EmailQueue;    :global EitherOr;    :global EMailGenerateFrom; +  :global FileExists;    :global IsDNSResolving;    :global IsTimeSync;    :global LogPrint; +  :global RmFile;    :local AllDone true;    :local QueueLen [ :len $EmailQueue ];    :local Scheduler [ /system/scheduler/find where name="_FlushEmailQueue" ]; -  :if ([ :len $Scheduler ] > 0 && [ /system/scheduler/get $Scheduler interval ] < 1m) do={ +  :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;    } @@ -67,53 +87,67 @@      :return false;    } -  :if ([ :len $Scheduler ] > 0 && $QueueLen = 0) do={ -    $LogPrint warning $0 ("Flushing E-Mail messages from scheduler, but queue is empty."); -  } - -  /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={ -      :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."); +      :onerror Err { +        :local Attach ({}); +        :foreach File in=[ :toarray [ $EitherOr ($Message->"attach") "" ] ] do={ +          :if ([ $FileExists $File ] = true) 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; +        :do { +          /tool/e-mail/send from=[ $EMailGenerateFrom ] to=($Message->"to") \ +              cc=($Message->"cc") subject=($Message->"subject") \ +              body=($Message->"body") file=$Attach; +        } on-error={ } +        :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={ +                $RmFile $File; +              }              }            } -        } -        :if ($Status = "failed") do={ -          :set AllDone false; -          :set Wait false; -        } -      } while=($Wait = true); +          :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; +      }      }    }    :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; +} do={ +  :global ExitError; $ExitError false $0 $Err; +} }  # generate filter for log-forward  :set LogForwardFilterLogForwarding do={ @@ -152,6 +186,7 @@    :global IfThenElse;    :global NotificationEMailSignature;    :global NotificationEMailSubject; +  :global SymbolForNotification;    :local To [ $EitherOr ($EmailGeneralToOverride->($Notification->"origin")) $EmailGeneralTo ];    :local Cc [ $EitherOr ($EmailGeneralCcOverride->($Notification->"origin")) $EmailGeneralCc ]; @@ -164,13 +199,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 \ @@ -224,11 +269,13 @@  }  # send notification via e-mail - expects at least two string arguments -:set SendEMail do={ +:set SendEMail do={ :onerror Err {    :global SendEMail2; -  $SendEMail2 ({ subject=$1; message=$2; link=$3 }); -} +  $SendEMail2 ({ origin=$0; subject=$1; message=$2; link=$3 }); +} do={ +  :global ExitError; $ExitError false $0 $Err; +} }  # send notification via e-mail - expects one array argument  :set SendEMail2 do={ |