Community discussions

MikroTik App
 
codenameultra
just joined
Topic Author
Posts: 6
Joined: Wed Aug 03, 2022 11:20 am

Get connected VPN names and send to telegram

Wed Aug 03, 2022 11:46 am

Hi guys, I need some help.
I have hAP ac^2 running on 7.4
I have several l2tp clients on my router, 2 wan, and a telegram bot. I succeed in making the telegram bot to send messages to my group. Now I want the followings:

1. I want the bot to send the list of uplink VPNs, something like:
Router ID: xxx <--- no problem
mmm/dd/yyyy hh:mm:ss <--- no problem
Connecting link: l2tp - xxx - Singapore <--- run but only for 1 VPN, if there is more than 1 VPN connection, it shows nothing.
:local VPNNames [:put [/interface get [find where running type=l2tp-out] value-name=name]]
I understand that "find" returns the ID of the interface and "get" will get the interface name. but since there is more than 1 id, "get" gets the error. But I don't know how to make it into a list and telegram can get that content to send message.

2. I have 2 wan, 1 from an LTE router and 1 from a PPPoE router. the VPNs connect through the LTE router just fine with no problem but cannot connect through the PPPoE router (it uses TR-069). Even when I disable the LTE router, no VPN can establish the link through the PPPoE router. Any suggestion?
 
codenameultra
just joined
Topic Author
Posts: 6
Joined: Wed Aug 03, 2022 11:20 am

Re: Get connected VPN names and send to telegram

Wed Aug 03, 2022 5:05 pm

after some researching I came up with this:
:local vpnID [/interface find where running type=l2tp-out]
:foreach vpnID in=$vpnID do={:local vpnNames [/interface get $vpnID value-name=name]}
:local deviceName [/system identity get name]
:local deviceDate [/system clock get date]
:local deviceTime [/system clock get time]
:local MessageText "Router ID: $deviceName%0A$deviceDate $deviceTime%0AConnecting link: $vpnNames"
:local SendTelegramMessage [:parse [/system script  get "Telegram Bot Send Message" source]];
$SendTelegramMessage MessageText=$MessageText;
The result is:
Screenshot_1.png
As you can see that nothing appear after "Connecting link". What should I do?
You do not have the required permissions to view the files attached to this post.
 
sindy
Forum Guru
Forum Guru
Posts: 10205
Joined: Mon Dec 04, 2017 9:19 pm

Re: Get connected VPN names and send to telegram

Wed Aug 03, 2022 8:37 pm

Several points:
  • a local variable only exists within the block where it was declared. So to let its contents survive the end of a run of the foreach body, you have to replace
    :foreach vpnID in=$vpnID do={:local vpnNames [/interface get $vpnID value-name=name]}
    by
    :local vpnNames
    :foreach vpnID in=$vpnID do={:set vpnNames [/interface get $vpnID value-name=name]}
  • it seems you want to send the whole list of interfaces in a single message; if so, you have to update it rather than rewrite it each time:
    :local vpnNames [:toarray ""]
    :foreach vpnID in=$vpnID do={:set vpnNames ($vpnNames,[/interface get $vpnID value-name=name])}
    ...
    :local MessageText ("Router ID: $deviceName%0A$deviceDate $deviceTime%0AConnecting link: " . [:tostr $vpnNames])

    (or use a flat string instead of an array: :set vpnNames ($vpnNames . " " . [/interface get $vpnID value-name=name]) and no need for the :tostr, you'll just have the separator before the last interface name unless you strip it using :pick, or unless you use an additional condition to only add it if the $vpnNames is not empty)
  • you can also send a message each time the state of the L2TP interface changes if you configure the on-up and on-down scripts on the /ppp profile row used by the /ppp secret rows at the server side. The on-down script is pre-cached during the on-up operation, so a change in the on-down script only actually becomes noticeable at the second down after the change. The pleasant side (and most likely the purpose) of this is that the values of the variables are pre-cached too, so even when the interface is dynamic and therefore doesn't exist any more when the on-down script is executed, its name is still available for logging or sending.
 
codenameultra
just joined
Topic Author
Posts: 6
Joined: Wed Aug 03, 2022 11:20 am

Re: Get connected VPN names and send to telegram

Fri Aug 05, 2022 2:18 pm

Thank you Sindy for your reply. I manage to make it run perfectly with your suggestion:
:local deviceName [/system identity get name]
:local deviceDate [/system clock get date]
:local deviceTime [/system clock get time]
:local VPNCountA [/file get VPNCountA.txt contents]
:local VPNCountB [/interface l2tp-client print count-only where running]
:if (($VPNCountA =$VPNCountB) && ($VPNCountB =0)) do={nothing}
:if (($VPNCountA =$VPNCountB) && ($VPNCountB !=0)) do={nothing}
:if (($VPNCountA !=$VPNCountB) && ($VPNCountB =0)) do={
:set [/file set VPNCountA.txt contents=$VPNCountB]
:local MessageText "<b>VPN CONNECTION NOTIFICATION</b>%0A<b>Router ID</b>: $deviceName%0A<b>Time:</b> $deviceDate $deviceTime%0A<b>Status:</b> Unsecured \F0\9F\94\B4%0A<b>Available Link(s):</b> 0%0A<b>Connection:</b> Not Available";
:local SendTelegramMessage [:parse [/system script  get "Telegram Bot Send Message" source]];
$SendTelegramMessage MessageText=$MessageText;}
:if (($VPNCountA !=$VPNCountB) && ($VPNCountB !=0)) do={
:set [/file set VPNCountA.txt contents=$VPNCountB]
:local VPNNames [:toarray ""]
:foreach VPNid in=[/interface l2tp-client find where running] do={:set VPNNames ($VPNNames,[/interface get $VPNid value-name=name])}
:local MessageText ("<b>VPN CONNECTION NOTIFICATION</b>%0A<b>Router ID</b>: $deviceName%0A<b>Time:</b> $deviceDate $deviceTime%0A<b>Status:</b> Secured \F0\9F\9F\A2%0A<b>Available Link(s):</b> $VPNCountB%0A<b>Connection:</b>%0A" . [:tostr $VPNNames]);
:local SendTelegramMessage [:parse [/system script  get "Telegram Bot Send Message" source]];
$SendTelegramMessage MessageText=$MessageText;}
But the result was:
Connection:
VPN1;VPN2;VPN3;VPN4
But I would like it to display as:
Connection:
VPN1
VPN2
VPN3
VPN4
I tried modifying
do={:set VPNNames ($VPNNames,[/interface get $VPNid value-name=name])}
to
do={:set VPNNames [/interface get $VPNid value-name=name]}
and
[:tostr $VPNNames]
to
:foreach k in=$VPNNames do={:put $VPNNames}}
but nothing works.

