logEventTGInformer | by xdenb43
Sends log events filtered by condition(s) to specific topic of telegram super-group
UPDATE HISTORY:
15.05.2026 version 2:
---- switch from unstable markdown to html format
---- improve logic
---- tested on RoS 7.22.3
- Created to post messages to dedicated topic of the specified supergroup telegram instance
- Default filtering conditions:
topics~"(error|critical|netwatch)" || message~"([fF]ailure|router rebooted|checkOSUpdate)" - NO time-format related troubles, mikrotik internal function totime used
- Executes every
60seconds - Uses limit to
4096message symbols
- Adds scheduler automatically with the first manual execution
- Selects
alllog events then filter by specified conditions starting from last successfull execution time - Saves last successfull execution time to COMMENT of the scheduled task
- Create telegram bot and connect to your channel/group/supergorup before usage
- Insert your own values instead of $TOKEN, $CHATID and $GROUPTOPICID variables
Warning
Known issue: log text parser failes for keyword "HTTP"
# logEventTGInformer | by xdenb43
# 15.05.2026 version 2:
# - switch from unstable markdown to html format
# - improve logic
# tested on
# - RoS 7.22.3
# BEGIN SETUP
:local tgBotToken "$TOKEN";
:local tgChatId "$CHATID";
:local tgTopicId "$GROUPTOPICID";
:local tgUrl ("https://api.telegram.org/bot" . $tgBotToken . "/sendMessage")
:local mikrotId ("❗ <code>" . [/system identity get name] . " " . [/system resource get board-name] . "</code> ❗")
:local messageHeader ($mikrotId . "\n\n");
:local scheduleName "logEventTGInformer";
:local logsBuffer [:toarray [/log find \
topics~"(error|critical|netwatch)" || \
message~"([fF]ailure|router rebooted|checkOSUpdate)"]]
:local ignoreInLog {
"static dns entry changed";
"changed script settings";
"HTTP";
"changed scheduled script setting"
}
# Telegram messages can currently hold up to 4KB of text (4096 latin characters).
:local symbolsLimit 4096
:local defaultTime "1970-01-01 00:00:00"
# END SETUP
# SCHEDULER
# warn if schedule does not exist and create it
:if ([:len [/system scheduler find name="$scheduleName"]] = 0) do={
/log warning "[logEventTGInformer] Alert : Schedule does not exist. Creating schedule ...."
:delay 1
/system scheduler add name=$scheduleName interval=60s start-time=startup on-event=logEventTGInformer policy=read,write,test
/log warning "[logEventTGInformer] Alert : Schedule created!"
}
# CURSOR (time-based)
:local lastCursor [/system scheduler get [find name="$scheduleName"] comment]
:if ([:len $lastCursor] = 0) do={
:set lastCursor ($defaultTime)
}
# MAIN PART
:local messageText $messageHeader
:local eventCursor
:if ([:len $logsBuffer] > 0) do={
:foreach line in=$logsBuffer do={
:local eventTime [/log get $line time]
:if ([:len $eventTime] != 0) do={
:local message [:tostr [/log get $line message]]
:local keepLog true
# ignore filter,
:foreach j in=$ignoreInLog do={
:if ($message ~ $j) do={
:set keepLog false
}
}
:if ($keepLog && ([:totime $eventTime] > [:totime $lastCursor])) do={
:local tempResult ($eventTime . "\n" . $message . "\n\n")
# lenght limit check
:if (([:len $messageText] + [:len $tempResult]) < $symbolsLimit) do={
:set messageText ($messageText . $tempResult)
:set eventCursor $eventTime
}
}
}
}
}
# send to telegram
:if ([:len $messageText] > [:len $messageHeader]) do={
/tool fetch \
url=$tgUrl \
http-method=post \
http-header-field="Content-Type: application/json" \
http-data=("{\"chat_id\":\"" . $tgChatId . "\",\"message_thread_id\":\"" . $tgTopicId . "\",\"text\":\"" . $messageText . "\",\"parse_mode\":\"HTML\"}") \
keep-result=no
/system scheduler set [find name=$scheduleName] comment=$eventCursor
}