# -------------------------------- JParseFunctions --------------------------------------------------- # ------------------------------- fJParsePrint ---------------------------------------------------------------- :global fJParsePrint :if (!any $fJParsePrint) do={ :global fJParsePrint do={ :global JParseOut :local TempPath :global fJParsePrint :if ([:len $1] = 0) do={ :set $1 "\$JParseOut" :set $2 $JParseOut } :foreach k,v in=$2 do={ :if ([:typeof $k] = "str") do={ :set k "\"$k\"" } :set TempPath ($1. "->" . $k) :if ([:typeof $v] = "array") do={ :if ([:len $v] > 0) do={ $fJParsePrint $TempPath $v } else={ :put "$TempPath = [] ($[:typeof $v])" } } else={ :put "$TempPath = $v ($[:typeof $v])" } } }} # ------------------------------- fJParsePrintVar ---------------------------------------------------------------- :global fJParsePrintVar :if (!any $fJParsePrintVar) do={ :global fJParsePrintVar do={ :global JParseOut :local TempPath :global fJParsePrintVar :local fJParsePrintRet "" :if ([:len $1] = 0) do={ :set $1 "\$JParseOut" :set $2 $JParseOut } :foreach k,v in=$2 do={ :if ([:typeof $k] = "str") do={ :set k "\"$k\"" } :set TempPath ($1. "->" . $k) :if ($fJParsePrintRet != "") do={ :set fJParsePrintRet ($fJParsePrintRet . "\r\n") } :if ([:typeof $v] = "array") do={ :if ([:len $v] > 0) do={ :set fJParsePrintRet ($fJParsePrintRet . [$fJParsePrintVar $TempPath $v]) } else={ :set fJParsePrintRet ($fJParsePrintRet . "$TempPath = [] ($[:typeof $v])") } } else={ :set fJParsePrintRet ($fJParsePrintRet . "$TempPath = $v ($[:typeof $v])") } } :return $fJParsePrintRet }} # ------------------------------- fJSkipWhitespace ---------------------------------------------------------------- :global fJSkipWhitespace :if (!any $fJSkipWhitespace) do={ :global fJSkipWhitespace do={ :global Jpos :global JSONIn :global Jdebug :while ($Jpos < [:len $JSONIn] and ([:pick $JSONIn $Jpos] ~ "[ \r\n\t]")) do={ :set Jpos ($Jpos + 1) } :if ($Jdebug) do={:put "fJSkipWhitespace: Jpos=$Jpos Char=$[:pick $JSONIn $Jpos]"} }} # -------------------------------- fJParse --------------------------------------------------------------- :global fJParse :if (!any $fJParse) do={ :global fJParse do={ :global Jpos :global JSONIn :global Jdebug :global fJSkipWhitespace :local Char :if (!$1) do={ :set Jpos 0 } $fJSkipWhitespace :set Char [:pick $JSONIn $Jpos] :if ($Jdebug) do={:put "fJParse: Jpos=$Jpos Char=$Char"} :if ($Char="{") do={ :set Jpos ($Jpos + 1) :global fJParseObject :return [$fJParseObject] } else={ :if ($Char="[") do={ :set Jpos ($Jpos + 1) :global fJParseArray :return [$fJParseArray] } else={ :if ($Char="\"") do={ :set Jpos ($Jpos + 1) :global fJParseString :return [$fJParseString] } else={ # :if ([:pick $JSONIn $Jpos ($Jpos+2)]~"^-\?[0-9]") do={ :if ($Char~"[eE0-9.+-]") do={ :global fJParseNumber :return [$fJParseNumber] } else={ :if ($Char="n" and [:pick $JSONIn $Jpos ($Jpos+4)]="null") do={ :set Jpos ($Jpos + 4) :return [] } else={ :if ($Char="t" and [:pick $JSONIn $Jpos ($Jpos+4)]="true") do={ :set Jpos ($Jpos + 4) :return true } else={ :if ($Char="f" and [:pick $JSONIn $Jpos ($Jpos+5)]="false") do={ :set Jpos ($Jpos + 5) :return false } else={ :put "Err.Raise 8732. No JSON object could be fJParseed" :set Jpos ($Jpos + 1) :return [] } } } } } } } }} #-------------------------------- fJParseString --------------------------------------------------------------- :global fJParseString :if (!any $fJParseString) do={ :global fJParseString do={ :global Jpos :global JSONIn :global Jdebug :global fUnicodeToUTF8 :local Char :local StartIdx :local Char2 :local TempString "" :local UTFCode :local Unicode :set StartIdx $Jpos :set Char [:pick $JSONIn $Jpos] :if ($Jdebug) do={:put "fJParseString: Jpos=$Jpos Char=$Char"} :while ($Jpos < [:len $JSONIn] and $Char != "\"") do={ :if ($Char="\\") do={ :set Char2 [:pick $JSONIn ($Jpos + 1)] :if ($Char2 = "u") do={ :set UTFCode [:tonum "0x$[:pick $JSONIn ($Jpos+2) ($Jpos+6)]"] :if ($UTFCode>=0xD800 and $UTFCode<=0xDFFF) do={ # Surrogate pair :set Unicode (($UTFCode & 0x3FF) << 10) :set UTFCode [:tonum "0x$[:pick $JSONIn ($Jpos+8) ($Jpos+12)]"] :set Unicode ($Unicode | ($UTFCode & 0x3FF) | 0x10000) :set TempString ($TempString . [:pick $JSONIn $StartIdx $Jpos] . [$fUnicodeToUTF8 $Unicode]) :set Jpos ($Jpos + 12) } else= { # Basic Multilingual Plane (BMP) :set Unicode $UTFCode :set TempString ($TempString . [:pick $JSONIn $StartIdx $Jpos] . [$fUnicodeToUTF8 $Unicode]) :set Jpos ($Jpos + 6) } :set StartIdx $Jpos :if ($Jdebug) do={:put "fJParseString Unicode: $Unicode"} } else={ :if ($Char2 ~ "[\\bfnrt\"]") do={ :if ($Jdebug) do={:put "fJParseString escape: Char+Char2 $Char$Char2"} :set TempString ($TempString . [:pick $JSONIn $StartIdx $Jpos] . [[:parse "(\"\\$Char2\")"]]) :set Jpos ($Jpos + 2) :set StartIdx $Jpos } else={ :if ($Char2 = "/") do={ :if ($Jdebug) do={:put "fJParseString /: Char+Char2 $Char$Char2"} :set TempString ($TempString . [:pick $JSONIn $StartIdx $Jpos] . "/") :set Jpos ($Jpos + 2) :set StartIdx $Jpos } else={ :put "Err.Raise 8732. Invalid escape" :set Jpos ($Jpos + 2) } } } } else={ :set Jpos ($Jpos + 1) } :set Char [:pick $JSONIn $Jpos] } :set TempString ($TempString . [:pick $JSONIn $StartIdx $Jpos]) :set Jpos ($Jpos + 1) :if ($Jdebug) do={:put "fJParseString: $TempString"} :return $TempString }} #-------------------------------- fJParseNumber --------------------------------------------------------------- :global fJParseNumber :if (!any $fJParseNumber) do={ :global fJParseNumber do={ :global Jpos :local StartIdx :global JSONIn :global Jdebug :local NumberString :local Number :set StartIdx $Jpos :set Jpos ($Jpos + 1) :while ($Jpos < [:len $JSONIn] and [:pick $JSONIn $Jpos]~"[eE0-9.+-]") do={ :set Jpos ($Jpos + 1) } :set NumberString [:pick $JSONIn $StartIdx $Jpos] :set Number [:tonum $NumberString] :if ([:typeof $Number] = "num") do={ :if ($Jdebug) do={:put "fJParseNumber: StartIdx=$StartIdx Jpos=$Jpos $Number ($[:typeof $Number])"} :return $Number } else={ :if ($Jdebug) do={:put "fJParseNumber: StartIdx=$StartIdx Jpos=$Jpos $NumberString ($[:typeof $NumberString])"} :return $NumberString } }} #-------------------------------- fJParseArray --------------------------------------------------------------- :global fJParseArray :if (!any $fJParseArray) do={ :global fJParseArray do={ :global Jpos :global JSONIn :global Jdebug :global fJParse :global fJSkipWhitespace :local Value :local ParseArrayRet [:toarray ""] $fJSkipWhitespace :while ($Jpos < [:len $JSONIn] and [:pick $JSONIn $Jpos]!= "]") do={ :set Value [$fJParse true] :set ($ParseArrayRet->([:len $ParseArrayRet])) $Value :if ($Jdebug) do={:put "fJParseArray: Value="; :put $Value} $fJSkipWhitespace :if ([:pick $JSONIn $Jpos] = ",") do={ :set Jpos ($Jpos + 1) $fJSkipWhitespace } } :set Jpos ($Jpos + 1) # :if ($Jdebug) do={:put "ParseArrayRet: "; :put $ParseArrayRet} :return $ParseArrayRet }} # -------------------------------- fJParseObject --------------------------------------------------------------- :global fJParseObject :if (!any $fJParseObject) do={ :global fJParseObject do={ :global Jpos :global JSONIn :global Jdebug :global fJSkipWhitespace :global fJParseString :global fJParse # Syntax :local ParseObjectRet ({}) don't work in recursive call, use [:toarray ""] for empty array!!! :local ParseObjectRet [:toarray ""] :local Key :local Value :local ExitDo false $fJSkipWhitespace :while ($Jpos < [:len $JSONIn] and [:pick $JSONIn $Jpos]!="}" and !$ExitDo) do={ :if ([:pick $JSONIn $Jpos]!="\"") do={ :put "Err.Raise 8732. Expecting property name" :set ExitDo true } else={ :set Jpos ($Jpos + 1) :set Key [$fJParseString] $fJSkipWhitespace :if ([:pick $JSONIn $Jpos] != ":") do={ :put "Err.Raise 8732. Expecting : delimiter" :set ExitDo true } else={ :set Jpos ($Jpos + 1) :set Value [$fJParse true] :set ($ParseObjectRet->$Key) $Value :if ($Jdebug) do={:put "fJParseObject: Key=$Key Value="; :put $Value} $fJSkipWhitespace :if ([:pick $JSONIn $Jpos]=",") do={ :set Jpos ($Jpos + 1) $fJSkipWhitespace } } } } :set Jpos ($Jpos + 1) # :if ($Jdebug) do={:put "ParseObjectRet: "; :put $ParseObjectRet} :return $ParseObjectRet }} # ------------------- fByteToEscapeChar ---------------------- :global fByteToEscapeChar :if (!any $fByteToEscapeChar) do={ :global fByteToEscapeChar do={ # :set $1 [:tonum $1] :return [[:parse "(\"\\$[:pick "0123456789ABCDEF" (($1 >> 4) & 0xF)]$[:pick "0123456789ABCDEF" ($1 & 0xF)]\")"]] }} # ------------------- fUnicodeToUTF8---------------------- :global fUnicodeToUTF8 :if (!any $fUnicodeToUTF8) do={ :global fUnicodeToUTF8 do={ :global fByteToEscapeChar # :local Ubytes [:tonum $1] :local Nbyte :local EscapeStr "" :if ($1 < 0x80) do={ :set EscapeStr [$fByteToEscapeChar $1] } else={ :if ($1 < 0x800) do={ :set Nbyte 2 } else={ :if ($1 < 0x10000) do={ :set Nbyte 3 } else={ :if ($1 < 0x20000) do={ :set Nbyte 4 } else={ :if ($1 < 0x4000000) do={ :set Nbyte 5 } else={ :if ($1 < 0x80000000) do={ :set Nbyte 6 } } } } } :for i from=2 to=$Nbyte do={ :set EscapeStr ([$fByteToEscapeChar ($1 & 0x3F | 0x80)] . $EscapeStr) :set $1 ($1 >> 6) } :set EscapeStr ([$fByteToEscapeChar (((0xFF00 >> $Nbyte) & 0xFF) | $1)] . $EscapeStr) } :return $EscapeStr }} # ------------------- End JParseFunctions----------------------
:do {/tool fetch url="https://api.telegram.org/bot$TToken/getWebhookInfo" dst-path=j.txt} on-error={:put "getWebhookInfo error"};
[admin@MikroTik] > :put [/file get j.txt contents]; {"ok":true,"result":{"url":"https://*****:8443","has_custom_certificate":false,"pending_update_count":0,"last_error_date":1524565055,"last_error_message":"Connection timed out","max_connections":4 0}}
:set JSONIn [/file get j.txt contents]
:set JParseOut [$fJParse];
[admin@MikroTik] > :put $JParseOut ok=true;result=has_custom_certificate=false;max_connections=40;pending_update_count=0;url=https://*****.ru:8443
[admin@MikroTik] > :put ($JParseOut->"result") has_custom_certificate=false;max_connections=40;pending_update_count=0;url=https://*****:8443
[admin@MikroTik] > :put ($JParseOut->"result"->"max_connections") 40
[admin@MikroTik] > :put [:typeof ($JParseOut->"result")] array
[admin@MikroTik] > :put [:typeof ($JParseOut->"result"->"max_connections")] num
[admin@MikroTik] > :put [:typeof ($JParseOut->"result"->"url")] str
:global fJParsePrint :if (!any $fJParsePrint) do={ :global fJParsePrint do={ :global JParseOut :local TempPath :global fJParsePrint :if ([:len $1] = 0) do={ :set $1 "\$JParseOut" :set $2 $JParseOut } :foreach k,v in=$2 do={ :if ([:typeof $k] = "str") do={ :set k "\"$k\"" } :set TempPath ($1. "->" . $k) :if ([:typeof $v] = "array") do={ :if ([:len $v] > 0) do={ $fJParsePrint $TempPath $v } else={ :put "$TempPath = [] ($[:typeof $v])" } } else={ :put "$TempPath = $v ($[:typeof $v])" } } }}
[admin@MikroTik] > $fJParsePrint $JParseOut->"ok" = true (bool) $JParseOut->"result"->"has_custom_certificate" = false (bool) $JParseOut->"result"->"last_error_date" = 1524483204 (num) $JParseOut->"result"->"last_error_message" = Connection timed out (str) $JParseOut->"result"->"max_connections" = 40 (num) $JParseOut->"result"->"pending_update_count" = 0 (num) $JParseOut->"result"->"url" = https://*****.ru:8443 (str)
$fJParsePrint $TempPath $v
[admin@MikroTik] > $fJParsePrint "home" $JParseOut home->"ok" = true (bool) home->"result"->"has_custom_certificate" = false (bool) home->"result"->"last_error_date" = 1524483204 (num) home->"result"->"last_error_message" = Connection timed out (str) home->"result"->"max_connections" = 40 (num) home->"result"->"pending_update_count" = 0 (num) home->"result"->"url" = https://*****.ru:8443 (str)
:global fByteToEscapeChar :if (!any $fByteToEscapeChar) do={ :global fByteToEscapeChar do={ # :set $1 [:tonum $1] :return [[:parse "(\"\\$[:pick "0123456789ABCDEF" (($1 >> 4) & 0xF)]$[:pick "0123456789ABCDEF" ($1 & 0xF)]\")"]] }}
[admin@MikroTik] > :put "\2B" +
:put [:parse "(\"\\$[:pick "0123456789ABCDEF" ((0x2B >> 4) & 0xF)]$[:pick "0123456789ABCDEF" (0x2B & 0xF)]\")"] (<%% + )
[admin@MikroTik] > :put [[:parse "(\"\\$[:pick "0123456789ABCDEF" ((0x2B >> 4) & 0xF)]$[:pick "0123456789ABCDEF" (0x2B & 0xF)]\")"]] +
/system script run JParseFunctions :global TToken "12312312:32131231231" :global TChatId "43242342423" :global Toffset :if ([:typeof $Toffset] != "num") do={:set Toffset 0} /tool fetch url="https://api.telegram.org/bot$TToken/getUpdates\?chat_id=$TChatId&offset=$Toffset" dst-path=j.txt #:delay 2 :global JSONIn [/file get j.txt contents] :global fJParse :global fJParsePrintVar :global Jdebug false :global JParseOut [$fJParse] :local Results ($JParseOut->"result") :if ([:len $Results]>0) do={ :foreach k,v in=$Results do={ :if (any ($v->"message"->"text")) do={ :if ($v->"message"->"text" ~ "uptime") do={ /tool fetch url="https://api.telegram.org/bot$TToken/sendmessage\?chat_id=$TChatId" http-method=post http-data="text=$[/system resource get uptime]" keep-result=no } else={ :if ($v->"message"->"text" ~ "ip") do={ /tool fetch url="https://api.telegram.org/bot$TToken/sendmessage\?chat_id=$TChatId" http-method=post http-data="text=$[/ip dhcp-client print as-value]" keep-result=no } else={ :if ($v->"message"->"text" ~ "parse") do={ /tool fetch url="https://api.telegram.org/bot$TToken/sendmessage\?chat_id=$TChatId" http-method=post http-data="text=$[$fJParsePrintVar]" keep-result=no } else={ /tool fetch url="https://api.telegram.org/bot$TToken/sendmessage\?chat_id=$TChatId" http-method=post http-data="text=$($v->"message"->"text")" keep-result=no } } } } :set $Toffset ($v->"update_id" + 1) } } else={ :set $Toffset 0 }
:if ([:len [/system script job find script=TelegramWebhookBot]] <= 1) do={...}
:if ([:len [/system script job find script=TelegramWebhookBot]] <= 1) do={ #:while (true) do={ :global TelegramWebhookPackets :local TWebhookURL "https://www.yourdomain" :local TWebhookPort "8443" # Create Telegram webhook mangle action :if ([:len [/ip firewall mangle find dst-port=$TWebhookPort]] = 0) do={ /ip firewall mangle add action=accept chain=prerouting connection-state=new dst-port=$TWebhookPort protocol=tcp src-address=149.154.167.192/26 comment="Telegram" } :if ([/ip firewall mangle get [find dst-port=$TWebhookPort] packets] != $TelegramWebhookPackets) do={ /system script run JParseFunctions :local TToken "123123123:123123123123123" :local TChatId "3213123123123" :global TelegramOffset :global fJParse :global fJParsePrintVar :global Jdebug false :global JSONIn :global JParseOut :if ([:typeof $TelegramOffset] != "num") do={:set TelegramOffset 0} :put "getWebhookInfo" :do {/tool fetch url="https://api.telegram.org/bot$TToken/getWebhookInfo" dst-path=j.txt} on-error={:put "getWebhookInfo error"} :set JSONIn [/file get j.txt contents] :set JParseOut [$fJParse] :put $JParseOut :if ($JParseOut->"result"->"pending_update_count" > 0) do={ :put "pending_update_count > 0" :do {/tool fetch url="https://api.telegram.org/bot$TToken/deleteWebhook" http-method=get keep-result=no} on-error={:put "deleteWebhook error"} :put "getUpdates" :do {/tool fetch url="https://api.telegram.org/bot$TToken/getUpdates\?chat_id=$TChatId&offset=$TelegramOffset" dst-path=j.txt} on-error={:put "getUpdates error"} :set JSONIn [/file get j.txt contents] :set JParseOut [$fJParse] :put $JParseOut :if ([:len ($JParseOut->"result")] > 0) do={ :foreach k,v in=($JParseOut->"result") do={ :if (any ($v->"message"->"text")) do={ :if ($v->"message"->"text" ~ "uptime") do={ :do {/tool fetch url="https://api.telegram.org/bot$TToken/sendmessage\?chat_id=$TChatId" http-method=post http-data="text=$[/system resource get uptime]" keep-result=no} on-error={:put "sendmessage error"} } else={ :if ($v->"message"->"text" ~ "ip") do={ :do {/tool fetch url="https://api.telegram.org/bot$TToken/sendmessage\?chat_id=$TChatId" http-method=post http-data="text=$[/ip dhcp-client print as-value]" keep-result=no} on-error={:put "sendmessage error"} } else={ :if ($v->"message"->"text" ~ "parse") do={ :do {/tool fetch url="https://api.telegram.org/bot$TToken/sendmessage\?chat_id=$TChatId" http-method=post http-data="text=$[$fJParsePrintVar]" keep-result=no} on-error={:put "sendmessage error"} } else={ :if ($v->"message"->"text" ~ "add") do={ :local addIP [:toip [:pick ($v->"message"->"text") 4 [:len ($v->"message"->"text")]]] :if ([:typeof $addIP] = "ip") do={ :do {/ip firewall address-list add address=$addIP list=ExtAccessIPList timeout=10m comment="temp"} on-error={:put "ip in list error"} } :local Str1 "" :foreach item in=[/ip firewall address-list print as-value where list=ExtAccessIPList and dynamic] do={:set Str1 ($Str1 . "$($item->"address") $($item->"timeout") $($item->"comment")\r\n")} :do {/tool fetch url="https://api.telegram.org/bot$TToken/sendmessage\?chat_id=$TChatId" http-method=post http-data="text=$Str1" keep-result=no} on-error={:put "sendmessage error"} } else={ :put ($v->"message"->"text") :do {/tool fetch url="https://api.telegram.org/bot$TToken/sendmessage\?chat_id=$TChatId" http-method=post http-data="text=$($v->"message"->"text")" keep-result=no} on-error={:put "sendmessage error"} } } } } } :set $TelegramOffset ($v->"update_id" + 1) } } else={ # :set $TelegramOffset 0 } :put "getUpdates" :do {/tool fetch url="https://api.telegram.org/bot$TToken/getUpdates\?chat_id=$TChatId&offset=$TelegramOffset" keep-result=no} on-error={:put "getUpdates error"} :put "setWebhook" :do {/tool fetch url="https://api.telegram.org/bot$TToken/setWebhook\?url=$TWebhookURL:$TWebhookPort" keep-result=no} on-error={:put "setWebhook error"} } else={ :if ($JParseOut->"result"->"url"="") do={ :put "setWebhook" :do {/tool fetch url="https://api.telegram.org/bot$TToken/setWebhook\?url=$TWebhookURL:$TWebhookPort" keep-result=no} on-error={:put "setWebhook error"} } } :set TelegramWebhookPackets [/ip firewall mangle get [find dst-port=$TWebhookPort] packets] :put "--------------------------------------------------" } }
>add 1.1.1.1
>> 90.0.0.97 h*******
100.0.0.157 6*******
90.0.0.2 i*******.ru
100.00.66 b*******.ru
1.1.1.1 00:10:00 temp
Source: https://habr.com/ru/post/337978/
All Articles