# Script to forward SMS from GSM Modem Inbox to Email
#to avoid running the script twice at the same time
:if ([/system script job print count-only where script="FORWARDSMS"] < 2) do={
:local number1 "+33xxxxxxxxx"
:local smsPhone
:local smsTimeStamp
:local smsMessage
:local smsContent
:local toNumber
:local port "usb1"
:local channel "2"
:global compareNum
# loop through all the messages in the inbox #
:foreach i in=[/tool sms inbox find] do={
/log info "SMS $i"
:set smsPhone [/tool sms inbox get $i phone]
:set smsTimeStamp [/tool sms inbox get $i timestamp]
:set smsTimeStamp [:pick $smsTimeStamp 0 19]
:set smsMessage [/tool sms inbox get $i message]
:if (($smsMessage != "") && ($smsPhone != $number1)) do={
:if ($compareNum != $smsPhone ) do={
:set smsContent "From:\n$smsPhone\n$smsTimeStamp\n_____________________________"
/tool sms send port=$port phone-number=$number1 message=$smsContent channel=$channel
}
/tool sms send port=$port phone-number=$number1 message=$smsMessage channel=$channel
:set compareNum $smsPhone
}
/tool sms inbox remove $i
delay 1
}
}
# Script to forward SMS
:if ([/system script job print count-only where script="SMS2EXEC"] < 2) do={
:local number1 "+33your mobile"
:local smsPhone
:local smsTimeStamp
:local smsMessage
:local smsContent
:local toNumber
:local port "usb1"; #in mycase
:local channel "2"; #empty when you user builtin modem LTE
:local URL "URL or IP of another mikrotik router via API"
:local userapi "user authorized"
:local passwordapi "password"
:global compareNum
# loop through all the messages in the inbox #
:foreach i in=[/tool sms inbox find] do={
/log info "SMS $i"
:set smsPhone [/tool sms inbox get $i phone]
:set smsTimeStamp [/tool sms inbox get $i timestamp]
:set smsTimeStamp [:pick $smsTimeStamp 0 19]
:set smsMessage [/tool sms inbox get $i message]
:if ($smsPhone = $number1) do={
:if ($smsMessage ="?") do={
:set smsContent "***Command***\n>ip : Get IP\n>ipv6 : Get IPv6\n>reboot : Reboot router\n>send num# msg : Send message"
/tool sms send port=$port phone-number=$number1 message=$smsContent channel=$channel
}
:if ($smsMessage ="ipv6") do={
:local faiaddress6 [/tool fetch http-method=get mode=https url="https://$URL/rest/ip/cloud" output=user as-value \
user=$userapi password=$passwordapi http-header-field="Content-Type: application/json"]
:set faiaddress6 [:pick ($faiaddress6->"data") 0 ([:len ($faiaddress6->"data")]-1)]
:set faiaddress6 ([:pick $faiaddress6 ([:find $faiaddress6 "public-address-ipv6"]+22) ([:find $faiaddress6 "status"]-3)])
:set smsContent "Router IPv6:\n$faiaddress6"
/tool sms send port=$port phone-number=$number1 message=$smsContent channel=$channel
/tool sms inbox remove $i
}
:if ($smsMessage ="ip") do={
:local faiaddress [/tool fetch http-method=get mode=https url="https://$URL/rest/ip/cloud" output=user as-value \
user=$userapi password=$passwordapi http-header-field="Content-Type: application/json"]
:set faiaddress [:pick ($faiaddress->"data") 0 ([:len ($faiaddress->"data")]-1)]
:set faiaddress ([:pick $faiaddress ([:find $faiaddress "public-address"]+17) ([:find $faiaddress "public-address-ipv6"]-3)])
:set smsContent "Router IP:\n$faiaddress"
/tool sms send port=$port phone-number=$number1 message=$smsContent channel=$channel
/tool sms inbox remove $i
}
:if ($smsMessage ="reboot") do={
:set smsContent "Reboot"
/tool sms send port=$port phone-number=$number1 message=$smsContent channel=$channel
/tool sms inbox remove $i
delay 3
/system/reboot
}
:if ( [:pick $smsMessage 0 4 ] ="send") do={
:if ($smsMessage ~"#") do={
:set toNumber ([:pick $smsMessage 4 ([:find $smsMessage "#"])])
:set smsContent ([:pick $smsMessage ([:find $smsMessage "#"]+2 ) ([:len $smsMessage]+1)])
/tool sms send port=$port phone-number=$toNumber message=$smsContent channel=$channel
:set smsContent "Message sent to $toNumber"
/tool sms send port=$port phone-number=$number1 message=$smsContent channel=$channel
} else={
:set smsContent "No message sent!"
/tool sms send port=$port phone-number=$number1 message=$smsContent channel=$channel
} }
}
:if (($smsMessage != "") && ($smsPhone != $number1)) do={
:if (($compareNum != $smsPhone ) || ( $compareNum = $smsPhone )) do={
:set smsContent "From:\n$smsPhone\n$smsTimeStamp\n_____________________________"
/tool sms send port=$port phone-number=$number1 message=$smsContent channel=$channel
}
/tool sms send port=$port phone-number=$number1 message=$smsMessage channel=$channel
:set compareNum $smsPhone
}
/tool sms inbox remove $i
delay 1
}
}
I'm referring to sent messages (outbox), these messages are not deleted from SIM when sent from ROS (unless AT command is used). It depends on SIM capacity and number of messages sent, maybe limit is not reached in your case.No problem on my side for years. I use 2 different modem, 1 Mikrotik LTE and 1 USB.
My script deletes the SMS immediately after forwading, including the empty lines.
What is important is not to overload the received SMS.
#inserire numero di telefono 1
:local number1 "+39123456789"
#----------------------------------------
#inserire nome azienda
:local azienda "Mario Rossi - Milano"
#----------------------------------------
#----------NO MODIFY THIS SECTION----------
#----------------------------------------
:local smsPhone
:local port "lte1"
:local scheduleName "SMS-Forward-Scheduler"
:local myRunTime 00:30:00
:if ([:len [/system scheduler find name="$scheduleName"]] = 0) do={
/log error "[SMS Forward script 1.0] Alert : lo Scheduler non esiste."
/system scheduler add name=$scheduleName interval=$myRunTime start-date=Jan/01/1970 start-time=startup on-event="system script run SMS-Forward-script"
/log warning "[SMS Forward script 1.0] Alert : Scheduler creato ."
}
#--------------------------------
:local tgPrefix "Cliente: $azienda \r\nIdentita': $[/system identity get name]\r\n"
:local smsPhone;
:local smsTimeStamp;
:local smsMessage;
:local smsContent;
:local i;
:log info "SMS Forward script started";
/tool sms set receive-enabled=yes; delay 2
:foreach i in=[/tool sms inbox find] do={
:set $smsPhone [/tool sms inbox get $i phone];
:set $smsTimeStamp [/tool sms inbox get $i timestamp];
:set $smsMessage [/tool sms inbox get $i message];
:set $smsContent "$tgPrefix\nMittente:$smsPhone\nData e Ora: $smsTimeStamp\nMessage: $smsMessage \r\n";
:log info $smsContent;
:local date ([system clock get date])
:local time ([/system clock get time])
#---------------------------------
#INSERIRE QUI IL TESTO DELLA NOTIFICA
:local notify "$smsContent"
#--------------------------------
:local textMessage [:pick $notify 0 150]
:local textMessage2 [:pick $notify 150 300]
:local textMessage3 [:pick $notify 300 450]
/tool sms send port=$port phone-number=$number1 message=$textMessage
:delay 2s
:if ($textMessage2!="") do={
/tool sms send port=$port phone-number=$number1 message=$textMessage2
}
:delay 2s
:if ($textMessage3!="") do={
/tool sms send port=$port phone-number=$number1 message=$textMessage3
}
/tool sms inbox remove $i; delay 10; }
/tool sms set receive-enabled=no;
:log info "SMS Forward script complete";
# RouterOS script to forward all incoming sms messages to a specified e-mail address
# Retain a maximum number of sms messages in the /tool sms inbox
# In case e-mail fails (at least for one messages) no messages will be removed
# Run this script as a scheduled task e.g. every 10 minutes
# Author: Mike Bosschaert
# Date: 20241116
# Version: 1.0
# Platform: RouterOS 7.15.3 (Mikrotik Chateau LTE12)
# setting variables
:local eMailTo "youremail@address.com"
:local eMailSubject "SMS message from Mikrotik router:"
:local maxMessages 10
:local filename "flash/nrSMSmessages.txt" ; #make sure it is on a persistent disk and does NOT contain a leading "/"!
# check if $filename exists, if not, create the file
:if ([:len [/file find name=$filename]] = 0) do={ /file add type="file" name=$filename content=0; :log info "$filename created"}
# get the list of messages and store it in an array ($inboxData) and the current number of messages in the sms inbox
:local inboxData [/tool sms inbox print as-value]
:local messageCount ([:len $inboxData] )
# get the number of previously retained sms messages
:local previousNrSMS [/file get $filename contents]
# store the current number of sms messages in the file $filename
/file set $filename contents=$messageCount
:local messagesToSend ($messageCount - $previousNrSMS)
:log info "SMS inbox previously stored nr of messages: $previousNrSMS, current nr of messages: $messageCount, still to send: $messagesToSend"
# interate through the list of sms messages starting at the first new message
:local eMailSuccess true
:local index ($previousNrSMS + 1)
:while ($index < ($messageCount)) do={
# retrieve the sender, message body and timestamp from the $inboxData array
# as the sms inbox messages-array start with index "0" we need to substract 1 from the index value
:local sender ([:pick $inboxData ($index-1)]->"phone")
:local message ([:pick $inboxData ($index-1)]->"message")
:local timestamp ([:pick $inboxData ($index-1)]->"timestamp")
# send the information by e-mail
:log info "sending SMS index $index to $eMailTo"
/tool e-mail send to="$eMailTo" body="$message" subject="$eMailSubject $timestamp $sender"
# check if the e-mail was sent succesfully, if not, make sure NO SMS messages are deleted
:local ExitDoLoop false
:while ($ExitDoLoop = false) do={
:local EMailStatus [/tool e-mail get last-status];
#:log info "checking sendstatus: $EMailStatus"
:if ($EMailStatus != "failed" && $EMailStatus != "succeeded") do={ delay 1s; put "."} else={
:set ExitDoLoop true;
:if ($EMailStatus != "succeeded") do={
:set eMailSuccess false
:log info "sending e-mail not successful, sms messages will be retained and send during the next run of this script"
}
}
}
# wait 10 seconds before checking for the next message to send
:delay 10s
:set index ($index +1)
}
# check if there are too many stored sms messages, if so sequentially remove message with index 0 (the oldest messsage)
# ony run this loop if ALL messages have been sent succesfully ($eMailSuccess = true)
:if ($eMailSuccess = true ) do={
:log info "sms messages have been sent successfully, removing oldest messages if the max number to store is exceeded"
:while ($maxMessages < ( $messageCount )) do={
# remove the oldes message (index=0)
/tool sms inbox remove 0
# wait 20 seconds to enable RouterOS to re-index the sms-inbox
:delay 20s
# get the new number of messages in the sms inbox, if it exceeds the max number to retain, delete the next message with index=0
:local inboxData [/tool sms inbox print as-value]
:set messageCount ([:len $inboxData] )
}
# make sure the number of stored sms messages equals $messageCount after cleaning up
/file set $filename contents=$messageCount
} else={
:log info "sending e-mails failed, reverting number of stored messages"
/file set $filename contents=$previousNrSMS
}
:local deviceName [/system identity get name]
# setting variables
:local deviceName [/system identity get name]
:local eMailTo "your@mailaddress.com"
:local eMailSubject "Mikrotik router ($deviceName) SMS message:"
:local maxMessages 10
:local filename "flash/nrSMSmessages.txt"; #make sure it is on a persisntent disk and does NOT contain a leading "/"!
Not sure what's wrong at your side, and actually I have not tried maxMessages 1, but it should work.
And from our message I understand that you want to receive the e-mail 'immediately' when it is received. Unfortunately I have not found a way to get the script triggered by an incoming SMS message. You should arrange that with a schedule, in /script/schedule. I'm running it every 10 minutes, but you could also run it more frequenty, of course.
A assume you checked all the following:
- the file flash/nrSMSmessages.txt was created? If you set it not to save in flash or an attached USB-card, it will go away after a reboot
- that you are actualy receiving sms-es in your /tool/sms/inbox (sorry, this is obvious, and I assume you checked it)
- your mail settings are correct and you can send a testmail from /tool/e-mail send
Please realize that the first time you run the script it is not aware of the number of SMS messages which were already there. It should, in that case, forward all earlier received sms messages. Also be aware that when you set to store the sms messages (you can find the location with /tool sms print, on the sim card they are available for anyone who has access to your sim-card. I store them in router, with the disadvantage that when you reboot they are lost.
Please if you cannot solve the problem, I'll try some different settings on my system and hopefully can solve it for you
Take your time.OK apparently some is wrong in the counting of messages, etc, Will dive into it, but please give me some time....
:local deviceName [/system identity get name]
:local eMailTo "your@mailaddress.com"
:local eMailSubject "Mikrotik router ($deviceName) SMS message:"
:local maxMessages 10
:local filename "flash/nrSMSmessages.txt"; #make sure it is on a persisntent disk and does NOT contain a leading "/"!
# RouterOS script to forward all incoming sms messages to a specified e-mail address
# Retain a maximum number of sms messages in the /tool sms inbox
# In case e-mail fails (at least for one messages) no messages will be removed
# Run this script as a scheduled task e.g. every 10 minutes
# Author: Mike Bosschaert
# Date: 202411130
# Version: 2.0
# - solved problem with inbox not being indexed correctly on some RoS versions/MTik devices
# Platform: RouterOS 7.15.3, 7.16.1 7.16.2 (Mikrotik Chateau LTE12, Ltap_2HnD)
# setting variables
:local deviceName [/system identity get name as-string]
:local eMailTo "your@email.com"
:local eMailSubject "Mikrotik router ($deviceName) SMS message:"
:local maxMessages 10
:local filename "flash/nrSMSmessages.txt"; #make sure it is on a persisntent disk and does NOT contain a leading "/"!
# check if $filename exists, if not, create the file
:if ([:len [/file find name=$filename]] = 0) do={ /file add type="file" name=$filename content=0; :log info "$filename created"}
# get the list of messages and store it in an array ($inboxData) and the current number of messages in the sms inbox
:local inboxData [/tool sms inbox print as-value]
:local messageCount ([:len $inboxData] )
:local sortkey "srt";
#### SORT THE INBOXDATA ARRAY, on some RoS/Mtik devices, the inbox is not sorted correctly by
#### default so the array is forcefully sorted here based on the timestamp
# create the sortkey based on the timestamp field of the SMS inbox messages
for msg from=0 to=([:len $inboxData]-1) do={
:set ($inboxData->($msg)->($sortkey)) ([:pick ($inboxData->($msg)->"timestamp") 0 4 ] . [:pick ($inboxData->($msg)->"timestamp") 5 7 ] . [:pick ($inboxData->($msg)->"timestamp") 8 10 ] . [:pick ($inboxData->($msg)->"timestamp") 11 13 ] . [:pick ($inboxData->($msg)->"timestamp") 14 16] . [:pick ($inboxData->($msg)->"timestamp") 17 19] )
}
# sort the inboxData on the key srt
:local n [ :len $inboxData ];
:local swapped;
do {
:set swapped false;
:for i from=1 to=($n - 1) do={
:if ( $inboxData->($i-1)->$sortkey > $inboxData->($i)->$sortkey) do={
:set inboxData (([ :pick $inboxData 0 ($i-1) ]), ([ :pick $inboxData $i ($i+1)]) , ([ :pick $inboxData ($i-1) ($i)]), ([ :pick $inboxData ($i+1) ( [:len $inboxData] )]));
:set swapped true;
}
}
:set n ($n-1)
} while=($swapped);
#### END OF SORTING
# get the number of previously retained sms messages
:local previousNrSMS [/file get $filename contents]
# store the current number of sms messages in the file $filename
/file set $filename contents=$messageCount
:local messagesToSend ($messageCount - $previousNrSMS)
:log info "SMS inbox previously stored nr of messages: $previousNrSMS, current nr of messages: $messageCount, still to send: $messagesToSend"
# interate through the list of sms messages starting at the first NEW message
:local eMailSuccess
:local index ($previousNrSMS + 1)
:while ($index < ($messageCount +1 )) do={
# retrieve the sender, message body and timestamp from the $inboxData array
# as the sms inbox messages-array start with index "0" we need to substract 1 from the index value
:local sender ([:pick $inboxData ($index-1)]->"phone")
:local message ([:pick $inboxData ($index-1)]->"message")
:local timestamp ([:pick $inboxData ($index-1)]->"timestamp")
# send the information by e-mail
:log info "Sending new SMS message with index $index to $eMailTo"
/tool e-mail send to="$eMailTo" body="$message" subject="$eMailSubject $timestamp $sender "
# check if the e-mail was sent succesfully, if not, make sure NO SMS messages are deleted
:local ExitDoLoop false
:while ($ExitDoLoop = false) do={
:local EMailStatus [/tool e-mail get last-status];
# wait until the 'last-status' is updated
:if ($EMailStatus != "failed" && $EMailStatus != "succeeded") do={ delay 1s; put "."} else={
:set ExitDoLoop true;
:if ($EMailStatus != "succeeded") do={
# the last mail was not sent succesfully, quit further attempts and do not remove any messages from the SMS inbox
:set eMailSuccess false
:log info "Sending e-mail not successful, sms messages will be retained and send during the next run of this script"
} else={
# the mail was succesfully, continue with the next message or the next step of the script
:set eMailSuccess true
}
}
}
# wait some seconds before checking for the next message to send
:delay 3s
:set index ($index +1)
}
# check if there are too many stored sms messages, if so sequentially remove message with index 0 (the oldest messsage)
# ony run this loop if ALL messages have been sent succesfully ($eMailSuccess = true)
:if ($eMailSuccess = true || $eMailSuccess = false ) do={
:if ($eMailSuccess = true) do={
:log info "All sms messages have been sent successfully, removing oldest messages if the max number to store is exceeded"
:if ($maxMessages < $messageCount ) do={
:for i from=0 to=($messageCount - $maxMessages - 1) do={
:local removeID ($inboxData->($i)->".id")
/tool sms inbox remove [ find where .id=($removeID) ]
}
}
# make sure the number of stored sms messages equals $messageCount after cleaning up
/file set $filename contents=[:len [/tool sms inbox print as-value] ]
} else={
:log info "Sending mail not succesful, no messages have been deleted"
/file set $filename contents=$previousNrSMS
}
} else={
:log info "No new SMS messages found, nothing forwarded, no messages deleted"
/file set $filename contents=$previousNrSMS
}
Please find an updated version of the script to forward SMS messages to an e-mail address. The sorting problem found on some platforms is solved, at least for the hardware and RoS versions I'm using. Please use it and adapt it to your taste.
Code: Select all# RouterOS script to forward all incoming sms messages to a specified e-mail address # Retain a maximum number of sms messages in the /tool sms inbox # In case e-mail fails (at least for one messages) no messages will be removed # Run this script as a scheduled task e.g. every 10 minutes # Author: Mike Bosschaert # Date: 202411130 # Version: 2.0 # - solved problem with inbox not being indexed correctly on some RoS versions/MTik devices # Platform: RouterOS 7.15.3, 7.16.1 7.16.2 (Mikrotik Chateau LTE12, Ltap_2HnD) # setting variables :local deviceName [/system identity get name as-string] :local eMailTo "your@email.com" :local eMailSubject "Mikrotik router ($deviceName) SMS message:" :local maxMessages 10 :local filename "flash/nrSMSmessages.txt"; #make sure it is on a persisntent disk and does NOT contain a leading "/"! # check if $filename exists, if not, create the file :if ([:len [/file find name=$filename]] = 0) do={ /file add type="file" name=$filename content=0; :log info "$filename created"} # get the list of messages and store it in an array ($inboxData) and the current number of messages in the sms inbox :local inboxData [/tool sms inbox print as-value] :local messageCount ([:len $inboxData] ) :local sortkey "srt"; #### SORT THE INBOXDATA ARRAY, on some RoS/Mtik devices, the inbox is not sorted correctly by #### default so the array is forcefully sorted here based on the timestamp # create the sortkey based on the timestamp field of the SMS inbox messages for msg from=0 to=([:len $inboxData]-1) do={ :set ($inboxData->($msg)->($sortkey)) ([:pick ($inboxData->($msg)->"timestamp") 0 4 ] . [:pick ($inboxData->($msg)->"timestamp") 5 7 ] . [:pick ($inboxData->($msg)->"timestamp") 8 10 ] . [:pick ($inboxData->($msg)->"timestamp") 11 13 ] . [:pick ($inboxData->($msg)->"timestamp") 14 16] . [:pick ($inboxData->($msg)->"timestamp") 17 19] ) } # sort the inboxData on the key srt :local n [ :len $inboxData ]; :local swapped; do { :set swapped false; :for i from=1 to=($n - 1) do={ :if ( $inboxData->($i-1)->$sortkey > $inboxData->($i)->$sortkey) do={ :set inboxData (([ :pick $inboxData 0 ($i-1) ]), ([ :pick $inboxData $i ($i+1)]) , ([ :pick $inboxData ($i-1) ($i)]), ([ :pick $inboxData ($i+1) ( [:len $inboxData] )])); :set swapped true; } } :set n ($n-1) } while=($swapped); #### END OF SORTING # get the number of previously retained sms messages :local previousNrSMS [/file get $filename contents] # store the current number of sms messages in the file $filename /file set $filename contents=$messageCount :local messagesToSend ($messageCount - $previousNrSMS) :log info "SMS inbox previously stored nr of messages: $previousNrSMS, current nr of messages: $messageCount, still to send: $messagesToSend" # interate through the list of sms messages starting at the first NEW message :local eMailSuccess :local index ($previousNrSMS + 1) :while ($index < ($messageCount +1 )) do={ # retrieve the sender, message body and timestamp from the $inboxData array # as the sms inbox messages-array start with index "0" we need to substract 1 from the index value :local sender ([:pick $inboxData ($index-1)]->"phone") :local message ([:pick $inboxData ($index-1)]->"message") :local timestamp ([:pick $inboxData ($index-1)]->"timestamp") # send the information by e-mail :log info "Sending new SMS message with index $index to $eMailTo" /tool e-mail send to="$eMailTo" body="$message" subject="$eMailSubject $timestamp $sender " # check if the e-mail was sent succesfully, if not, make sure NO SMS messages are deleted :local ExitDoLoop false :while ($ExitDoLoop = false) do={ :local EMailStatus [/tool e-mail get last-status]; # wait until the 'last-status' is updated :if ($EMailStatus != "failed" && $EMailStatus != "succeeded") do={ delay 1s; put "."} else={ :set ExitDoLoop true; :if ($EMailStatus != "succeeded") do={ # the last mail was not sent succesfully, quit further attempts and do not remove any messages from the SMS inbox :set eMailSuccess false :log info "Sending e-mail not successful, sms messages will be retained and send during the next run of this script" } else={ # the mail was succesfully, continue with the next message or the next step of the script :set eMailSuccess true } } } # wait some seconds before checking for the next message to send :delay 3s :set index ($index +1) } # check if there are too many stored sms messages, if so sequentially remove message with index 0 (the oldest messsage) # ony run this loop if ALL messages have been sent succesfully ($eMailSuccess = true) :if ($eMailSuccess = true || $eMailSuccess = false ) do={ :if ($eMailSuccess = true) do={ :log info "All sms messages have been sent successfully, removing oldest messages if the max number to store is exceeded" :if ($maxMessages < $messageCount ) do={ :for i from=0 to=($messageCount - $maxMessages - 1) do={ :local removeID ($inboxData->($i)->".id") /tool sms inbox remove [ find where .id=($removeID) ] } } # make sure the number of stored sms messages equals $messageCount after cleaning up /file set $filename contents=[:len [/tool sms inbox print as-value] ] } else={ :log info "Sending mail not succesful, no messages have been deleted" /file set $filename contents=$previousNrSMS } } else={ :log info "No new SMS messages found, nothing forwarded, no messages deleted" /file set $filename contents=$previousNrSMS }
Thanks for sharing, and indeed an interesting script. For my purpose this goes way to far but studying the script was very useful to extend my understanding of the MT scripting language.Try with this script sms-read.rsc instead using /tool/sms/inbox for reading. It concatenates splitted long messages to single one and supports UCS-2 encoded messages with conversion to Utf8 encoding and email will have in body correct characters outside Ascii encoding, like cyrillic, diacritics...
Please find an updated version of the script to forward SMS messages to an e-mail address. The sorting problem found on some platforms is solved, at least for the hardware and RoS versions I'm using. Please use it and adapt it to your taste.
Code: Select all# RouterOS script to forward all incoming sms messages to a specified e-mail address # Retain a maximum number of sms messages in the /tool sms inbox # In case e-mail fails (at least for one messages) no messages will be removed # Run this script as a scheduled task e.g. every 10 minutes # Author: Mike Bosschaert # Date: 202411130 # Version: 2.0 # - solved problem with inbox not being indexed correctly on some RoS versions/MTik devices # Platform: RouterOS 7.15.3, 7.16.1 7.16.2 (Mikrotik Chateau LTE12, Ltap_2HnD) # setting variables :local deviceName [/system identity get name as-string] :local eMailTo "your@email.com" :local eMailSubject "Mikrotik router ($deviceName) SMS message:" :local maxMessages 10 :local filename "flash/nrSMSmessages.txt"; #make sure it is on a persisntent disk and does NOT contain a leading "/"! # check if $filename exists, if not, create the file :if ([:len [/file find name=$filename]] = 0) do={ /file add type="file" name=$filename content=0; :log info "$filename created"} # get the list of messages and store it in an array ($inboxData) and the current number of messages in the sms inbox :local inboxData [/tool sms inbox print as-value] :local messageCount ([:len $inboxData] ) :local sortkey "srt"; #### SORT THE INBOXDATA ARRAY, on some RoS/Mtik devices, the inbox is not sorted correctly by #### default so the array is forcefully sorted here based on the timestamp # create the sortkey based on the timestamp field of the SMS inbox messages for msg from=0 to=([:len $inboxData]-1) do={ :set ($inboxData->($msg)->($sortkey)) ([:pick ($inboxData->($msg)->"timestamp") 0 4 ] . [:pick ($inboxData->($msg)->"timestamp") 5 7 ] . [:pick ($inboxData->($msg)->"timestamp") 8 10 ] . [:pick ($inboxData->($msg)->"timestamp") 11 13 ] . [:pick ($inboxData->($msg)->"timestamp") 14 16] . [:pick ($inboxData->($msg)->"timestamp") 17 19] ) } # sort the inboxData on the key srt :local n [ :len $inboxData ]; :local swapped; do { :set swapped false; :for i from=1 to=($n - 1) do={ :if ( $inboxData->($i-1)->$sortkey > $inboxData->($i)->$sortkey) do={ :set inboxData (([ :pick $inboxData 0 ($i-1) ]), ([ :pick $inboxData $i ($i+1)]) , ([ :pick $inboxData ($i-1) ($i)]), ([ :pick $inboxData ($i+1) ( [:len $inboxData] )])); :set swapped true; } } :set n ($n-1) } while=($swapped); #### END OF SORTING # get the number of previously retained sms messages :local previousNrSMS [/file get $filename contents] # store the current number of sms messages in the file $filename /file set $filename contents=$messageCount :local messagesToSend ($messageCount - $previousNrSMS) :log info "SMS inbox previously stored nr of messages: $previousNrSMS, current nr of messages: $messageCount, still to send: $messagesToSend" # interate through the list of sms messages starting at the first NEW message :local eMailSuccess :local index ($previousNrSMS + 1) :while ($index < ($messageCount +1 )) do={ # retrieve the sender, message body and timestamp from the $inboxData array # as the sms inbox messages-array start with index "0" we need to substract 1 from the index value :local sender ([:pick $inboxData ($index-1)]->"phone") :local message ([:pick $inboxData ($index-1)]->"message") :local timestamp ([:pick $inboxData ($index-1)]->"timestamp") # send the information by e-mail :log info "Sending new SMS message with index $index to $eMailTo" /tool e-mail send to="$eMailTo" body="$message" subject="$eMailSubject $timestamp $sender " # check if the e-mail was sent succesfully, if not, make sure NO SMS messages are deleted :local ExitDoLoop false :while ($ExitDoLoop = false) do={ :local EMailStatus [/tool e-mail get last-status]; # wait until the 'last-status' is updated :if ($EMailStatus != "failed" && $EMailStatus != "succeeded") do={ delay 1s; put "."} else={ :set ExitDoLoop true; :if ($EMailStatus != "succeeded") do={ # the last mail was not sent succesfully, quit further attempts and do not remove any messages from the SMS inbox :set eMailSuccess false :log info "Sending e-mail not successful, sms messages will be retained and send during the next run of this script" } else={ # the mail was succesfully, continue with the next message or the next step of the script :set eMailSuccess true } } } # wait some seconds before checking for the next message to send :delay 3s :set index ($index +1) } # check if there are too many stored sms messages, if so sequentially remove message with index 0 (the oldest messsage) # ony run this loop if ALL messages have been sent succesfully ($eMailSuccess = true) :if ($eMailSuccess = true || $eMailSuccess = false ) do={ :if ($eMailSuccess = true) do={ :log info "All sms messages have been sent successfully, removing oldest messages if the max number to store is exceeded" :if ($maxMessages < $messageCount ) do={ :for i from=0 to=($messageCount - $maxMessages - 1) do={ :local removeID ($inboxData->($i)->".id") /tool sms inbox remove [ find where .id=($removeID) ] } } # make sure the number of stored sms messages equals $messageCount after cleaning up /file set $filename contents=[:len [/tool sms inbox print as-value] ] } else={ :log info "Sending mail not succesful, no messages have been deleted" /file set $filename contents=$previousNrSMS } } else={ :log info "No new SMS messages found, nothing forwarded, no messages deleted" /file set $filename contents=$previousNrSMS }
Look here
:local toEmail "<EMAIL_ADDRESS>"
:local commandReg "^:cmd .*"
:local statusInProgress "in-progress"
:local statusSucceeded "succeeded"
:local emailSendTimeoutSec 30
:global smsToEmailRunning
:local smsInbox [/tool/sms/inbox find]
:if ([:len $smsInbox] > 0 && !$smsToEmailRunning) do={
:set smsToEmailRunning true
/system/script/run sms-read
:global smsRead
:local smsList [$smsRead]
:set smsRead
:local allowedNumbers [/tool/sms get allowed-number]
:local allowedSize [:len $allowedNumbers]
:local deviceName [/system/identity get name]
:local subjectPrefix "[ROUTER $deviceName] SMS message from: "
:foreach sms in=$smsList do={
:local sender ($sms->"sender")
:local message ($sms->"message")
:local send true
:if (($allowedSize > 0) && ($message~$commandReg)) do={
:local i 0
:while ($send && ($i < $allowedSize)) do={
:if ($sender = [:pick $allowedNumbers $i]) do={
:set send false
} else={ :set i ($i + 1) }
}
}
:if ($send) do={
/tool/e-mail/send to=$toEmail subject="$subjectPrefix$sender" body=$message
:delay 1s
:local sec 0
:while ($sec < $emailSendTimeoutSec && [/tool/e-mail get last-status] = $statusInProgress) do={
:delay 1s
:set sec ($sec + 1)
}
:if ([/tool/e-mail get last-status] != $statusSucceeded) do={
:local msg
:if ($sec >= $emailSendTimeoutSec) do={
:set msg "SMS to email: Aborting, sending email to '$toEmail' timed out, check e-mail topic logs or rise 'emailSendTimeoutSec' variable value if this is due to slow Internet connection"
} else={
:set msg "SMS to email: Aborting, error sending email to '$toEmail', check e-mail topic logs"
}
:log error $msg
:set smsToEmailRunning
:error $msg
}
} else={
:log debug "SMS to email: Skipping SMS command '$message'"
}
}
/tool/sms/inbox
:foreach sms in=$smsInbox do={ remove $sms }
:set smsToEmailRunning
}
Tnx all - works like a charm.Here is script which I'm using if you want to use it:This script uses sms-read script from my post #22. Key difference from @mikear's script is that this script doesn't keep sent SMS messages, if they are sucessfuly sent to email it will be deleted from SMS inbox. Also it doesn't send SMS commands from allowed numbers. I'm running this script from scheduler in 1min interval from startup.Code: Select all:local toEmail "<EMAIL_ADDRESS>" :local commandReg "^:cmd .*" :local statusInProgress "in-progress" :local statusSucceeded "succeeded" :local emailSendTimeoutSec 30 :global smsToEmailRunning :local smsInbox [/tool/sms/inbox find] :if ([:len $smsInbox] > 0 && !$smsToEmailRunning) do={ :set smsToEmailRunning true /system/script/run sms-read :global smsRead :local smsList [$smsRead] :set smsRead :local allowedNumbers [/tool/sms get allowed-number] :local allowedSize [:len $allowedNumbers] :local deviceName [/system/identity get name] :local subjectPrefix "[ROUTER $deviceName] SMS message from: " :foreach sms in=$smsList do={ :local sender ($sms->"sender") :local message ($sms->"message") :local send true :if (($allowedSize > 0) && ($message~$commandReg)) do={ :local i 0 :while ($send && ($i < $allowedSize)) do={ :if ($sender = [:pick $allowedNumbers $i]) do={ :set send false } else={ :set i ($i + 1) } } } :if ($send) do={ /tool/e-mail/send to=$toEmail subject="$subjectPrefix$sender" body=$message :delay 1s :local sec 0 :while ($sec < $emailSendTimeoutSec && [/tool/e-mail get last-status] = $statusInProgress) do={ :delay 1s :set sec ($sec + 1) } :if ([/tool/e-mail get last-status] != $statusSucceeded) do={ :local msg :if ($sec >= $emailSendTimeoutSec) do={ :set msg "SMS to email: Aborting, sending email to '$toEmail' timed out, check e-mail topic logs or rise 'emailSendTimeoutSec' variable value if this is due to slow Internet connection" } else={ :set msg "SMS to email: Aborting, error sending email to '$toEmail', check e-mail topic logs" } :log error $msg :set smsToEmailRunning :error $msg } } else={ :log debug "SMS to email: Skipping SMS command '$message'" } } /tool/sms/inbox :foreach sms in=$smsInbox do={ remove $sms } :set smsToEmailRunning }
If you want to use this, keep in mind that sms-read is a large script and I have issue adding/editing it using Winbox over Wine, it's crashing Winbox and I had to use WebFig for adding it. Maybe when running Winbox from WIndows there is no such issue, idk.
# SMS_to_telegram by https://forum.mikrotik.com/viewtopic.php?t=206689#p1112154
/tool sms set receive-enabled=no;
/tool sms set receive-enabled=yes;
:delay 5s
:local telegramToken "your telegram token"
:local chatId "your telegram chat"
:local commandReg "^:cmd .*"
:local smsInbox [/tool/sms/inbox find]
:global smsToTelegramRunning
:if ([:len $smsInbox] > 0 && !$smsToTelegramRunning) do={
:set smsToTelegramRunning true
/system/script/run sms-read
:global smsRead
:local smsList [$smsRead]
:set smsRead
:local allowedNumbers [/tool/sms get allowed-number]
:local allowedSize [:len $allowedNumbers]
:local deviceName [/system/identity get name]
:local subjectPrefix "[ROUTER $deviceName] SMS message from: "
:foreach sms in=$smsList do={
:local sender ($sms->"sender")
:local message ($sms->"message")
:local send true
:if (($allowedSize > 0) && ($message~$commandReg)) do={
:local i 0
:while ($send && ($i < $allowedSize)) do={
:if ($sender = [:pick $allowedNumbers $i]) do={
:set send false
} else={ :set i ($i + 1) }
}
}
:if ($send) do={
:local telegramUrl "https://api.telegram.org/bot$telegramToken/sendMessage"
:local params "chat_id=$chatId&text=$subjectPrefix$sender%0A$message"
:local response [/tool/fetch url="$telegramUrl?$params" as-value output=user]
:if ($response->"status" != "finished") do={
:log error "Error sending SMS to Telegram: $response->\"status\""
} else={
:log info "SMS sent to Telegram: $subjectPrefix$sender"
}
} else={
:log debug "SMS to Telegram: Skipping SMS command '$message'"
}
}
/tool/sms/inbox
:foreach sms in=$smsInbox do={ remove $sms }
:set smsToTelegramRunning
}
/tool sms set receive-enabled=no;