diff --git a/doc/check-certificates.md b/doc/check-certificates.md index 5b1e3b2..aa4a258 100644 --- a/doc/check-certificates.md +++ b/doc/check-certificates.md @@ -22,8 +22,8 @@ Just install the script: Configuration ------------- -The expiry notifications just require notification settings for e-mail and -telegram. +The expiry notifications just require notification settings for e-mail, +matrix and/or telegram. For automatic download and renewal of certificates you need configuration in `global-config-overlay`, these are the parameters: diff --git a/doc/check-health.md b/doc/check-health.md index f1b9d91..de7f9eb 100644 --- a/doc/check-health.md +++ b/doc/check-health.md @@ -39,7 +39,7 @@ The configuration goes to `global-config-overlay`, These are the parameters: * `CheckHealthTemperature`: an array specifying temperature thresholds for sensors * `CheckHealthVoltagePercent`: percentage value to trigger voltage jumps -Also notification settings are required for e-mail and telegram. +Also notification settings are required for e-mail, matrix and/or telegram. --- [◀ Go back to main README](../README.md) diff --git a/doc/check-lte-firmware-upgrade.md b/doc/check-lte-firmware-upgrade.md index a145da8..dea6b82 100644 --- a/doc/check-lte-firmware-upgrade.md +++ b/doc/check-lte-firmware-upgrade.md @@ -31,7 +31,7 @@ Just install the script: Configuration ------------- -Notification setting are required for e-mail and telegram. +Notification setting are required for e-mail, matrix and/or telegram. See also -------- diff --git a/doc/cloud-backup.md b/doc/cloud-backup.md index 60e71c9..21d287f 100644 --- a/doc/cloud-backup.md +++ b/doc/cloud-backup.md @@ -26,7 +26,7 @@ The configuration goes to `global-config-overlay`, these are the parameters: * `BackupPassword`: password to encrypt the backup with * `BackupRandomDelay`: delay up to amount of seconds when run from scheduler -Also notification settings are required for e-mail and telegram. +Also notification settings are required for e-mail, matrix and/or telegram. Usage and invocation -------------------- diff --git a/doc/collect-wireless-mac.md b/doc/collect-wireless-mac.md index 4da06b9..8f3ff6f 100644 --- a/doc/collect-wireless-mac.md +++ b/doc/collect-wireless-mac.md @@ -36,7 +36,7 @@ On first run a disabled access list entry acting as marker (with comment "`--- collected above ---`") is added. Move this entry to define where new entries are to be added. -Also notification settings are required for e-mail and telegram. +Also notification settings are required for e-mail, matrix and/or telegram. Usage and invocation -------------------- diff --git a/doc/daily-psk.md b/doc/daily-psk.md index ec55c85..28f9afc 100644 --- a/doc/daily-psk.md +++ b/doc/daily-psk.md @@ -47,7 +47,7 @@ Then add an access list entry: / interface wireless access-list add comment="Daily PSK" interface=wl-daily private-pre-shared-key="ToBeChangedDaily"; -Also notification settings are required for e-mail and telegram. +Also notification settings are required for e-mail, matrix and/or telegram. --- [◀ Go back to main README](../README.md) diff --git a/doc/log-forward.md b/doc/log-forward.md index 0993b52..68a6ca1 100644 --- a/doc/log-forward.md +++ b/doc/log-forward.md @@ -39,7 +39,7 @@ The configuration goes to `global-config-overlay`, these are the parameters: * `LogForwardFilter`: define topics *not* to be forwarded * `LogForwardFilterMessage`: define message text *not* to be forwarded -Also notification settings are required for e-mail and telegram. +Also notification settings are required for e-mail, matrix and/or telegram. --- [◀ Go back to main README](../README.md) diff --git a/doc/netwatch-notify.md b/doc/netwatch-notify.md index ff1eae9..2bba8d9 100644 --- a/doc/netwatch-notify.md +++ b/doc/netwatch-notify.md @@ -61,7 +61,7 @@ But be warned: Dynamic updates will probably cause issues if the name has more than one record in dns - a high rate of configuration changes (and flash writes) at least. -Also notification settings are required for e-mail and telegram. +Also notification settings are required for e-mail, matrix and/or telegram. Tips & Tricks ------------- diff --git a/doc/sms-forward.md b/doc/sms-forward.md index d603daa..69ea5d0 100644 --- a/doc/sms-forward.md +++ b/doc/sms-forward.md @@ -27,8 +27,8 @@ Just install the script: Configuration ------------- -Notification settings are required for e-mail and telegram. Also you have -to enable receiving of SMS: +Notification settings are required for e-mail, matrix and/or telegram. Also +you have to enable receiving of SMS: / tool sms set receive-enabled=yes; diff --git a/doc/upload-backup.md b/doc/upload-backup.md index 4b656e4..f9a9b4f 100644 --- a/doc/upload-backup.md +++ b/doc/upload-backup.md @@ -32,7 +32,7 @@ The configuration goes to `global-config-overlay`, these are the parameters: * `BackupUploadUser`: username for server authentication * `BackupUploadPass`: password for server authentication -Also notification settings are required for e-mail and telegram. +Also notification settings are required for e-mail, matrix and/or telegram. ### Issues with SFTP client diff --git a/global-config b/global-config index 6730a45..19d1215 100644 --- a/global-config +++ b/global-config @@ -8,7 +8,7 @@ # Make sure all configuration properties are up to date and this # value is in sync with value in script 'global-functions'! -:global GlobalConfigVersion 52; +:global GlobalConfigVersion 53; # This is used for DNS and backup file. :global Domain "example.com"; @@ -33,9 +33,19 @@ # This is whether or not to send Telegram messages with fixed-width font. :global TelegramFixedWidthFont true; -# It is possible to override e-mail and Telegram setting for every script. -# This is done in arrays EmailGeneralToOverride, EmailGeneralCcOverride, -# TelegramTokenIdOverride and TelegramChatIdOverride like this: +# You can send Matrix notifications. Configure these settings and +# install the module: +# $ScriptInstallUpdate global-functions.d/notification-matrix +:global MatrixHomeServer ""; +:global MatrixAccessToken ""; +:global MatrixRoom ""; +#:global MatrixHomeServer "matrix.org"; +#:global MatrixAccessToken "123456ABCDEFGHI..."; +#:global MatrixRoom "!example:matrix.org"; + +# It is possible to override e-mail, Telegram and Matrix setting for every +# script. This is done in arrays, where 'Override' is appended to the +# variable name, like this: #:global EmailGeneralToOverride { # "check-certificates"="override@example.com"; # "email-backup"="backup@example.com"; diff --git a/global-config-overlay b/global-config-overlay index f90abd6..1cbaedf 100644 --- a/global-config-overlay +++ b/global-config-overlay @@ -8,7 +8,7 @@ # Make sure all configuration properties are up to date and this # value is in sync with value in script 'global-functions'! # Comment or remove to disable news and change notifications. -:global GlobalConfigVersion 52; +:global GlobalConfigVersion 53; # Copy configuration from global-config here and modify it. diff --git a/global-config.changes b/global-config.changes index cfaf649..21d4941 100644 --- a/global-config.changes +++ b/global-config.changes @@ -56,6 +56,7 @@ 50="Added support for dynamic address update in 'netwatch-notify'."; 51="Added 'ipsec-to-dns' to add DNS records for IPSec peers from mode-config."; 52="Updated Let's Encrypt trust chain to use root certificate 'ISRG Root X1'. Do not re-import the old chain!"; + 53="Added support to send notifications via Matrix."; }; # Migration steps to be applied on script updates diff --git a/global-functions b/global-functions index 5ceab4f..b3db3dd 100644 --- a/global-functions +++ b/global-functions @@ -8,7 +8,7 @@ # https://git.eworm.de/cgit/routeros-scripts/about/ # expected configuration version -:global ExpectedConfigVersion 52; +:global ExpectedConfigVersion 53; # global variables not to be changed by user :global GlobalFunctionsReady false; diff --git a/global-functions.d/notification-matrix b/global-functions.d/notification-matrix new file mode 100644 index 0000000..962924e --- /dev/null +++ b/global-functions.d/notification-matrix @@ -0,0 +1,157 @@ +#!rsc by RouterOS +# RouterOS script: global-functions.d/notification-matrix +# Copyright (c) 2013-2021 Michael Gisbers +# Christian Hesse +# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md + +:global FlushMatrixQueue; +:global NotificationFunctions; +:global SendMatrix; +:global SendMatrix2; + +# flush Matrix queue +:set FlushMatrixQueue do={ + :global MatrixQueue; + + :global LogPrintExit2; + + :local AllDone true; + :local QueueLen [ :len $MatrixQueue ]; + + :if ([ :len [ / system scheduler find where name="FlushMatrixQueue" ] ] > 0 && $QueueLen = 0) do={ + $LogPrintExit2 warning $0 ("Flushing Matrix messages from scheduler, but queue is empty.") false; + } + + :foreach Id,Message in=$MatrixQueue do={ + :if ([ :typeof $Message ] = "array" ) do={ + :do { + / tool fetch check-certificate=yes-without-crl output=none http-method=post \ + ("https://" . $Message->"homeserver" . "/_matrix/client/r0/rooms/" . $Message->"room" . \ + "/send/m.room.message?access_token=" . $Message->"accesstoken") \ + http-data=("{ \"msgtype\": \"m.text\", \"body\": \"" . $Message->"plain" . "\"," . \ + "\"format\": \"org.matrix.custom.html\", \"formatted_body\": \"" . \ + $Message->"formatted" . "\" }") as-value; + :set ($MatrixQueue->$Id); + } on-error={ + $LogPrintExit2 debug $0 ("Sending queued Matrix message failed.") false; + :set AllDone false; + } + } + } + + :if ($AllDone = true && $QueueLen = [ :len $MatrixQueue ]) do={ + / system scheduler remove [ find where name="FlushMatrixQueue" ]; + :set MatrixQueue; + } +} + +# send notification via Matrix - expects one array argument +:set ($NotificationFunctions->"matrix") do={ + :local Notification $1; + + :global Identity; + :global MatrixAccessToken; + :global MatrixAccessTokenOverride; + :global MatrixHomeServer; + :global MatrixHomeServerOverride; + :global MatrixQueue; + :global MatrixRoom; + :global MatrixRoomOverride; + + :global EitherOr; + :global LogPrintExit2; + :global SymbolForNotification; + + :local PrepareText do={ + :local Input [ :tostr $1 ]; + + :if ([ :len $Input ] = 0) do={ + :return ""; + } + + :local Return ""; + :local Chars { + "plain"={ "\\"; "\""; "\n" }; + "format"={ "\\"; "\""; "\n"; "&"; "<"; ">" }; + } + :local Subs { + "plain"={ "\\\\"; "\\\""; "\\n" }; + "format"={ "\\\\"; """; "
"; "&"; "<"; ">" }; + } + + :for I from=0 to=([ :len $Input ] - 1) do={ + :local Char [ :pick $Input $I ]; + :local Replace [ :find ($Chars->$2) $Char ]; + + :if ([ :typeof $Replace ] = "num") do={ + :set Char ($Subs->$2->$Replace); + } + :set Return ($Return . $Char); + } + + :return $Return; + } + + :local AccessToken [ $EitherOr ($MatrixAccessTokenOverride->($Notification->"origin")) $MatrixAccessToken ]; + :local HomeServer [ $EitherOr ($MatrixHomeServerOverride->($Notification->"origin")) $MatrixHomeServer ]; + :local Room [ $EitherOr ($MatrixRoomOverride->($Notification->"origin")) $MatrixRoom ]; + + :if ([ :len $AccessToken ] = 0 || [ :len $HomeServer ] = 0 || [ :len $Room ] = 0) do={ + :return false; + } + + :local Plain [ $PrepareText ("## [" . $Identity . "] " . ($Notification->"subject") . "\n```\n" . \ + ($Notification->"message") . "\n```") "plain" ]; + :local Formatted ("

