PUSHOVER - ready MikroTik script to send messages

I’ve just written a script (function) to send the Pushover messages directly from MikroTik, not using e-mail but direct API (faster). Just run once on bootup to “install” the functions:

:global urlEncode do={
  :local output ""
  :local input [:toarray $1]
  :if ([:len $input] > 0) do={
    :local input1 [:tostr [:pick $input 0]]
    :local conversion {" "="%20";"!"="%21";"\""="%22";"#"="%23";"\$"="%24";"%"="%25";"&"="%26";"'"="%27";"-"="%2D";"("="%28";")"="%29";"*"="%2A";"+"="%2B";","="%2C";"/"="%2F";":"="%3A";";"="%3B";"<"="%3C";">"="%3E";"="="%3D";"?"="%3F";"@"="%40";"["="%5B";"]"="%5D";"{"="%7B";"}"="%7D"};
    :for i from=0 to=([:len $input1] - 1) do={ 
      :local char [:pick $input1 $i]
      :if ([:typeof ($conversion->[:tostr $char])]!="nothing") do={:set $char ($conversion->[:tostr $char]);}
      :set output ($output . $char)
    }
    :set output [:tostr $output]
    :set output [:toarray $output]
  }
  :return $output
}

:global pushover do={
:global urlEncode;
  :if ([:typeof $message]!="nothing") do={
    :local api "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
    :local user "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
    :local urlmessage [$urlEncode $message];
    :local string "token=$api&user=$user&message=$urlmessage";
    :if ([:typeof $title]!="nothing") do={:set $string ($string . "&title=$[$urlEncode $title]");}
    :if ([:typeof $priority]!="nothing") do={:set $string ($string . "&priority=$priority");}
    :if ([:typeof $sound]!="nothing") do={:set $string ($string . "&sound=$sound");}
    /tool fetch mode=https url="https://api.pushover.net/1/messages.json" http-method=post http-data="$string";
  }
}

Of course, in “api” and “user” variables I have my keys from Pushover (you need to create application in the Pushover panel). Then I can just do:

$pushover message="This is a simple Pushover message."

Or more advanced:

:local title "Important message from router $[/system identity get name]";                              
:local message "Just writing to inform you that my temperature is $[/system health get temperature] degrees Celsius!" 
$pushover title=$title message=$message priority=1 sound="tugboat"

I used the urlEncode function written by few people in this thread.

Thank you for this - it’s proven to be a very helpful chunk of code!

Works well on FW 6.45.5 including getting PUSHOVER from NETWATCH.

On FW 6.46.4 works only to send PUSHOVER manualy runing script, but doesn’t work to send PUSHOVER from NETWATCH.

Any suggestion?

If you set keep-result=no on the fetch command in the script it works.

Also make sure you set the policy to something like policy=read,write,test on scripts that you want to run from netwatch.

How do you exactly do this? pasting the script on the winbox terminal? and what about the API Keys?
Would you mind elaborating this one? thankyou

@Belikearu, In Winbox or webintraface you can place it under System->Scripts
@dasiu, awesome script, I was looking for a pushover integration

Amazing - thank you!

I tried to use it in net watch, but it didn’t work even I add keep-result=no in script

I use telegram to send me messages from my router.
Is pushover easier/better to use??

$pushover message=“xyz” does work in terminal, but it doesn’t work in scripts

update:
add
:global pushover
and I can use $pushover now

Hi,

Where did you fix this? I am able to send using terminal but not in from inside of scripts….

Can you tell me which line to changed?

Thanks.

Simply READ carefully pervious post…

The post is not clear. It does not state where to add it.

The correct answer would have been:

Add :global pushover in the script you are calling $pushover in.

No need to be a dick.

I was helpful, seen? Now you have read it carefully…

Thank you for the script.

Working perfectly. To test I run the script below

:global pushover
$pushover message=“This is a simple Pushover message.”

Pushover also support JSON as an input. And in 5 years since the OP, Mikrotik added JSON support RouterOS scripting (7.13+).

