Skip to content

Instantly share code, notes, and snippets.

@leporel
Last active September 25, 2024 04:26
Show Gist options
  • Select an option

  • Save leporel/b899d23d299ecfee684ceafef2443c87 to your computer and use it in GitHub Desktop.

Select an option

Save leporel/b899d23d299ecfee684ceafef2443c87 to your computer and use it in GitHub Desktop.
Mikrotik script notification

Mikrotik script for logs notifications/alert script via Telegram, ROS 7
Change "BotToken", "MyID"

:local BotToken "Token"
:local MyID "UserID"

:local findPosix do={
    :local string [:tostr $1];
    :local posix $2;
    :local posix0 $posix;
    :local fstart [:tonum $3];
    :local fend 0;
    :if ($fstart < 0) do={ :set fstart 0 };
    :local  substr [:pick $string $fstart [:len $string]];
    :if ([:len $string] > 0 && [:len $posix] > 0 && $fstart <[:len $string] && ($substr ~ $posix)) do={
        :while ($fstart < [:len $string]) do={
            :set posix $posix0;
            :if ([:pick $posix 0] != "^") do={
                :set posix ("^".$posix);
                :local continue true;
                :while ($continue && $fstart < [:len $string]) do={
                    :if ([:pick $string $fstart [:len $string]] ~ $posix) do={
                        :set continue false;
                    } else={:set fstart ($fstart + 1);};
                }
            } 
            :if ($fstart < [:len $string]) do={
                :if ([:pick $posix ([:len $posix] -1)] != "\$") do={
                    :set posix ($posix."\$");
                    :local continue true;
                    :set fend [:len $string];
                    :while ($fend > $fstart && $continue) do={
                        :if ([:pick $string $fstart $fend] ~ $posix) do={:set continue false} else={:set fend ($fend - 1)}; 
                    }
                } else={:set fend [:len $string];}
            } 
            :if ($fend > $fstart) do={:return {[:pick $string $fstart $fend] ; $fstart ;$fend};};
            :set fstart ($fstart +1);
            :set fend 0;
            :put "Unidentified error";
        }
    }
    :return {[]; []; []};
};

:local date [system clock get date]
:local currentTime [system clock get time]
:local logs
:local logAll [:toarray [log find]]
:local logCnt [ :len $logAll ];

:local index 0;
:local timeLog;
:global lastTimeLog;
:local lastTime;
:local today true

if ([:len $lastTimeLog] < 1) do={ 
    :log info ("<extra-log> Time of the last log entry was not found. Set to -1m");
     # GMT time=+02:00
     # :local currentTimeStamp [:totime ([:timestamp]+2h)]
     :local currentTimeStamp [ :totime [  ([:timestamp] + ([system clock get gmt-offset] . "s") )] ]
    :set lastTimeLog ($currentTimeStamp-1m);
}

:do {
    :set index ($index + 1);
    :local currentLog [:pick $logAll ($logCnt - $index)] 
    :local htime [log get $currentLog time]

    if ([:len $htime] > 8) do={
            if ([:len $htime] > 14) do={
                # previous year
                :set timeLog ([ :totime ($htime) ]);
            } else={
                # yesterday
                :set timeLog ([ :totime ([:pick [$date] 0 4] . "-" . $htime) ]);
            }
        } else={
            # today
            # if block for fix when next day after 00:00:00 and recieve log with time only
            :if ( ($htime <= $currentTime) && $today) do={
                :set timeLog ([ :totime ($date . " " . $htime) ]);
            } else={ :set today false; :set timeLog; } 
    }
        
    :if ( $timeLog > $lastTimeLog ) do={
        :set logs ($logs, $currentLog)
    }
    
    if ( ($index = 1) || ( ([:len $lastTime] < 1) && ([:len $timeLog] > 12) ) ) do={
     :set lastTime $timeLog;
    }

} while=((([:len $timeLog] < 1) || ($timeLog > $lastTimeLog)) && ($index < $logCnt));

:if (([:len $lastTime] > 12) && ($lastTime > $lastTimeLog))  do={
   :set lastTimeLog $lastTime;
}