Thank you.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Get connected VPN names and send to telegram

Fri Aug 05, 2022 2:28 pm

See and understand also the various corrections:
{

/system identity
:local deviceName [get name]
/system clock 
:local deviceDate [get date]
:local deviceTime [get time]

:local VPNCountA  [:tonum [/file get [find where name="VPNCountA.txt"] contents]]
:local VPNids     [/interface l2tp-client find where running=yes]
:local VPNCountB  [:len $VPNids]
:local VPNNames   ""

:if (($VPNCountA != $VPNCountB) and ($VPNCountB = 0)) do={
    /file set [find where name="VPNCountA.txt"] contents=$VPNCountB

    :local MessageText "<b>VPN CONNECTION NOTIFICATION</b>%0A\
                        <b>Router ID</b>: $deviceName%0A\
                        <b>Time:</b> $deviceDate $deviceTime%0A\
                        <b>Status:</b> Unsecured \F0\9F\94\B4%0A\
                        <b>Available Link(s):</b> 0%0A\
                        <b>Connection:</b> Not Available"

    :local SendTelegramMessage [:parse [/system script get "Telegram Bot Send Message" source]]
    [$SendTelegramMessage MessageText=$MessageText]
}

:if (($VPNCountA != $VPNCountB) and ($VPNCountB != 0)) do={
    /file set [find where name="VPNCountA.txt"] contents=$VPNCountB

    :foreach VPNid in=$VPNids do={
        :set VPNNames "$VPNNames%0A$[/interface get $VPNid value-name=name]"
    }

    :local MessageText "<b>VPN CONNECTION NOTIFICATION</b>%0A\
                        <b>Router ID</b>: $deviceName%0A\
                        <b>Time:</b> $deviceDate $deviceTime%0A\
                        <b>Status:</b> Secured \F0\9F\9F\A2%0A\
                        <b>Available Link(s):</b> $VPNCountB%0A\
                        <b>Connection:</b>%0A\
                        $VPNNames"

    :local SendTelegramMessage [:parse [/system script get "Telegram Bot Send Message" source]]
    [$SendTelegramMessage MessageText=$MessageText]
}

}
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Get connected VPN names and send to telegram

Fri Aug 05, 2022 2:49 pm

About VPNCount, better use a global variable than a file.
If the file not exist, the script do not create one.
At least add a check if the file exist go, else create first one file, then put 0 inside, then continue the execution of the script.

If you create a file outside /flash on device that have flash, on reboot the file is lost, also like with global variable.
 
sindy
Forum Guru
Forum Guru
Posts: 10205
Joined: Mon Dec 04, 2017 9:19 pm

Re: Get connected VPN names and send to telegram

Fri Aug 05, 2022 2:55 pm

:put <something> prints the <something> on the script console, it does not provide the <something> as an output value to the calling function.

Second, if you want to use another separator than ';' (which is inserted by :tostr), you cannot add the VPN names into an array - instead, you have to follow my previous advice to start with an empty string, and add each new VPN interface name followed by the '%0a' separator to the end of this string in the :foreach cycle. Then, you just copy the resulting string into the final message, without the :tostr.
 
codenameultra
just joined
Topic Author
Posts: 6
Joined: Wed Aug 03, 2022 11:20 am

Re: Get connected VPN names and send to telegram

Fri Aug 05, 2022 3:21 pm

See and understand also the various corrections:
{

/system identity
:local deviceName [get name]
/system clock 
:local deviceDate [get date]
:local deviceTime [get time]

:local VPNCountA  [:tonum [/file get [find where name="VPNCountA.txt"] contents]]
:local VPNids     [/interface l2tp-client find where running=yes]
:local VPNCountB  [:len $VPNids]
:local VPNNames   ""

:if (($VPNCountA != $VPNCountB) and ($VPNCountB = 0)) do={
    /file set [find where name="VPNCountA.txt"] contents=$VPNCountB

    :local MessageText "<b>VPN CONNECTION NOTIFICATION</b>%0A\
                        <b>Router ID</b>: $deviceName%0A\
                        <b>Time:</b> $deviceDate $deviceTime%0A\
                        <b>Status:</b> Unsecured \F0\9F\94\B4%0A\
                        <b>Available Link(s):</b> 0%0A\
                        <b>Connection:</b> Not Available"

    :local SendTelegramMessage [:parse [/system script get "Telegram Bot Send Message" source]]
    [$SendTelegramMessage MessageText=$MessageText]
}

:if (($VPNCountA != $VPNCountB) and ($VPNCountB != 0)) do={
    /file set [find where name="VPNCountA.txt"] contents=$VPNCountB

    :foreach VPNid in=$VPNids do={
        :set VPNNames "$VPNNames%0A$[/interface get $VPNid value-name=name]"
    }

    :local MessageText "<b>VPN CONNECTION NOTIFICATION</b>%0A\
                        <b>Router ID</b>: $deviceName%0A\
                        <b>Time:</b> $deviceDate $deviceTime%0A\
                        <b>Status:</b> Secured \F0\9F\9F\A2%0A\
                        <b>Available Link(s):</b> $VPNCountB%0A\
                        <b>Connection:</b>%0A\
                        $VPNNames"

    :local SendTelegramMessage [:parse [/system script get "Telegram Bot Send Message" source]]
    [$SendTelegramMessage MessageText=$MessageText]
}

}
Thank you so much for the correction. So the point here is "$VPNNames%0A$[". So "%0A" is for a new line and "$[" is for each string in that array, am I right?
furthermore, there is a space between connection and output. Can I make it disappear?

Can you take a look at "2." in my first post?
You do not have the required permissions to view the files attached to this post.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Get connected VPN names and send to telegram

Fri Aug 05, 2022 3:56 pm

Is not a space, is a line-feed (0x0A or \n)

try to remove %0A here:
                        <b>Connection:</b>%0A\
                        $VPNNames"

for point 2 not, sorry.
 
codenameultra
just joined
Topic Author
Posts: 6
Joined: Wed Aug 03, 2022 11:20 am

Re: Get connected VPN names and send to telegram

Fri Aug 05, 2022 4:24 pm

Is not a space, is a line-feed (0x0A or \n)

try to remove %0A here:
                        <b>Connection:</b>%0A\
                        $VPNNames"

for point 2 not, sorry.
Work perfectly, thank you very much.
 
codenameultra
just joined
Topic Author
Posts: 6
Joined: Wed Aug 03, 2022 11:20 am

Re: Get connected VPN names and send to telegram

Fri Aug 05, 2022 4:25 pm

:put <something> prints the <something> on the script console, it does not provide the <something> as an output value to the calling function.

Second, if you want to use another separator than ';' (which is inserted by :tostr), you cannot add the VPN names into an array - instead, you have to follow my previous advice to start with an empty string, and add each new VPN interface name followed by the '%0a' separator to the end of this string in the :foreach cycle. Then, you just copy the resulting string into the final message, without the :tostr.
Thank you, I will try to modify it to understand the structure and how it works.

Who is online

Users browsing this forum: Bing [Bot], cloud45, karlisi and 81 guests