PDA

Επιστροφή στο Forum : [Scripts] Προώθηση SMS μέσω Telegram



WhatTheIanni
22-07-22, 14:49
Σας παραθέτω ένα κύριο script & δύο helper scripts για να προωθεί το Tik σας μέσω Telegram τα SMS που έρχονται στο LTE interface.

Υπάρχουν κάποιες έτοιμες λύσεις αλλά προϋποθέτουν το loading ενός σκασμού από global functions και δεν μου άρεσε η ιδέα, οπότε το έφτιαξα μόνος μου.

Τι κάνει το script:
Τραβάει την λίστα των SMS από το Inbox, και αν υπάρχουν SMS:
1. Παίρνει για κάθε μήνυμα τον αποστολέα και το περιεχόμενο.
2. Τα κάνει URL Encode για να στηθεί σωστά το request στο Telegram API.
3. Τα συγκεντρώνει όλα σε ένα μήνυμα με διαχωριστικές παύλες για οικονομία request.
4. Εκτελεί το request στο Telegram API για την αποστολή του μηνύματος.
5. Αν πετύχει το request, σβήνει τα SMS από το Inbox

Προαπαιτούμενα:
- Να έχετε φτιάξει ένα bot μέσω του @BotFather (https://t.me/BotFather) (απόστολή /newbot, ακολουθείτε οδηγίες και στο τέλος παίρνετε το token που σας επιστρέφει ο @BotFather)
- Να πάρετε το chat id σας (ανοίγετε κουβέντα με το @getidsbot (https://t.me/getidsbot), πατάτε [START] και στις πληροφορίες που θα σας δώσει, κάτω από το You είναι το chat id σας)

Βήμα 1: Δημιουργία script με τον helper για το URL Encoding

Πάμε System -> Scripts και φτιάχνουμε ένα νέο script με όνομα UrlEncode και περιεχόμενο:




:global UrlEncode;
:set UrlEncode do={
:local Input [ :tostr $1 ];
:log info "UrlEncode started";
:log info "input $Input";
:if ([ :len $Input ] = 0) do={
:return "";
}

:local Return "";
:local Chars ("\n\r !\"#\$%&'()*+,:;<=>\?@[\\]^`{|}~");
:local Subs { "%0A"; "%0D"; "%20"; "%21"; "%22"; "%23"; "%24"; "%25"; "%26"; "%27";
"%28"; "%29"; "%2A"; "%2B"; "%2C"; "%3A"; "%3B"; "%3C"; "%3D"; "%3E"; "%3F";
"%40"; "%5B"; "%5C"; "%5D"; "%5E"; "%60"; "%7B"; "%7C"; "%7D"; "%7E" };
:log info "UrlEncode middle";
:log info "$Subs";
:for I from=0 to=([ :len $Input ] - 1) do={
:local Char [ :pick $Input $I ];
:local Replace [ :find $Chars $Char ];

:if ([ :typeof $Replace ] = "num") do={
:set Char ($Subs->$Replace);
}
:set Return ($Return . $Char);
}
:log info "UrlEncode ended";
:log info "return value $Return";
:return $Return;
}


Πηγή: routeros-scripts @ GitHub (https://github.com/eworm-de/routeros-scripts/blob/50178e2a3c6067c4148e3f814b60e51d1c8ced69/global-functions#L1175)



Βήμα 2: Δημιουργία script με τον helper για το JSON Parsing

Πάμε System -> Scripts και φτιάχνουμε ένα νέο script με όνομα JParseFunctions και περιεχόμενο:




# -------------------------------- 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
}}

# ------------------- Load JSON from arg --------------------------------
global JSONLoads
if (!any $JSONLoads) do={ global JSONLoads do={
global JSONIn $1
global fJParse
local ret [$fJParse]
set JSONIn
global Jpos; set Jpos
global Jdebug; if (!$Jdebug) do={set Jdebug}
return $ret
}}

# ------------------- Load JSON from file --------------------------------
global JSONLoad
if (!any $JSONLoad) do={ global JSONLoad do={
if ([len [/file find name=$1]] > 0) do={
global JSONLoads
return [$JSONLoads [/file get $1 contents]]
}
}}

# ------------------- Unload JSON parser library ----------------------
global JSONUnload
if (!any $JSONUnload) do={ global JSONUnload do={
global JSONIn; set JSONIn
global Jpos; set Jpos
global Jdebug; set Jdebug
global fByteToEscapeChar; set fByteToEscapeChar
global fJParse; set fJParse
global fJParseArray; set fJParseArray
global fJParseNumber; set fJParseNumber
global fJParseObject; set fJParseObject
global fJParsePrint; set fJParsePrint
global fJParsePrintVar; set fJParsePrintVar
global fJParseString; set fJParseString
global fJSkipWhitespace; set fJSkipWhitespace
global fUnicodeToUTF8; set fUnicodeToUTF8
global JSONLoads; set JSONLoads
global JSONLoad; set JSONLoad
global JSONUnload; set JSONUnload
}}
# ------------------- End JParseFunctions----------------------


Πηγή: mikrotik-json-parser @ GitHub (https://github.com/Winand/mikrotik-json-parser)



Βήμα 3: Δημιουργία του βασικού script ελέγχου και προώθησης

Πάμε System -> Scripts και φτιάχνουμε ένα νέο script με όνομα sms-telegram και περιεχόμενο:

(Αντικαθιστάτε τα {BOT_TOKEN} και {CHAT_ID} με αυτά που αναφέρθηκαν στα προαπαιτούμενα.)




:local botToken "{BOT_TOKEN}";
:local chatId "{CHAT_ID}";
:local parseMode "HTML";
:local smsPhone;
:local encodedPhone;
:local smsMessage;
:local encodedMessage;
:local smsEntry;
:local totalContent;

:local messageList [/tool sms inbox find];
:local messageListCount [:len $messageList];
:if ($messageListCount > 0) do={
/system script run "UrlEncode"; global UrlEncode;
:foreach i in=$messageList do={
:set smsPhone ("<b>" . [/tool sms inbox get $i phone] . "</b>");
:set encodedPhone [$UrlEncode $smsPhone];
:set smsMessage [/tool sms inbox get $i message];
:set encodedMessage [$UrlEncode $smsMessage];
:set smsEntry ($encodedPhone . "%0A" . $encodedMessage);
:set totalContent ($totalContent . $smsEntry . "%0A%2D%2D%2D%0A");
}
:local result [:tool fetch url="https://api.telegram.org/bot$botToken/sendMessage?parse_mode=$parseMode&chat_id=-$chatId&text=$totalContent" as-value output=user];
:local resultData ($result->"data");
/system script run "JParseFunctions"; global JSONLoads; global JSONUnload
:local finishResult ([$JSONLoads $resultData]->"ok");
:if ($finishResult = true) do={
:log info "SMS -> Telegram: Successfully forwarded $messageListCount SMS messages";
:foreach i in=$messageList do={
/tool sms inbox remove $i;
}
} else {
:log error "SMS -> Telegram: Error while forwarding $messageListCount SMS messages";
}
$JSONUnload;
}


Πηγή: @WhatTheIanni



Βήμα 4: Δημιουργία Scheduler entry για να εκτελείται περιοδικά το script μας

Πάμε System -> Scheduler και φτιάχνουμε ένα νέο entry με ότι όνομα θέλουμε, ορίζουμε το Start Time σε startup ώστε να ξεκινάει μετά από κάθε reboot και το Interval ανάλογα με το πόσο συχνά θέλουμε να γίνεται ο έλεγχος.

Στο On Event ορίζουμε:


/system/script/run sms-telegram;

jkarabas
04-01-23, 17:59
Σας παραθέτω ένα κύριο script & δύο helper scripts για να προωθεί το Tik σας μέσω Telegram τα SMS που έρχονται στο LTE interface.

Υπάρχουν κάποιες έτοιμες λύσεις αλλά προϋποθέτουν το loading ενός σκασμού από global functions και δεν μου άρεσε η ιδέα, οπότε το έφτιαξα μόνος μου.

Τι κάνει το script:
Τραβάει την λίστα των SMS από το Inbox, και αν υπάρχουν SMS:
1. Παίρνει για κάθε μήνυμα τον αποστολέα και το περιεχόμενο.
2. Τα κάνει URL Encode για να στηθεί σωστά το request στο Telegram API.
3. Τα συγκεντρώνει όλα σε ένα μήνυμα με διαχωριστικές παύλες για οικονομία request.
4. Εκτελεί το request στο Telegram API για την αποστολή του μηνύματος.
5. Αν πετύχει το request, σβήνει τα SMS από το Inbox

Προαπαιτούμενα:
- Να έχετε φτιάξει ένα bot μέσω του @BotFather (https://t.me/BotFather) (απόστολή /newbot, ακολουθείτε οδηγίες και στο τέλος παίρνετε το token που σας επιστρέφει ο @BotFather)
- Να πάρετε το chat id σας (ανοίγετε κουβέντα με το @getidsbot (https://t.me/getidsbot), πατάτε [START] και στις πληροφορίες που θα σας δώσει, κάτω από το You είναι το chat id σας)

Βήμα 1: Δημιουργία script με τον helper για το URL Encoding

Πάμε System -> Scripts και φτιάχνουμε ένα νέο script με όνομα UrlEncode και περιεχόμενο:




:global UrlEncode;
:set UrlEncode do={
:local Input [ :tostr $1 ];
:log info "UrlEncode started";
:log info "input $Input";
:if ([ :len $Input ] = 0) do={
:return "";
}

:local Return "";
:local Chars ("\n\r !\"#\$%&'()*+,:;<=>\?@[\\]^`{|}~");
:local Subs { "%0A"; "%0D"; "%20"; "%21"; "%22"; "%23"; "%24"; "%25"; "%26"; "%27";
"%28"; "%29"; "%2A"; "%2B"; "%2C"; "%3A"; "%3B"; "%3C"; "%3D"; "%3E"; "%3F";
"%40"; "%5B"; "%5C"; "%5D"; "%5E"; "%60"; "%7B"; "%7C"; "%7D"; "%7E" };
:log info "UrlEncode middle";
:log info "$Subs";
:for I from=0 to=([ :len $Input ] - 1) do={
:local Char [ :pick $Input $I ];
:local Replace [ :find $Chars $Char ];

:if ([ :typeof $Replace ] = "num") do={
:set Char ($Subs->$Replace);
}
:set Return ($Return . $Char);
}
:log info "UrlEncode ended";
:log info "return value $Return";
:return $Return;
}


Πηγή: routeros-scripts @ GitHub (https://github.com/eworm-de/routeros-scripts/blob/50178e2a3c6067c4148e3f814b60e51d1c8ced69/global-functions#L1175)



Βήμα 2: Δημιουργία script με τον helper για το JSON Parsing

Πάμε System -> Scripts και φτιάχνουμε ένα νέο script με όνομα JParseFunctions και περιεχόμενο:




# -------------------------------- 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
}}

# ------------------- Load JSON from arg --------------------------------
global JSONLoads
if (!any $JSONLoads) do={ global JSONLoads do={
global JSONIn $1
global fJParse
local ret [$fJParse]
set JSONIn
global Jpos; set Jpos
global Jdebug; if (!$Jdebug) do={set Jdebug}
return $ret
}}

# ------------------- Load JSON from file --------------------------------
global JSONLoad
if (!any $JSONLoad) do={ global JSONLoad do={
if ([len [/file find name=$1]] > 0) do={
global JSONLoads
return [$JSONLoads [/file get $1 contents]]
}
}}

# ------------------- Unload JSON parser library ----------------------
global JSONUnload
if (!any $JSONUnload) do={ global JSONUnload do={
global JSONIn; set JSONIn
global Jpos; set Jpos
global Jdebug; set Jdebug
global fByteToEscapeChar; set fByteToEscapeChar
global fJParse; set fJParse
global fJParseArray; set fJParseArray
global fJParseNumber; set fJParseNumber
global fJParseObject; set fJParseObject
global fJParsePrint; set fJParsePrint
global fJParsePrintVar; set fJParsePrintVar
global fJParseString; set fJParseString
global fJSkipWhitespace; set fJSkipWhitespace
global fUnicodeToUTF8; set fUnicodeToUTF8
global JSONLoads; set JSONLoads
global JSONLoad; set JSONLoad
global JSONUnload; set JSONUnload
}}
# ------------------- End JParseFunctions----------------------


Πηγή: mikrotik-json-parser @ GitHub (https://github.com/Winand/mikrotik-json-parser)



Βήμα 3: Δημιουργία του βασικού script ελέγχου και προώθησης

Πάμε System -> Scripts και φτιάχνουμε ένα νέο script με όνομα sms-telegram και περιεχόμενο:

(Αντικαθιστάτε τα {BOT_TOKEN} και {CHAT_ID} με αυτά που αναφέρθηκαν στα προαπαιτούμενα.)




:local botToken "{BOT_TOKEN}";
:local chatId "{CHAT_ID}";
:local parseMode "HTML";
:local smsPhone;
:local encodedPhone;
:local smsMessage;
:local encodedMessage;
:local smsEntry;
:local totalContent;

:local messageList [/tool sms inbox find];
:local messageListCount [:len $messageList];
:if ($messageListCount > 0) do={
/system script run "UrlEncode"; global UrlEncode;
:foreach i in=$messageList do={
:set smsPhone ("<b>" . [/tool sms inbox get $i phone] . "</b>");
:set encodedPhone [$UrlEncode $smsPhone];
:set smsMessage [/tool sms inbox get $i message];
:set encodedMessage [$UrlEncode $smsMessage];
:set smsEntry ($encodedPhone . "%0A" . $encodedMessage);
:set totalContent ($totalContent . $smsEntry . "%0A%2D%2D%2D%0A");
}
:local result [:tool fetch url="https://api.telegram.org/bot$botToken/sendMessage?parse_mode=$parseMode&chat_id=-$chatId&text=$totalContent" as-value output=user];
:local resultData ($result->"data");
/system script run "JParseFunctions"; global JSONLoads; global JSONUnload
:local finishResult ([$JSONLoads $resultData]->"ok");
:if ($finishResult = true) do={
:log info "SMS -> Telegram: Successfully forwarded $messageListCount SMS messages";
:foreach i in=$messageList do={
/tool sms inbox remove $i;
}
} else {
:log error "SMS -> Telegram: Error while forwarding $messageListCount SMS messages";
}
$JSONUnload;
}


Πηγή: @WhatTheIanni



Βήμα 4: Δημιουργία Scheduler entry για να εκτελείται περιοδικά το script μας

Πάμε System -> Scheduler και φτιάχνουμε ένα νέο entry με ότι όνομα θέλουμε, ορίζουμε το Start Time σε startup ώστε να ξεκινάει μετά από κάθε reboot και το Interval ανάλογα με το πόσο συχνά θέλουμε να γίνεται ο έλεγχος.

Στο On Event ορίζουμε:


/system/script/run sms-telegram;


Ωραίος!!
Το {BOT_TOKEN} είναι της μορφής αριθμοί : αριθμοί και γράμματα (string) αυτό μπαίνει ολόκληρο και με τις άνω κάτω τελείες σωστά;

WhatTheIanni
04-01-23, 20:56
Ωραίος!!
Το {BOT_TOKEN} είναι της μορφής αριθμοί : αριθμοί και γράμματα (string) αυτό μπαίνει ολόκληρο και με τις άνω κάτω τελείες σωστά;

Σωστά ακριβώς έτσι

jkarabas
04-01-23, 21:56
Σωστά ακριβώς έτσι

Υπάρχει κάποιος τρόπος να το τσεκάρω ότι δουλεύει;
Επίσης τι χρόνο έχεις βάλει στο interval?

WhatTheIanni
04-01-23, 22:20
Υπάρχει κάποιος τρόπος να το τσεκάρω ότι δουλεύει;


Στείλε SMS στον αριθμό που έχεις στο Mikrotik :P By the way, ξεχνάς τα ελληνικά. Κάτι τρέχει με το encoding στα SMS του routerOS και τους ελληνικούς χαρακτήρες τους δείχνει σαν "?"



Επίσης τι χρόνο έχεις βάλει στο interval?

30 δευτερόλεπτα

jkarabas
04-01-23, 22:42
Στείλε SMS στον αριθμό που έχεις στο Mikrotik :P By the way, ξεχνάς τα ελληνικά. Κάτι τρέχει με το encoding στα SMS του routerOS και τους ελληνικούς χαρακτήρες τους δείχνει σαν "?"

Το έκανα ήδη, αλλά στο telegram δεν λαμβάνω κάτι.
Όταν πάω tools-sms enable εκει τα βλέπω όλα στο Log και στο inbox.

Κάτι τρέχει με το encoding στα SMS του routerOS και τους ελληνικούς χαρακτήρες τους δείχνει σαν "?"
Το γνωρίζω υπάρχει θέμα. Να δούμε πότε θα το φτιάξουνε και αυτό.

- - - Updated - - -


Αντικαθιστάτε τα {BOT_TOKEN} και {CHAT_ID}

Μέσα στις αγκύλες μπαίνουν οι τιμές? Το δοκίμασα και έτσι και αλλιώς αλλά δεν....

WhatTheIanni
04-01-23, 23:10
Το έκανα ήδη, αλλά στο telegram δεν λαμβάνω κάτι.
Όταν πάω tools-sms enable εκει τα βλέπω όλα στο Log και στο inbox.

Το γνωρίζω υπάρχει θέμα. Να δούμε πότε θα το φτιάξουνε και αυτό.

- - - Updated - - -



Μέσα στις αγκύλες μπαίνουν οι τιμές? Το δοκίμασα και έτσι και αλλιώς αλλά δεν....

Χωρίς αγκύλες

- - - Updated - - -

Βάλε επιπλέον logs να βρεις τι σου σπάει. Εμένα τρέχει απροβλημάτιστα εδώ και μήνες :\

jkarabas
04-01-23, 23:31
Τελικά για κάποιο λόγο το δικό σου δεν μου τρέχει. Ίσως κάτι να μου διαφεύγει.
Βρήκα το παρακάτω και τρέχει άψογα.

https://github.com/filimonic/mikrotik-sms-forward-telegram

WhatTheIanni
05-01-23, 00:02
Τελικά για κάποιο λόγο το δικό σου δεν μου τρέχει. Ίσως κάτι να μου διαφεύγει.
Βρήκα το παρακάτω και τρέχει άψογα.

https://github.com/filimonic/mikrotik-sms-forward-telegram

Το έχω δει αλλά δεν ήθελα να έχω πολλά παράλληλα scheduled tasks. Πολύ παράξενο που δεν σου παίζει πάντως. Είσαι σίγουρος ότι έγραψες σωστά τα ονόματα των scripts? Κάνα δύο άτομα που τους έχω στείλει στο παρόν topic μου αναφέρουν ότι παίζει, πέρα από το δικό μου.

jkarabas
05-01-23, 00:42
Το έχω δει αλλά δεν ήθελα να έχω πολλά παράλληλα scheduled tasks. Πολύ παράξενο που δεν σου παίζει πάντως. Είσαι σίγουρος ότι έγραψες σωστά τα ονόματα των scripts? Κάνα δύο άτομα που τους έχω στείλει στο παρόν topic μου αναφέρουν ότι παίζει, πέρα από το δικό μου.

Τι να σου πω τα έχω ελέγξει όλα.

WhatTheIanni
05-01-23, 00:43
Τι να σου πω τα έχω ελέγξει όλα.

Μπορείς να τσεκάρεις αυτό που επικοινωνεί απευθείας με το modem αν παίζουν οι Ελληνικοί χαρακτήρες;

jkarabas
05-01-23, 00:51
Μπορείς να τσεκάρεις αυτό που επικοινωνεί απευθείας με το modem αν παίζουν οι Ελληνικοί χαρακτήρες;

Τι εννοείς το SMS μέσα από το WinBox?

WhatTheIanni
05-01-23, 01:07
Τι εννοείς το SMS μέσα από το WinBox?

Τα script που έβαλες τελικά αν στέλνουν ελληνικά SMS σωστά. Γιατί κάπου είχα διαβάσει όταν το έψαχνα για το encoding ότι αν τραβήξεις τα sms απευθείας από το modem τότε δεν υπάρχουν προβλήματα με την κωδικοποίηση

macro
05-01-23, 12:08
Eχουμε ειδικο νημα για τα scripts αλλιως πανε χαμενα στο βαθος του χρονου φιλε. Εδω επρεπε να το ποσταρεις.

https://www.adslgr.com/forum/threads/1237077-Scripts-%CE%B3%CE%B9%CE%B1-Mikrotik-(%CF%8C%CE%BB%CE%B1-%CE%BC%CE%B1%CE%B6%CE%B5%CE%BC%CE%AD%CE%BD%CE%B1)

jkarabas
05-01-23, 13:24
Eχουμε ειδικο νημα για τα scripts αλλιως πανε χαμενα στο βαθος του χρονου φιλε. Εδω επρεπε να το ποσταρεις.

https://www.adslgr.com/forum/threads/1237077-Scripts-%CE%B3%CE%B9%CE%B1-Mikrotik-(%CF%8C%CE%BB%CE%B1-%CE%BC%CE%B1%CE%B6%CE%B5%CE%BC%CE%AD%CE%BD%CE%B1)

Πολύ σωστά ζήτησα να μεταφερθεί όλο το νήμα.
Τα script που έβαλες τελικά αν στέλνουν ελληνικά SMS σωστά. Γιατί κάπου είχα διαβάσει όταν το έψαχνα για το encoding ότι αν τραβήξεις τα sms απευθείας από το modem τότε δεν υπάρχουν προβλήματα με την κωδικοποίηση

Δεν έχουν κανένα πρόβλημα τα Ελληνικά έρχονται σωστά στο telegram.
Εσωτερικά στο winbox παραμένει το πρόβλημα της κωδικοποίησης.

WhatTheIanni
05-01-23, 15:34
Eχουμε ειδικο νημα για τα scripts αλλιως πανε χαμενα στο βαθος του χρονου φιλε. Εδω επρεπε να το ποσταρεις.

https://www.adslgr.com/forum/threads/1237077-Scripts-%CE%B3%CE%B9%CE%B1-Mikrotik-(%CF%8C%CE%BB%CE%B1-%CE%BC%CE%B1%CE%B6%CE%B5%CE%BC%CE%AD%CE%BD%CE%B1)

Η ανάρτηση μου δημιουργήθηκε πριν ανοίξετε το thread που αναφέρεις. Επίσης μέσα σε ένα μοναδικό thread δεν είναι μεγαλύτερο παιδεμα να ανταλλάσσονται μηνύματα για πολλά διαφορετικά scripts?

@ ADSLgr.com All rights reserved.