:if ([:len $logs] > 0 ) do={
:local TelegramMsg
:local Msgcounter 0
:local finded false
:local mac
:local comment
:local hostname
    :for index from=([:len $logs]-1) to=0 step=-1 do={
        :local i [:pick $logs $index ]
        :local imessage [log get $i message]
        :local topics [log get $i topics]
        :local processLogs false;
    
        :if ( ($topics ~"critical") || ($topics ~"error")  || ($topics ~"warning") ) do={   
            :set processLogs true;  
        } else= {       
            :if ( ($topics ~"info") && \
            ($imessage ~"banned" || \
            $imessage ~"login failure" || \
            $imessage ~"authentication failed" || \
            $imessage ~">: connected" || \
            $imessage ~"logged in"  || \
            $imessage ~"changed" || \
            $imessage ~"<extra-log>") ) do={
                :set processLogs true;  
            }
        }
        
        #Skip flood messages
        :if ( $imessage ~"unknown msg!" || \
        $imessage ~"msg too short") do={
            :set processLogs false; 
        }
                
        :if ( $processLogs = true ) do={
            :set finded false
            :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={
                :if ($finded = false) do={
                    :foreach k in=[ip dhcp-server lease find] do={
                        :set mac [ip dhcp-server lease get $k value-name=mac-address]
                        :if ($imessage ~ "$mac") do={
                            :set comment [ip dhcp-server lease get $k value-name=comment]
                            :set hostname [ip dhcp-server lease get $k value-name=host-name]
                            :if ($comment != "" || $hostname != "") do={
                                :set imessage ($imessage . " / " . $hostname . " / " . $comment)
                                :set finded true
                            }
                        }
                    }
                }
                :if ($finded = false) do={
                    :foreach h in=[ip hotspot ip-binding find] do={
                        :set mac [ip hotspot ip-binding get $h value-name=mac-address]
                        :if ($imessage ~ "$mac") do={
                            :set comment [ip hotspot ip-binding get $h value-name=comment]
                            :if ($comment != "") do={
                                :set imessage ($imessage . " / " . $comment)
                                :set finded true
                            }
                        }
                    }
                }
                :if ($finded = false) do={
                    :foreach w in=[interface wifi access-list find] do={
                        :set mac [interface wifi access-list get $w value-name=mac-address]
                        :if ($imessage ~ "$mac") do={
                            :set comment [interface wifi access-list get $w value-name=comment]
                            :if ($comment != "") do={
                                :set imessage ($imessage . " / " . $comment)
                                :set finded true
                            }
                        }
                    }
                }                   
            }
            
            :local logTime [ log get $i time ]
            :local trueLogTime ([:pick $date 0 11]." ". $logTime )    
            
            if ([:len $logTime] > 8) do={
                :set trueLogTime $logTime
            }       
  
            :set Msgcounter ($Msgcounter + 1)
            if ($Msgcounter < 16 ) do={
                #Only First 15 Logs For Telegram

                # Strip message length
                :if ([:len $imessage] > 130) do={
                 :set imessage [:pick $imessage 0 130]
                }

                :local emojiIcon ""
                
                if ( $topics ~"critical" ) do={
                    :set emojiIcon "\E2\98\A0\EF\B8\8F"
                }
                if ( $topics ~"error" ) do={
                    :set emojiIcon "\F0\9F\94\A5"
                }
                if ( $topics ~"warning" ) do={
                    :set emojiIcon "\E2\9D\97"
                }
                if ( $topics ~"info" ) do={
                    :set emojiIcon "\E2\9D\95"
                }

                :set TelegramMsg ($TelegramMsg.$trueLogTime." - " . $emojiIcon . " - ".$imessage."%0A%0A")
            }
        }
    }
    :if ([:len $TelegramMsg] > 0 ) do={ 
          # Hide IP's from log
          :local regex "[0-2]\?[0-9]\?[0-9]\?[.][0-2]\?[0-9]\?[0-9]\?[.][0-2]\?[0-9]\?[0-9]\?[.][0-2]\?[0-9]\?[0-9]\?";
          :local startPosition 0;
          :local ArrRezult {"";"";""}; 

          :do {
            :set ArrRezult [$findPosix $TelegramMsg $regex $startPosition];
            :if ([:len [:pick $ArrRezult 0]] > 0) do={
                :local subStart [:pick $ArrRezult 1];
                :local subEnd [:pick $ArrRezult 2];
                :local ipaddress [:put ([:pick $ArrRezult 0]|0.0.255.255)];
                :if ($ipaddress != "192.168.255.255") do={
                    :set ipaddress ([:pick $ipaddress 0  [:find $ipaddress "255.255"]] . "***.***" )
                    :set TelegramMsg ([:pick $TelegramMsg 0 $subStart] . $ipaddress . [:pick $TelegramMsg $subEnd [:len $TelegramMsg]]);
                }
                :set startPosition ($subEnd);
            }
          } while ([:len [:pick $ArrRezult 0]] > 0)


        :local TelMsgFix
        :local achar
          :set TelegramMsg ("[\F0\9F\94\94]%20Logs%20Monitor%20Alert%20:%0A".$TelegramMsg)
             # Replace " " With "%20" For Telegram String        
            :if ([:find $TelegramMsg " " -1] > 0) do={
            set achar ""
            set TelMsgFix ""
             :for i from=0 to=([:len $TelegramMsg] -1) step=1 do={
                :set achar value=[:pick $TelegramMsg $i]
                :if ($achar = " ") do={ :set achar value="%20" }
                :set TelMsgFix value=($TelMsgFix.$achar)
             }
            } else={:set TelMsgFix value=($TelegramMsg)}            
         :do {
           tool fetch url="https://api.telegram.org/bot$BotToken/sendmessage?chat_id=$MyID&text=$TelMsgFix" mode=https keep-result=no 
           log info "[LOGMON] Telegram message Sended."
          } on-error={
           log error "[LOGMON] Failed to send Telegram message.";
          } 
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment