tgConfig.rsc: this is the configuration files - your bot’s API, default chatID (will send message to this IDs when chat=), trusted will receive commands only from allowed IDs and etc…)
######################################
# Telegram bot API, VVS/BlackVS 2017
# Config file
######################################
:log info "telegram configuration file has been loaded";
# to use config insert next lines:
#:local fconfig [:parse [/system script get tg_config source]]
#:local config [$fconfig]
#:put $config
######################################
# Common parameters
######################################
:local config {
"Command"="telegram";
"botAPI"="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
"defaultChatID"="AAAAAAAAA,BBBBBBBBB";
"trusted"="AAAAAAAAA,BBBBBBBBB,CCCCCCCCCC";
"storage"="";
"timeout"=1;
"refresh_active"=15;
"refresh_standby"=300;
}
return $config
tgScheduler.rsc: this script create scheduler that check for telegram updates every 5 mins and create global (script environment) called $telegram (once/if not exists). after running this script you can use commands such “$telegram action=send chat= text=” to send telegram message or just $telegram ($telegram action=receive is same) to receive message/commands.
:local onevent "
:if (([:len [/system script environment find name=telegram]]=0) or [:len [/system script environment get value-name=value [/system script environment find name=telegram]]]=0) do={
:log warning \"telegram environment has been updated\"
:global telegram do={
:local fconfig [:parse [/system script get tgConfig source]]
:local tgData [\$fconfig]
:local tgActive (\$tgData->\"refresh_active\")
:local tgStandby (\$tgData->\"refresh_standby\")
# check last time received message
:local lastseen do={
:local date1 [:tostr \$1];
:local date2 [:tostr \$2];
:local date1month [:pick \$date1 0 3]
:local date1day [:pick \$date1 4 6]
:local date1year [:pick \$date1 7 11]
:local date1hours [:pick \$date1 12 14]
:local date1minutes [:pick \$date1 15 17]
:local date1seconds [:pick \$date1 18 20]
:local date2month [:pick \$date2 0 3]
:local date2day [:pick \$date2 4 6]
:local date2year [:pick \$date2 7 11]
:local date2hours [:pick \$date2 12 14]
:local date2minutes [:pick \$date2 15 17]
:local date2seconds [:pick \$date2 18 20]
# month to decimal converter - http://forum.mikrotik.com/t/compare-dates/53609/1
:local months (\"jan\",\"feb\",\"mar\",\"apr\",\"may\",\"jun\",\"jul\",\"aug\",\"sep\",\"oct\",\"nov\",\"dec\");
:set date1month ([:find \$months \$date1month -1 ] + 1)
:set date2month ([:find \$months \$date2month -1 ] + 1)
:local yearDiff (\$date2year - \$date1year)
:local monthDiff (\$date2month - \$date1month)
:local dayDiff (\$date2day - \$date1day)
:local hoursDiff (\$date2hours - \$date1hours)
:local minutesDiff (\$date2minutes - \$date1minutes)
:local secondsDiff (\$date2seconds - \$date1seconds)
:local secondsGlobalDiff
:set secondsGlobalDiff ((\$dayDiff * 86400) + (\$hoursDiff * 3600) + (\$minutesDiff *60) + \$secondsDiff)
:set dayDiff (\$secondsGlobalDiff / 86400)
:set secondsGlobalDiff (\$secondsGlobalDiff - (\$dayDiff * 86400))
:set hoursDiff (\$secondsGlobalDiff / 3600)
:set secondsGlobalDiff (\$secondsGlobalDiff - (\$hoursDiff * 3600))
:set minutesDiff (\$secondsGlobalDiff / 60)
:set secondsGlobalDiff (\$secondsGlobalDiff - (\$minutesDiff * 60))
:set secondsDiff \$secondsGlobalDiff
# check if leap years - https://wiki.mikrotik.com/wiki/AutomatedBilling/MonthEndScript
:local isYear1Leap 0
:local isYear2Leap 0
if (((\$date1year / 4) * 4) = \$date1year) do={
:set isYear1Leap 1
}
if (((\$date2year / 4) * 4) = \$date2year) do={
:set isYear2Leap 1
}
# find the right amount of days between 2 months
:local daysInEachMonth (\"31\",\"28\",\"31\",\"30\",\"31\",\"30\",\"31\",\"31\",\"30\",\"31\",\"30\",\"31\");
:local daysInEachMonthLeapYear (\"31\",\"29\",\"31\",\"30\",\"31\",\"30\",\"31\",\"31\",\"30\",\"31\",\"30\",\"31\");
:local totalDaysBetweenMonths
# same year; yearDiff = 0 so year1 = year2
if (\$yearDiff = 0 and \$monthDiff >= 1) do={
if (\$isYear1Leap = 0) do={
for month from=(\$date1month - 1) to=(\$date2month - 1) step=1 do={
:set totalDaysBetweenMonths (\$totalDaysBetweenMonths + [:pick \$daysInEachMonth \$month])
}
}
if (\$isYear1Leap = 1) do={
for month from=(\$date1month - 1) to=((\$date2month - 1) - 1) step=1 do={
:set totalDaysBetweenMonths (\$totalDaysBetweenMonths + [:pick \$daysInEachMonthLeapYear \$month])
}
}
}
# different year, make concatenation of daysInEachMonth arrays first
:local daysInEachMonthConcatenatedYears
if (\$yearDiff >= 1) do={
for year from=\$date1year to=\$date2year step=1 do={
# if leap year, concatenate the right daysInEachMonth array
if (((\$year / 4) * 4) = \$year) do={
:set daysInEachMonthConcatenatedYears (\$daysInEachMonthConcatenatedYears, \$daysInEachMonthLeapYear)
} else={
:set daysInEachMonthConcatenatedYears (\$daysInEachMonthConcatenatedYears, \$daysInEachMonth)
}
}
# must add years count
for month from=(\$date1month - 1) to=((\$date2month - 1) + ((\$yearDiff * 12) - 1)) step=1 do={
:set totalDaysBetweenMonths (\$totalDaysBetweenMonths + [:pick \$daysInEachMonthConcatenatedYears \$month])
}
}
:local globalDaysDiff (\$totalDaysBetweenMonths + \$dayDiff)
# add leading zeros if necessary
:if (\$hoursDiff < 10) do={
:set hoursDiff (\"0\" . \$hoursDiff)
}
:if (\$minutesDiff < 10) do={
:set minutesDiff (\"0\" . \$minutesDiff)
}
:if (\$secondsDiff < 10) do={
:set secondsDiff (\"0\" . \$secondsDiff)
}
:local inMinutes (\$globalDaysDiff*24*60+\$hoursDiff*60+\$minutesDiff);
return \$inMinutes;
}
#send message
:local tgSendMessage do={
:local fconfig [:parse [/system script get tgConfig source]]
:local tgData [\$fconfig]
:local tgBotAPI (\$tgData->\"botAPI\")
:local tgStorage (\$tgData->\"storage\")
:local tgDefaultChatID (\$tgData->\"defaultChatID\")
:local tgID \$tgDefaultChatID
:if ([:len \$chat]>0) do={ set tgID \$chat }
:foreach chatID in=[:toarray \$tgID] do={
:local fail false;
:local url \"https://api.telegram.org/bot\$tgBotAPI/sendmessage\?chat_id=\$chatID&text=\$text\"
:set url (\$url.\"&parse_mode=Markdown\")
:if ([:len \$mode]>0) do={:set url (\$url.\"&parse_mode=\$mode\")}
:log warning \$url;
:do {
/tool fetch url=\$url keep-result=no
} on-error={
:log error \"failed to send telegram message to '\$chatID'.\"
:set fail true;
}
:if (!\$fail) do={
:log info \"telegram message has been sent to '\$chatID'\"
}
}
}
#receive message
:local tgReceiveMessage do={
:global tgLastMsgID
:global tgLastUPDID
:global tgLasttime;
:local fconfig [:parse [/system script get tgConfig source]]
:local tgData [\$fconfig]
:local tgTrusted [:toarray (\$tgData->\"trusted\")]
:local tgBotAPI (\$tgData->\"botAPI\")
:local tgStorage (\$tgData->\"storage\")
:local tgTimeout (\$tgData->\"timeout\")
:local tgGetkey do={
:local cur 0
:local lkey [:len \$key]
:local res \"\"
:local p
:if ([:len \$block]>0) do={
:set p [:find \$text \$block \$cur]
:if ([:type \$p]=\"nil\") do={
:return \$res
}
:set cur (\$p+[:len \$block]+2)
}
:set p [:find \$text \$key \$cur]
:if ([:type \$p]!=\"nil\") do={
:set cur (\$p+lkey+2)
:set p [:find \$text \",\" \$cur]
:if ([:type \$p]!=\"nil\") do={
:if ([:pick \$text \$cur]=\"\\\"\") do={
:set res [:pick \$text (\$cur+1) (\$p-1)]
} else={
:set res [:pick \$text \$cur \$p]
}
}
}
:return \$res
}
:local http do={
:local res \"fetchRESULT.txt\"
:if ([:len \$resfile]>0) do={:set res \$resfile}
#:put \$res
:local cmd \"/tool fetch\"
:if ([:len \$mode]>0) do={:set cmd \"\$cmd mode=\$mode\"}
:if ([:len \$upload]>0) do={:set cmd \"\$cmd upload=\$upload\"}
:if ([:len \$user]>0) do={:set cmd \"\$cmd user=\\\"\$user\\\"\"}
:if ([:len \$password]>0) do={:set cmd \"\$cmd password=\\\"\$password\\\"\"}
:if ([:len \$address]>0) do={:set cmd \"\$cmd address=\\\"\$address\\\"\"}
:if ([:len \$host]>0) do={:set cmd \"\$cmd host=\\\"\$host\\\"\"}
:if ([:len \$\"http-data\"]>0) do={:set cmd \"\$cmd http-data=\\\"\$\"http-data\"\\\"\"}
:if ([:len \$\"http-method\"]>0) do={:set cmd \"\$cmd http-method=\\\"\$\"http-method\"\\\"\"}
:if ([:len \$\"check-certificate\"]>0) do={:set cmd \"\$cmd check-certificate=\\\"\$\"check-certificate\"\\\"\"}
:if ([:len \$\"src-path\"]>0) do={:set cmd \"\$cmd src-path=\\\"\$\"src-path\"\\\"\"}
:if ([:len \$\"dst-path\"]>0) do={:set cmd \"\$cmd dst-path=\\\"\$\"dst-path\"\\\"\"}
:if ([:len \$ascii]>0) do={:set cmd \"\$cmd ascii=\\\"\$ascii\\\"\"}
:if ([:len \$url]>0) do={:set cmd \"\$cmd url=\\\"\$url\\\"\"}
:put \">> \$cmd\"
:global fetchRESULT
:set fetchRESULT \"none\"
:local script \"\
:global fetchRESULT;\
:do {\
\$cmd;\
:set fetchRESULT \\\"success\\\";\
} on-error={\
:set fetchRESULT \\\"failed\\\";\
}\
\"
:execute script=\$script file=\$res
:local cnt 0
#:put \"\$cnt -> \$fetchRESULT\"
:while (\$cnt<100 and \$fetchRESULT=\"none\") do={
:delay 1s
:set \$cnt (\$cnt+1)
#:put \"\$cnt -> \$fetchRESULT\"
}
:local content [/file get [find name=\$res] content]
#:put \$content
if (\$content~\"finished\") do={:return \"success\"}
:return \$fetchRESULT
}
:put \"trusted=\$tgTrusted\"
:put \"botID=\$tgBotAPI\"
:put \"storage=\$tgStorage\"
:put \"timeout=\$tgTimeout\"
:local file (\$tgStorage.\"tgReceiveMessage.txt\")
:local logfile (\$tgStorage.\"tgFetch.txt\")
:local noupdate false;
#loop start
while (!\$noupdate) do={
:local url (\"https://api.telegram.org/bot\".\$tgBotAPI.\"/getUpdates?timeout=\$tgTimeout&limit=1\")
:if ([:len \$tgLastUPDID]>0) do={
:set url \"\$url&offset=\$(\$tgLastUPDID+1)\"
}
:log info \"telegram receiving updates...\"
:local res [\$http dst-path=\$file url=\$url resfile=\$logfile]
:if (\$res!=\"success\") do={
:log error \"telegram receive updates failed\"
:return \"Failed get updates\"
:set noupdate true;
}
:log info \"telegram receiving updates complete\"
:local content [/file get [/file find name=\$file] contents]
:local msgid [\$tgGetkey key=\"message_id\" text=\$content]
:if (\$msgid=\"\") do={
:log info \"telegram has no new messages\"
:set noupdate true;
:return 0
} else={
:set tgLastMsgID \$msgid
:local updid [\$tgGetkey key=\"update_id\" text=\$content]
:set tgLastUPDID \$updid
:local tgFromID [\$tgGetkey block=\"from\" key=\"id\" text=\$content]
:local tgUsername [\$tgGetkey block=\"from\" key=\"username\" text=\$content]
:local tgFirstName [\$tgGetkey block=\"from\" key=\"first_name\" text=\$content]
:local tgLastName [\$tgGetkey block=\"from\" key=\"last_name\" text=\$content]
:local tgID [\$tgGetkey block=\"chat\" key=\"id\" text=\$content]
:local tgMessage [\$tgGetkey block=\"chat\" key=\"text\" text=\$content]
:local tgName \"\$tgFirstName \$tgLastName\"
:put \"message id=\$msgid\"
:put \"update id=\$updid\"
:put \"from id=\$tgFromID\"
:put \"first name=\$tgFirstName\"
:put \"last name=\$tgLastName\"
:put \"username=\$tgUsername\"
:if ([:len \$tgName]<2) do {
:if ([:len \$tgUsername]>0) do={
:set tgName \$tgUsername
} else={
:set tgName \"Unknown\"
}
}
:put \"name=\$tgName\"
:put \"in chat=\$tgID\"
:put \"command=\$tgMessage\"
:local allowed ( [:type [:find \$tgTrusted \$tgFromID]]!=\"nil\" or [:type [:find \$tgTrusted \$tgID]]!=\"nil\")
:if (!\$allowed) do={
:log warning \"telegram unknown sender, keep silence\"
:return -1
} else={
:set tgLasttime ([/system clock get date].\" \".[/system clock get time])
:local cmd \"\"
:local params \"\"
:local ltext [:len \$tgMessage]
:local pos [:find \$tgMessage \" \"]
:if ([:type \$pos]=\"nil\") do={
:set cmd [:pick \$tgMessage 1 \$ltext]
} else={
:set cmd [:pick \$tgMessage 1 \$pos]
:set params [:pick \$tgMessage (\$pos+1) \$ltext]
}
:local pos [:find \$cmd \"@\"]
:if ([:type \$pos]!=\"nil\") do={
:set cmd [:pick \$cmd 0 \$pos]
}
:put \"cmd=<\$cmd>\"
:put \"params=<\$params>\"
:global tgLastCmd \$cmd
:if ([:len [/system script find name=\"tgCmd_\$cmd\"]]>0) do={
:log warning \"Try to invoke external script tgCmd_\$cmd\"
:local script [:parse [/system script get \"tgCmd_\$cmd\" source]]
\$script params=\$params chatid=\$tgID from=\$tgName
} else={
# :log warning \"command (\$tgMessage) has been received from '\$tgName' (\$tgID) via telegram\";
# :local tgScriptFile \"tgTemp\";
# :local tgScriptSource (\"
# :global telegram
# :do {
# :local fail false;
# \$tgMessage
# } on-error={
# :set \\\$fail true;
# }
# :if (!\\\$fail) do={
# \\\$telegram action=send chat=\$tgID text=\\\"Command '\$tgMessage' has been done.\\\"
# :log warning \\\"telegram command '\$tgMessage' received from '\$tgName' (\$tgID) has been done.\\\"
# } else={
# \\\$telegram action=send chat=\$tgID text=\\\"Error command '\$tgMessage'.\\\"
# :log error \\\"telegram command '\$tgMessage' received from '\$tgName' (\$tgID) has been failed.\\\"
# }
# /system script remove [/system script find name=\\\"\$tgScriptFile\\\"]
# \")
# /system script add name=\$tgScriptFile source=\$tgScriptSource;
# /system script run \$tgScriptFile;
}
}
}
#loop end
}
/system script environment remove [/system script environment find name=\"fetchRESULT\"];
}
:global tgLasttime;
:if ((([:len \$tgLasttime]>0) and ([\$lastseen \$tgLasttime ([/system clock get date].\" \".[/system clock get time])]<3)) or (\$action=\"send\")) do={
/system scheduler set interval=\$tgActive telegram
} else={
/system scheduler set interval=\$tgStandby telegram
}
:if (([:len \$action]=0) or (\$action=\"receive\")) do={
\$tgReceiveMessage;
} else={
:if (\$action=\"send\") do={
\$tgSendMessage chat=\$chat text=\$text;
}
:if (\$action=\"last\") do={
/put [\$lastseen \$tgLasttime ([/system clock get date].\" \".[/system clock get time])]
}
}
}
}
:global telegram
\$telegram
"
:if ([:len [/system scheduler find name=telegram]]=0) do={
:log warning "Creating telegram scheduler"
/system scheduler add name=telegram interval=15m on-event=$onevent
} else={
:if ([/system scheduler get value-name=on-event [/system scheduler find name=telegram]]!=$onevent) do={
:log warning "Updating telegram scheduler"
/system scheduler set on-event=$onevent [/system scheduler find name=telegram]
}
}
:execute script=[/system scheduler get value-name=on-event telegram]
tgCmd_hotspot.rsc: This script creating new guest account randomly (can work without telegram) but you should have before “Hotspot server”, the script will create hotspot’s user profile with “on-login” and random hotspot account (username and password), after someone login by this your it’s will update him MAC address so no body else can use this account anymore, after that the script will create new randomly hotspot account (username and password) and send you notification by mail (you should set “notifyMail” for that).
Call the script via telegram using commands:
/hotspot active - returns active hotspot clients
/hotspot user list - returns hotspot user list
/hotspot user disable - disable hotspot account
/hotspot user enable - enable hotspot account
/hotspot user create - create random hotspot account (username and password)
/hotspot user create - create random hotspot account (username and password) assign to specific email
/hotspot user recover - returns all hotspot account include passwords
/hotspot user recover - returns specific hotspot user’s password
/hotspot user recover - send all hotspot account assigns to specific email by email"
# Hotspot server name
:local serverName "guests"
# User Profile
:local userProfile "generated"
# User prefix
:local userPrefix "G"
# User expired days
:local userExpired 30
# User identify length (the username will be 'user'+random chars)
:local identifyLength 4
# Password generate length
:local passwordLength 5
# After creating username and password send notification mail to (addresses seperate by ',')
:local notifyMail "your@mail.com"
:local rsc ("
:local calcDays do={
:local date1 [:tostr \$1];
:local date2 [:tostr \$2];
:local date1month [:pick \$date1 0 3]
:local date1day [:pick \$date1 4 6]
:local date1year [:pick \$date1 7 11]
:local date2month [:pick \$date2 0 3]
:local date2day [:pick \$date2 4 6]
:local date2year [:pick \$date2 7 11]
# month to decimal converter - http://forum.mikrotik.com/t/compare-dates/53609/1
:local months (\"jan\",\"feb\",\"mar\",\"apr\",\"may\",\"jun\",\"jul\",\"aug\",\"sep\",\"oct\",\"nov\",\"dec\");
:set date1month ([:find \$months \$date1month -1 ] + 1)
:set date2month ([:find \$months \$date2month -1 ] + 1)
:local globalDiff
:local yearDiff (\$date2year - \$date1year)
:local monthDiff (\$date2month - \$date1month)
:local dayDiff (\$date2day - \$date1day)
# check if date1 is older than date2 to avoid errors in calculation
if (\$yearDiff < 0) do={
:return \"error : date1 should be older that date2 (year check), exiting\"
} else={
if (\$yearDiff = 0) do={
if (\$monthDiff <0) do={
:return \"error : date1 should be older that date2 (month check), exiting\"
} else={
if (\$monthDiff = 0) do={
if (\$dayDiff < 0) do={
:return \"error : date1 should be older that date2 (day check), exiting\"
}
}
}
}
}
# check if leap years - https://wiki.mikrotik.com/wiki/AutomatedBilling/MonthEndScript
:local isYear1Leap 0
:local isYear2Leap 0
if (((\$date1year / 4) * 4) = \$date1year) do={
:set isYear1Leap 1
}
if (((\$date2year / 4) * 4) = \$date2year) do={
:set isYear2Leap 1
}
# find the right amount of days between 2 months
:local daysInEachMonth (\"31\",\"28\",\"31\",\"30\",\"31\",\"30\",\"31\",\"31\",\"30\",\"31\",\"30\",\"31\");
:local daysInEachMonthLeapYear (\"31\",\"29\",\"31\",\"30\",\"31\",\"30\",\"31\",\"31\",\"30\",\"31\",\"30\",\"31\");
:local totalDaysBetweenMonths
# same year; yearDiff = 0 so year1 = year2
if (\$yearDiff = 0 and \$monthDiff >= 1) do={
if (\$isYear1Leap = 0) do={
for month from=(\$date1month - 1) to=(\$date2month - 1) step=1 do={
:set totalDaysBetweenMonths (\$totalDaysBetweenMonths + [:pick \$daysInEachMonth \$month])
}
}
if (\$isYear1Leap = 1) do={
for month from=(\$date1month - 1) to=((\$date2month - 1) - 1) step=1 do={
:set totalDaysBetweenMonths (\$totalDaysBetweenMonths + [:pick \$daysInEachMonthLeapYear \$month])
}
}
}
# different year, make concatenation of daysInEachMonth arrays first
:local daysInEachMonthConcatenatedYears
if (\$yearDiff >= 1) do={
for year from=\$date1year to=\$date2year step=1 do={
# if leap year, concatenate the right daysInEachMonth array
if (((\$year / 4) * 4) = \$year) do={
:set daysInEachMonthConcatenatedYears (\$daysInEachMonthConcatenatedYears, \$daysInEachMonthLeapYear)
} else={
:set daysInEachMonthConcatenatedYears (\$daysInEachMonthConcatenatedYears, \$daysInEachMonth)
}
}
# must add years count
for month from=(\$date1month - 1) to=((\$date2month - 1) + ((\$yearDiff * 12) - 1)) step=1 do={
:set totalDaysBetweenMonths (\$totalDaysBetweenMonths + [:pick \$daysInEachMonthConcatenatedYears \$month])
}
}
:local globalDaysDiff (\$totalDaysBetweenMonths + \$dayDiff)
:return \$globalDaysDiff
}
:local PwdGen do={
:local random 0
:local charStrNum 1
:local p1
:local var1
:local var2
:local var3
:local newPassword
:local newPassLength [:tonum \$1];
:local charStr1 \"23456789ABCDEFGHJKLMNPQRSTUVWXYZ23456789abcdefghijkmnopqrstuvwxyz23456789\"
:local charStr2 \"cN47iKd2bLn8sQz4JAu2PD6Vm5RjTG4UrFY78XewHE3W9gMq62v7a9Z5yf5pC3k6xt9Bh8S3o\"
:local charStr3 \"uYswW92z6M5fJynQp6hGm5VSr4oR8k7A2bKq5U3FiZvc8gHP2tdL9E4jBT3X7xC6N4D8e7a93\"
:for char from=1 to=\$newPassLength step=1 do={
:set var1 ([:pick [/system clock get time] 6 8])
:set p1 ([:len [/system resource get uptime]])
:set var2 ([:pick [/system resource get uptime] (\$p1-2) \$p1])
:set var3 ((\$var1 * \$var2) / 48)
:if (\$charStrNum=1) do={
:set newPassword (\$newPassword . [:pick \$charStr1 \$var3])
}
:if (\$charStrNum=2) do={
:set newPassword (\$newPassword . [:pick \$charStr2 \$var3])
}
:if (\$charStrNum=3) do={
:set newPassword (\$newPassword . [:pick \$charStr3 \$var3])
}
:set charStrNum (\$charStrNum + 1)
:if (\$charStrNum = 4) do={
:set charStrNum 1
}
:delay ((\$var1 + \$var2 + \$var3) / 5)
}
:return [:tostr \$newPassword];
}
:global telegram;
:local mailBody;
:local mailSend false;
:foreach activeConn in=[/ip hotspot active find] do={
:if ([:len [:find [/ip hotspot active get value-name=user \$activeConn] \"$userPrefix\"]]>0) do={
:if ([/ip hotspot user get value-name=mac-address [/ip hotspot user find where name=[/ip hotspot active get value-name=user \$activeConn]]]!=[/ip hotspot active get value-name=mac-address \$activeConn]) do={
/ip hotspot user set mac-address=[/ip hotspot active get value-name=mac-address \$activeConn] [/ip hotspot user find where name=[/ip hotspot active get value-name=user \$activeConn]];
\$telegram action=send text=(\"MAC Address (*\".[/ip hotspot active get value-name=mac-address \$activeConn].\"*) has been updated to '\".[/ip hotspot active get value-name=user \$activeConn].\"'\")
:log warning (\"MAC Address (\".[/ip hotspot active get value-name=mac-address \$activeConn].\") has been updated to '\".[/ip hotspot active get value-name=user \$activeConn].\"'\");
:set mailSend true;
}
:if ([:len [:find [/ip hotspot user get value-name=comment \$userIndex] \"last connection was at\"]]>0) do={
/ip hotspot user set comment=([:pick [/ip hotspot user get value-name=comment \$userIndex] 0 ([:find [/ip hotspot user get value-name=comment \$userIndex] \"last connection was at\"]-2)].\" (last connection was at \".[/system clock get date].\" \".[/system clock get time].\")\") [/ip hotspot user find where name=[/ip hotspot active get value-name=user \$activeConn]];
} else={
/ip hotspot user set comment=([/ip dhcp-server lease get value-name=host-name [/ip dhcp-server lease find address=[/ip hotspot active get value-name=address \$activeConn]]].\" (last connection was at \".[/system clock get date].\" \".[/system clock get time].\")\") [/ip hotspot user find where name=[/ip hotspot active get value-name=user \$activeConn]];
}
}
}
:if ([:len [/ip hotspot user find where profile=$userProfile and !mac-address~\"\"]]=0) do={
:log warning \"Creating username and password...\";
:local newUser (\"$userPrefix\".[\$PwdGen $identifyLength]);
:local newPass [\$PwdGen $passwordLength];
:while ([:len [/ip hotspot user find where name=\$newUser]]>0) do={
:log error \"The user \$newUser is already exists, retry to create another user.\";
:set newUser (\"$userPrefix\".[\$PwdGen $identifyLength]);
}
/ip hotspot user add name=\$newUser password=\$newPass server=$serverName profile=$userProfile comment=(\"Auto created at \".[/system clock get date].\" \".[/system clock get time]);
\$telegram action=send text=(\"*Hotspot account created*%0A*Username*: \$newUser%0A*Password:* \$newPass\")
:log warning (\"Hotspot account created successfully (\$newUser/\$newPass)\")
:set mailSend true;
}
:foreach userIndex in=[/ip hotspot user find profile=$userProfile and server=$serverName] do={
:local loginName [/ip hotspot user get value-name=name \$userIndex];
:local loginPass [/ip hotspot user get value-name=password \$userIndex];
:local loginMAC [/ip hotspot user get value-name=mac-address \$userIndex];
:local loginComment [/ip hotspot user get value-name=comment \$userIndex];
:if ([:len [:find [/ip hotspot user get value-name=comment \$userIndex] \"last connection was at\"]]>0) do={
:local loginLastTime [:pick [/ip hotspot user get value-name=comment \$userIndex] ([:find [/ip hotspot user get value-name=comment \$userIndex] \"last connection was at\"]+23) ([:find [/ip hotspot user get value-name=comment \$userIndex] \"last connection was at\"]+23+11)];
:local loginDaysAgo [\$calcDays \$loginLastTime [/system clock get date]];
:set loginComment [:pick [/ip hotspot user get value-name=comment \$userIndex] 0 ([:find [/ip hotspot user get value-name=comment \$userIndex] \"last connection was at\"]-2)];
:if (\$loginDaysAgo>$userExpired) do={
:if ([:len [/ip hotspot user get value-name=email \$userIndex]]=0) do={
/ip hotspot user remove \$userIndex;
\$telegram action=send text=(\"*Hotspot's account '\$loginName' has been removed.*%0AThe account not being use more then \$loginDaysAgo days.\")
:log warning \"Hotspot's account '\$loginName' was removed. The account not being use more then \$loginDaysAgo days.\";
:set loginComment \"<expired>\";
} else={
/ip hotspot user disable \$userIndex;
\$telegram action=send text=(\"*Hotspot's account '\$loginName' has been disabled.*%0AThe account not being use more then \$loginDaysAgo days.\")
:log warning (\"Hotspot's account '\$loginName' was disabled. The account not being use more then \$loginDaysAgo days.\")
:set loginComment \"<disabled>\";
}
:set mailSend true;
}
:set loginComment (\$loginComment.\"\\nLast seen: \$loginLastTime (\$loginDaysAgo days ago)\");
}
:if ([:len \$loginMAC]>0) do={
:set mailBody (\$mailBody.\"\\nUsername: \$loginName\\nPassword: \$loginPass\\nMAC Address: \$loginMAC\\nComment: \$loginComment\\n\");
} else={
:set loginMAC \"<unsigned>\";
:set mailBody (\"\\nUsername: \$loginName\\nPassword: \$loginPass\\nMAC Address: \$loginMAC\\nComment: \$loginComment\\n\".\$mailBody);
}
}
:if ((\$mailSend) and ([:len \"$notifyMail\"]>0)) do={
foreach mail in=[:toarray $notifyMail] do={
:log info \"send hotspot's account list to \$mail\";
/tool e-mail send to=\$mail subject=([/system identity get name].\": Hotspot accounts update\") body=(\$mailBody);
}
}");
:if ([:len [/ip hotspot user profile find where name=$userProfile]]=0) do={
:log warning "Creating user profile '$userProfile'..."
/ip hotspot user profile add name=$userProfile mac-cookie-timeout=30d shared-users=1 on-login=$rsc
} else={
:if ([/ip hotspot user profile get value-name=on-login [/ip hotspot user profile find where name=$userProfile]]!=$rsc) do={
:log info "Update '$userProfile' (user profile) on-login action..."
/ip hotspot user profile set on-login=$rsc [find name=$userProfile]
}
}
:execute script=[/ip hotspot user profile get value-name=on-login [find name=$userProfile]]
#telegram command
:global telegram
:local fail false;
#split parameters
:local param1 [:pick $params 0 [:find $params " "]]
:local param2 [:pick $params ([:find $params " "]+1) [:len $params]]
:local param3 [:pick [:pick $params ([:find $params " "]+1) [:len $params]] ([:find [:pick $params ([:find $params " "]+1) [:len $params]] " "]+1) [:len [:pick $params ([:find $params " "]+1) [:len $params]]]]
:if ([:len [:find $param2 " "]]>0) do={
:set param2 [:pick [:pick $params ([:find $params " "]+1) [:len $params]] 0 [:find [:pick $params ([:find $params " "]+1) [:len $params]] " "]]
} else={
:set param3 ""
}
:put $params
:put $param1
:put $param2
:put $param3
#/hotspot active - returns active hotspot clients
#/hotspot user list - returns hotspot user list
#/hotspot user disable <username> - disable hotspot account
#/hotspot user enable <username> - enable hotspot account
#/hotspot user create - create random hotspot account (username and password)
#/hotspot user create <email> - create random hotspot account (username and password) assign to specific email
#/hotspot user recover - returns all hotspot account include passwords
#/hotspot user recover <username> - returns specific hotspot user's password
#/hotspot user recover <email> - send all hotspot account assigns to specific email by email"
:local calcDays do={
:local date1 [:tostr $1]
:local date2 [:tostr $2]
:local date1month [:pick $date1 0 3]
:local date1day [:pick $date1 4 6]
:local date1year [:pick $date1 7 11]
:local date2month [:pick $date2 0 3]
:local date2day [:pick $date2 4 6]
:local date2year [:pick $date2 7 11]
# month to decimal converter - http://forum.mikrotik.com/t/compare-dates/53609/1
:local months ("jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec")
:set date1month ([:find $months $date1month -1 ] + 1)
:set date2month ([:find $months $date2month -1 ] + 1)
:local globalDiff
:local yearDiff ($date2year - $date1year)
:local monthDiff ($date2month - $date1month)
:local dayDiff ($date2day - $date1day)
# check if date1 is older than date2 to avoid errors in calculation
if ($yearDiff < 0) do={
:return "error : date1 should be older that date2 (year check), exiting"
} else={
if ($yearDiff = 0) do={
if ($monthDiff <0) do={
:return "error : date1 should be older that date2 (month check), exiting"
} else={
if ($monthDiff = 0) do={
if ($dayDiff < 0) do={
:return "error : date1 should be older that date2 (day check), exiting"
}
}
}
}
}
# check if leap years - https://wiki.mikrotik.com/wiki/AutomatedBilling/MonthEndScript
:local isYear1Leap 0
:local isYear2Leap 0
if ((($date1year / 4) * 4) = $date1year) do={
:set isYear1Leap 1
}
if ((($date2year / 4) * 4) = $date2year) do={
:set isYear2Leap 1
}
# find the right amount of days between 2 months
:local daysInEachMonth ("31","28","31","30","31","30","31","31","30","31","30","31")
:local daysInEachMonthLeapYear ("31","29","31","30","31","30","31","31","30","31","30","31")
:local totalDaysBetweenMonths
# same year yearDiff = 0 so year1 = year2
if ($yearDiff = 0 and $monthDiff >= 1) do={
if ($isYear1Leap = 0) do={
for month from=($date1month - 1) to=($date2month - 1) step=1 do={
:set totalDaysBetweenMonths ($totalDaysBetweenMonths + [:pick $daysInEachMonth $month])
}
}
if ($isYear1Leap = 1) do={
for month from=($date1month - 1) to=(($date2month - 1) - 1) step=1 do={
:set totalDaysBetweenMonths ($totalDaysBetweenMonths + [:pick $daysInEachMonthLeapYear $month])
}
}
}
# different year, make concatenation of daysInEachMonth arrays first
:local daysInEachMonthConcatenatedYears
if ($yearDiff >= 1) do={
for year from=$date1year to=$date2year step=1 do={
# if leap year, concatenate the right daysInEachMonth array
if ((($year / 4) * 4) = $year) do={
:set daysInEachMonthConcatenatedYears ($daysInEachMonthConcatenatedYears, $daysInEachMonthLeapYear)
} else={
:set daysInEachMonthConcatenatedYears ($daysInEachMonthConcatenatedYears, $daysInEachMonth)
}
}
# must add years count
for month from=($date1month - 1) to=(($date2month - 1) + (($yearDiff * 12) - 1)) step=1 do={
:set totalDaysBetweenMonths ($totalDaysBetweenMonths + [:pick $daysInEachMonthConcatenatedYears $month])
}
}
:local globalDaysDiff ($totalDaysBetweenMonths + $dayDiff)
:return $globalDaysDiff
}
:local PwdGen do={
:local random 0
:local charStrNum 1
:local p1
:local var1
:local var2
:local var3
:local newPassword
:local newPassLength [:tonum $1]
:local charStr1 "23456789ABCDEFGHJKLMNPQRSTUVWXYZ23456789abcdefghijkmnopqrstuvwxyz23456789"
:local charStr2 "cN47iKd2bLn8sQz4JAu2PD6Vm5RjTG4UrFY78XewHE3W9gMq62v7a9Z5yf5pC3k6xt9Bh8S3o"
:local charStr3 "uYswW92z6M5fJynQp6hGm5VSr4oR8k7A2bKq5U3FiZvc8gHP2tdL9E4jBT3X7xC6N4D8e7a93"
:for char from=1 to=$newPassLength step=1 do={
:set var1 ([:pick [/system clock get time] 6 8])
:set p1 ([:len [/system resource get uptime]])
:set var2 ([:pick [/system resource get uptime] ($p1-2) $p1])
:set var3 (($var1 * $var2) / 48)
:if ($charStrNum=1) do={
:set newPassword ($newPassword . [:pick $charStr1 $var3])
}
:if ($charStrNum=2) do={
:set newPassword ($newPassword . [:pick $charStr2 $var3])
}
:if ($charStrNum=3) do={
:set newPassword ($newPassword . [:pick $charStr3 $var3])
}
:set charStrNum ($charStrNum + 1)
:if ($charStrNum = 4) do={
:set charStrNum 1
}
:delay (($var1 + $var2 + $var3) / 5)
}
:return [:tostr $newPassword]
}
:if ($params="active") do={
:local output
:foreach activeIndex in=[/ip hotspot active find] do={
:local activeUser ("*Username:* ".[/ip hotspot active get value-name="user" $activeIndex]."%0A")
:local userEmail ("*Email:* ".[/ip hotspot user get value-name="email" [/ip hotspot active get value-name="user" $activeIndex]]."%0A")
:local userComment ("*Comment:* ".[/ip hotspot user get value-name="comment" [/ip hotspot active get value-name="user" $activeIndex]]."%0A")
:local activeAddress ("*Address:* ".[/ip hotspot active get value-name="address" $activeIndex]."%0A")
:local activeMACAddr ("*MAC Address:* ".[/ip hotspot active get value-name="mac-address" $activeIndex]."%0A")
:local activeServer ("*Server:* ".[/ip hotspot active get value-name="server" $activeIndex]."%0A")
:local activeLoginBy ("*Login by:* ".[/ip hotspot active get value-name="login-by" $activeIndex]."%0A")
:local activeUptime ("*Uptime:* ".[/ip hotspot active get value-name="uptime" $activeIndex]."%0A")
:local activeBytes ("*Bytes In/Out*: ".([/ip hotspot active get value-name="bytes-in" $activeIndex]/1024)."k/".([/ip hotspot active get value-name="bytes-out" $activeIndex]/1024)."k"."%0A")
:set output ($output.$activeUser)
:if ([:len [:pick $userEmail ([:find $userEmail ":* "]+3) [:find $userEmail "%0A"]]]>0) do={
:set output ($output.$userEmail);
}
:if ([:len [:pick $userComment ([:find $userComment ":* "]+3) [:find $userComment "%0A"]]]>0) do={
:set output ($output.$userComment);
}
:set output ($output.$activeAddress.$activeMACAddr.$activeUptime.$activeBytes.$activeServer.$activeLoginBy."%0A")
}
:if ([:len $output]>0) do={
$telegram action=send chat=$chatid text=$output mode="Markdown"
} else={
$telegram action=send chat=$chatid text="No active hotspot users" mode="Markdown"
}
}
:if ($param1="user") do={
#list
:if ($param2="list") do={
:local output
:foreach userIndex in=[/ip hotspot user find] do={
:local userName ("*Username:* ".[/ip hotspot user get value-name="name" $userIndex]."%0A")
:local userEmail ("*Email:* ".[/ip hotspot user get value-name="email" $userIndex]."%0A")
:local userAddress ("*Address:* ".[/ip hotspot user get value-name="address" $userIndex]."%0A")
:local userMACAddr ("*MAC Address:* ".[/ip hotspot user get value-name="mac-address" $userIndex]."%0A")
:local userUptime ("*Uptime:* ".[/ip hotspot user get value-name="uptime" $userIndex]."%0A")
:local userBytes ("*Bytes In/Out*: ".([/ip hotspot user get value-name="bytes-in" $userIndex]/1024)."k/".([/ip hotspot user get value-name="bytes-out" $userIndex]/1024)."k"."%0A")
:local userComment ("*Comment:* ".[/ip hotspot user get value-name="comment" $userIndex]."%0A")
:local userServer ("*Server:* ".[/ip hotspot user get value-name="server" $userIndex]."%0A")
:local userProfile ("*Profile:* ".[/ip hotspot user get value-name="profile" $userIndex]."%0A")
:local userDisabled ("*Disabled:* ".[/ip hotspot user get value-name="disabled" $userIndex]."%0A")
:set output ($output.$userName)
:if ([:len [:pick $userEmail ([:find $userEmail ":* "]+3) [:find $userEmail "%0A"]]]>0) do={
:set output ($output.$userEmail);
}
:if ([:len [:pick $userComment ([:find $userComment ":* "]+3) [:find $userComment "%0A"]]]>0) do={
:if ([:len [:find $userComment "last connection was at"]]>0) do={
:local userLastlogin [:pick $userComment ([:find $userComment "last connection was at"]+23) ([:find $userComment "last connection was at"]+23+11)]
:local userLastseen ("*Last seen:* $userLastlogin (".[$calcDays $userLastlogin [/system clock get date]]." days ago)%0A")
:set userComment ([:pick $userComment 0 ([:find $userComment "last connection was at"]-2)]."%0A")
:set output ($output.$userComment.$userLastseen);
} else={
:set output ($output.$userComment);
}
}
:if ([:len [:pick $userAddress ([:find $userAddress ":* "]+3) [:find $userAddress "%0A"]]]>0) do={
:set output ($output.$userAddress);
}
:if ([:len [:pick $userMACAddr ([:find $userMACAddr ":* "]+3) [:find $userMACAddr "%0A"]]]>0) do={
:set output ($output.$userMACAddr);
}
:if ([:pick $userUptime ([:find $userUptime ":* "]+3) [:find $userUptime "%0A"]]!="00:00:00") do={
:set output ($output.$userUptime.$userBytes);
}
:if ([:len [:pick $userServer ([:find $userServer ":* "]+3) [:find $userServer "%0A"]]]>0) do={
:set output ($output.$userServer);
}
:if ([:len [:pick $userProfile ([:find $userProfile ":* "]+3) [:find $userProfile "%0A"]]]>0) do={
:set output ($output.$userProfile);
}
:set output ($output.$userDisabled."%0A")
}
:if ([:len $output]>0) do={
$telegram action=send chat=$chatid text=$output mode="Markdown"
} else={
$telegram action=send chat=$chatid text="User list is empty" mode="Markdown"
}
}
#disable user
:if (($param2="disable") and ([:len $param3]>0)) do={
:log warning "Disabling hotspot account..."
:do {
/ip hotspot user disable [/ip hotspot user find name="$param3"]
} on-error={
:set fail true;
:log error "Disable hotspot account ('$param3') was failed"
$telegram action=send chat=$chatid text=("Disable hotspot account ('$param3') was failed")
}
:if (!$fail) do={
:log warning "Hotspot account ('$param3') was disabled"
$telegram action=send chat=$chatid text=("Hotspot account ('$param3') was disabled")
}
}
#enable user
:if (($param2="enable") and ([:len $param3]>0)) do={
:log warning "Enabling hotspot account..."
:do {
/ip hotspot user enable [/ip hotspot user find name="$param3"]
} on-error={
:set fail true;
:log error "Enable hotspot account ('$param3') was failed"
$telegram action=send chat=$chatid text=("Enable hotspot account ('$param3') was failed")
}
:if (!$fail) do={
:log warning "Hotspot account ('$param3') was enabled"
$telegram action=send chat=$chatid text=("Hotspot account ('$param3') was enabled")
}
}
#create user
:if ($param2="create") do={
:log warning "Creating username and password..."
:local newUser ($userPrefix.[$PwdGen 4])
:local newPass [$PwdGen 5]
:local newEmail
:if (([:len [:find $param3 "@"]]>0) and ([:len [:find $param3 "."]]>0)) do={
:set newEmail $param3
}
:while ([:len [/ip hotspot user find where name=$newUser]]>0) do={
:log error "The user '$newUser' is already exists, retry to create another user."
:set newUser ($userPrefix.[$PwdGen 4])
}
/ip hotspot user add name=$newUser password=$newPass server=guests profile=generated email=$newEmail comment=("Created at ".[/system clock get date]." ".[/system clock get time]." by $from")
:log warning ("Hotspot account has been created ($newUser/$newPass)")
:if ([:len $newEmail]>0) do={
:log info "sending hotspot account information to '$param3'"
/tool e-mail send to=$param3 subject=([/system identity get name].": Hotspot account") body=("Username: $newUser\nPassword: $newPass")
:set param3 "%0A*E-mail:* $param3";
}
$telegram action=send chat=$chatid text=("*Hotspot account has been created*%0A*Username:* $newUser %0A*Password:* $newPass".$param3)
}
:if ($param2="recover") do={
:local output
:if ([:len $param3]>0) do={
:if (([:len [:find $param3 "@"]]>0) and ([:len [:find $param3 "."]]>0)) do={
:log warning "recover hotspot accounts to '$param3'"
:foreach userIndex in=[/ip hotspot user find email=$param3] do={
:if (![/ip hotspot user get value-name="disabled" $userIndex]) do={
:local userName ("Username: ".[/ip hotspot user get value-name="name" $userIndex]."\n")
:local userPassword ("Password: ".[/ip hotspot user get value-name="password" $userIndex]."\n")
:local userMACAddr ("MAC Address: ".[/ip hotspot user get value-name="mac-address" $userIndex]."\n")
:local userComment ("Comment: ".[/ip hotspot user get value-name="comment" $userIndex]."\n")
:set output ($output.$userName.$userPassword.$userMACAddr."\n")
}
}
:if ([:len $output]>0) do={
:log warning "sending recovered accounts to mail '$param3'..."
:do {
/tool e-mail send to=$param3 subject=([/system identity get name].": Recover hotspot accounts") body=$output
} on-error={
:log error "send recovered accounts by mail was failed"
}
}
} else={
:if ([:len [/ip hotspot user find where name=$param3]]>0) do={
:log warning "recover hotspot password for '$param3'"
:local output
:local userName ("*Username:* ".$param3."%0A")
:local userPassword ("*Password:* ".[/ip hotspot user get value-name="password" [/ip hotspot user find name=$param3]]."%0A")
:local userEmail ("*Email:* ".[/ip hotspot user get value-name="email" [/ip hotspot user find name=$param3]]."%0A")
:local userMACAddr ("*MAC Address:* ".[/ip hotspot user get value-name="mac-address" [/ip hotspot user find name=$param3]]."%0A")
:local userComment ("*Comment:* ".[/ip hotspot user get value-name="comment" [/ip hotspot user find name=$param3]]."%0A")
:local userUptime ("*Uptime:* ".[/ip hotspot user get value-name="uptime" [/ip hotspot user find name=$param3]]."%0A")
:local userBytes ("*Bytes In/Out:* ".([/ip hotspot user get value-name="bytes-in" [/ip hotspot user find name=$param3]]/1024)."k/".([/ip hotspot user get value-name="bytes-out" [/ip hotspot user find name=$param3]]/1024)."k"."%0A")
:set output ($output.$userName.$userPassword)
:if ([:len [:pick $userEmail ([:find $userEmail ":* "]+3) [:find $userEmail "%0A"]]]>0) do={
:set output ($output.$userEmail);
}
:if ([:len [:pick $userComment ([:find $userComment ":* "]+3) [:find $userComment "%0A"]]]>0) do={
:if ([:len [:find $userComment "last connection was at"]]>0) do={
:local userLastlogin [:pick $userComment ([:find $userComment "last connection was at"]+23) ([:find $userComment "last connection was at"]+23+11)]
:local userLastseen ("*Last seen:* $userLastlogin (".[$calcDays $userLastlogin [/system clock get date]]." days ago)%0A")
:set userComment ([:pick $userComment 0 ([:find $userComment "last connection was at"]-2)]."%0A")
:set output ($output.$userComment.$userLastseen);
} else={
:set output ($output.$userComment);
}
}
:if ([:len [:pick $userMACAddr ([:find $userMACAddr ":* "]+3) [:find $userMACAddr "%0A"]]]>0) do={
:set output ($output.$userMACAddr);
}
:if ([:pick $userUptime ([:find $userUptime ":* "]+3) [:find $userUptime "%0A"]]!="00:00:00") do={
:set output ($output.$userUptime.$userBytes);
}
:set output ($output.$userDisabled."%0A")
:put $output
$telegram action=send chat=$chatid text=$output
}
}
} else={
:foreach userIndex in=[/ip hotspot user find] do={
:local userName ("*Username:* ".[/ip hotspot user get value-name="name" $userIndex]."%0A")
:local userPassword ("*Password:* ".[/ip hotspot user get value-name="password" $userIndex]."%0A")
:local userEmail ("*Email:* ".[/ip hotspot user get value-name="email" $userIndex]."%0A")
:local userComment ("*Comment:* ".[/ip hotspot user get value-name="comment" $userIndex]."%0A")
:local userMACAddr ("*MAC Address:* ".[/ip hotspot user get value-name="mac-address" $userIndex]."%0A")
:local userDisabled ("*Disabled:* ".[/ip hotspot user get value-name="disabled" $userIndex]."%0A")
:set output ($output.$userName.$userPassword)
:if ([:len [:pick $userEmail ([:find $userEmail ":* "]+3) [:find $userEmail "%0A"]]]>0) do={
:set output ($output.$userEmail);
}
:if ([:len [:pick $userComment ([:find $userComment ":* "]+3) [:find $userComment "%0A"]]]>0) do={
:if ([:len [:find $userComment "last connection was at"]]>0) do={
:local userLastlogin [:pick $userComment ([:find $userComment "last connection was at"]+23) ([:find $userComment "last connection was at"]+23+11)]
:local userLastseen ("*Last seen:* $userLastlogin (".[$calcDays $userLastlogin [/system clock get date]]." days ago)%0A")
:set userComment ([:pick $userComment 0 ([:find $userComment "last connection was at"]-2)]."%0A")
:set output ($output.$userComment.$userLastseen);
} else={
:set output ($output.$userComment);
}
}
:if ([:len [:pick $userMACAddr ([:find $userMACAddr ":* "]+3) [:find $userMACAddr "%0A"]]]>0) do={
:set output ($output.$userMACAddr);
}
:set output ($output.$userDisabled."%0A")
}
:if ([:len $output]>0) do={
$telegram action=send chat=$chatid text=$output mode="Markdown"
} else={
$telegram action=send chat=$chatid text="User list is empty" mode="Markdown"
}
}
}
}