" . [ $PrepareText ("[" . $Identity . "] " . ($Notification->"subject")) "format" ] . "

" . \ + "
" . [ $PrepareText ($Notification->"message") "format" ] . "
"); + :if ([ :len ($Notification->"link") ] > 0) do={ + :set Plain ($Plain . "\\n" . [ $SymbolForNotification "link" ] . \ + [ $PrepareText ("[" . $Notification->"link" . "](" . $Notification->"link" . ")") "plain" ]); + :set Formatted ($Formatted . "
" . [ $SymbolForNotification "link" ] . \ + ""link") "format" ] . "\\\">" . \ + [ $PrepareText ($Notification->"link") "format" ] . ""); + } + + :do { + / tool fetch check-certificate=yes-without-crl output=none http-method=post \ + ("https://" . $HomeServer . "/_matrix/client/r0/rooms/" . $Room . \ + "/send/m.room.message?access_token=" . $AccessToken) \ + http-data=("{ \"msgtype\": \"m.text\", \"body\": \"" . $Plain . "\"," . \ + "\"format\": \"org.matrix.custom.html\", \"formatted_body\": \"" . \ + $Formatted . "\" }") as-value; + } on-error={ + $LogPrintExit2 info $0 ("Failed sending Matrix notification! Queuing...") false; + + :if ([ :typeof $MatrixQueue ] = "nothing") do={ + :set MatrixQueue [ :toarray "" ]; + } + :local Text ([ $SymbolForNotification "alarm-clock" ] . \ + "This message was queued since " . [ / system clock get date ] . \ + " " . [ / system clock get time ] . " and may be obsolete."); + :set Plain ($Plain . "\\n" . $Text); + :set Formatted ($Formatted . "
" . $Text); + :set ($MatrixQueue->[ :len $MatrixQueue ]) { room=$Room; \ + accesstoken=$AccessToken; homeserver=$HomeServer; \ + plain=$Plain; formatted=$Formatted }; + :if ([ :len [ / system scheduler find where name="FlushMatrixQueue" ] ] = 0) do={ + / system scheduler add name=FlushMatrixQueue interval=1m start-time=startup \ + on-event=":global FlushMatrixQueue; \$FlushMatrixQueue;"; + } + } +} + +# send notification via Matrix - expects at lease two string arguments +:set SendMatrix do={ + :global SendMatrix2; + + $SendMatrix2 ({ subject=$1; message=$2; link=$3 }); +} + +# send notification via Matrix - expects one array argument +:set SendMatrix2 do={ + :local Notification $1; + + :global NotificationFunctions; + + ($NotificationFunctions->"matrix") ("\$NotificationFunctions->\"matrix\"") $Notification; +}