While I’m sure the existing script is fine, I re-wrote to take an RouterOS array with ANY of the allowed by pushover’s API. Since new [:serialize] will deal with types and escaping when converting the RouterOS array into JSON needed by pushover… the code gets dramatically simplier:

:global npushover do={
    :local url "https://api.pushover.net/1/messages.json"
    :local headers "Content-Type: application/json"
    :local reqdata [:toarray ""]
    :if ([:typeof $1]="array") do={:set reqdata $1} else={
        :error "\$$0 requires an array of values to set, see https://pushover.net/api"
    }
    :local json [:serialize to=json $reqdata]
    :local resp [/tool/fetch url=$url http-data=$json http-header-field=$headers output=user as-value]
    :local respdata [:deserialize from=json ($resp->"data")]
    :if (($respdata->"status")=1) do={
        /log/debug "$0 $[:put "successfully sent request $($respdata->"request")"]"
    } else={
        /log/warning "$0 failed, got: $[:tostr $resp]"
        :error $resp
    }
}

To send a message using pushover using the $npushover above, and using an array allows any of the attributes supports like url or priority:

$npushover ({ 
        user="u8xxxxxxxxxxx"
        token="acyqxxxxxxxxxxxxxxx"
        message="Perhaps some <b>HTML</b>"
        title="Test Message"
        html=1
        sound="magic"
        priority=0
        url="https://router.lan/rest/system/resource"
        "url_title"="/system/resources"
})

See https://pushover.net/api for possible/allowed values. No validation is provided, kinda by design. Errors should be output and logged, likely giving a clue as the right values. And stuff like “priority” has additional allowed attributes like “retry”, so validation might block that (or get very complex).

Thank you very much Ammo, your script is very timely as I only discovered Pushover two days ago.

Much simpler than Telegram

Cheers Dave.

Thank you Amm0. one question. How can I add info from RouterOS in the message. e.g. interface/lte/monitor lte1

I’ve tried

:global npushover
$npushover ({ 
        user="private"
        token="private"
        message="Mikrotik SXT Rebooted <b>nPushover</b> $[interface/lte/monitor lte1 duration=2]"
        title="MikroTik SXTR"
        html=1
        sound="magic"
        priority=0
        url="https://192.168.x.1"
        "url_title"="MikroTik"
})

.. and it executes, but no info from the LTE is included in the message. Any pointers appreciated.

:global npushover
$npushover ({ 
        user="private"
        token="private"
        message="Mikrotik SXT Rebooted <b>nPushover</b> $[interface/lte/monitor lte1 duration=2]"
        title="MikroTik SXTR"
        html=1
        sound="magic"
        priority=0
        url="https://192.168.x.1"
        "url_title"="MikroTik"
})

.. and it executes, but no info from the LTE is included in the message. Any pointers appreciated.

All of the commands with “monitor” are tricky, since it’s like a “for loop”… So you need to remove “duration” and use “once” instead.

:global npushover
$npushover ({ 
        user="private"
        token="private"
        message="Mikrotik SXT Rebooted <b>nPushover</b> $[interface/lte/monitor lte1 once as-value]"
        title="MikroTik SXTR"
        html=1
        sound="magic"
        priority=0
        url="https://192.168.x.1"
        "url_title"="MikroTik"
})

The “once” cause the /interface/lte/monitor to only return one set of value to insert into the message. You could use a duration, but that requires collecting the LTE monitor data into a new variable, and then using the new variable in the message.

Thank you for this. Either version of the code $[interface/lte/monitor lte1 once] doesn’t add data/content at all to the message (not even the code is included). It this the correct way to pull MikroTik data into the message that is sent?

The received message is as attached (sorry can’t seem to attach message)

https://imgur.com/xlI5yVq

UPDATE: This works though

message=“Mikrotik SXT Rebooted nPushover $[/system clock get time] $[/system clock get time] $[/system identity get name]”