This is a quick RouterOS script hack which I just wanted to get up online; it’s not anywhere near perfect but it might be useful to others. My objective here was to post a message to any Slack channel from Mikrotik RouterOS:
Slack has a super-simple to use ‘incoming webhook‘ integration but unfortunately, this requires that your app make a HTTP POST
request – unfortunately not actually possible with RouterOS. Luckily, you can alternatively send messages using a HTTP GET
request to Slack’s chat.postMessage API method. All you’ll need to do this is an API test token, which you can generate here.
Once you have your test token (beginning xoxp-..) you can form a HTTP GET
request, including your message and any additional args (username, icon, channel..) as per the script below. Submitting a message is as easy as making a /tool fetch url
command in your script.
To actually implement this usefully, the script below will parse the log file (ref.) for topics of interest, URL-encode any unsafe ASCII characters (non-exhaustive…) then post a message to your nominated Slack channel.
#log parse functionality from http://forum.mikrotik.com/viewtopic.php?t=77498#p390040 :global lastTime :global messageencoded "" :global output :local botname "Slackbutt" :local channel "%23mikrotik" :local token "xoxp-your-token-here" :local iconurl http://www.zlmedia.hr/wp-content/uploads/2013/05/mikrotik-zlmediahr-icon.png :local currentBuf [ :toarray [ /log find topics~"critical" || message~"login failure" || message~"disabled" || message~"pptp" || message~"sit1" || message~"[Ff]ailure" ] ] ; :local currentLineCount [ :len $currentBuf ] ; if ($currentLineCount > 0) do={ :local currentTime "$[ /log get [ :pick $currentBuf ($currentLineCount -1) ] time ]"; :if ([:len $currentTime] = 15 ) do={ :set currentTime [ :pick $currentTime 7 15 ]; } :set output "$currentTime - $[/log get [ :pick $currentBuf ($currentLineCount-1) ] message ]"; #replace ASCII characters with URL encoded characters :for i from=0 to=([:len $output] - 1) do={ :local char [:pick $output $i] :if ($char = " ") do={ :set $char "%20" } :if ($char = "-") do={ :set $char "%2D" } :if ($char = "#") do={ :set $char "%23" } :if ($char = "+") do={ :set $char "%2B" } :set messageencoded ($messageencoded . $char) } :if (([:len $lastTime] < 1) || (([:len $lastTime] > 0) && ($lastTime != $currentTime))) do={ :set lastTime $currentTime ; /tool fetch url="https://slack.com/api/chat.postMessage?token=$token&channel=$channel&text=$messageencoded&icon_url=$iconurl&as_user=false&username=$botname"; } }
Todo: Read multiple log lines and post them as a single message using newlines, make logging topics and keywords better.
Leave a Reply to Hengst Cancel reply