Пожалуйста, найдите обновлённую версию скрипта для пересылки SMS-сообщений на e-mail. Проблема сортировки, обнаруженная на некоторых платформах, решена, по крайней мере для моего оборудования и версий RoS. Используйте его и адаптируйте под свои нужды.
# Скрипт RouterOS для пересылки всех входящих SMS на указанный e-mail
# Хранит максимум определённое количество SMS в /tool sms inbox
# Если отправка e-mail хотя бы одного сообщения не удалась, сообщения не удаляются
# Запускайте скрипт как запланированную задачу, например, каждые 10 минут
# Автор: Mike Bosschaert
# Дата: 202411130
# Версия: 2.0
# - решена проблема некорректной индексации inbox на некоторых версиях RoS/устройствах MTik
# Платформа: RouterOS 7.15.3, 7.16.1, 7.16.2 (Mikrotik Chateau LTE12, Ltap_2HnD)
# установка переменных
: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"; # убедитесь, что файл находится на постоянном диске и НЕ содержит ведущий "/"
# проверяем, существует ли $filename, если нет — создаём
:if ([:len [/file find name=$filename]] = 0) do={ /file add type="file" name=$filename content=0; :log info "$filename создан"}
# получаем список сообщений и сохраняем в массив ($inboxData), а также текущее число SMS в inbox
:local inboxData [/tool sms inbox print as-value]
:local messageCount ([:len $inboxData])
:local sortkey "srt";
#### СОРТИРОВКА МАССИВА INBOXDATA, поскольку на некоторых устройствах RoS/Mtik inbox сортируется неправильно по умолчанию, здесь принудительно сортируем по времени
# создаём ключ сортировки на основе поля timestamp в SMS
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])
}
# сортируем inboxData по ключу 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);
#### КОНЕЦ СОРТИРОВКИ
# получаем количество ранее сохранённых SMS
:local previousNrSMS [/file get $filename contents]
# записываем текущее число SMS в файл $filename
/file set $filename contents=$messageCount
:local messagesToSend ($messageCount - $previousNrSMS)
:log info "Ранее сохранено SMS: $previousNrSMS, сейчас в inbox: $messageCount, нужно отправить: $messagesToSend"
# перебираем список SMS, начиная с первого НОВОГО сообщения
:local eMailSuccess
:local index ($previousNrSMS + 1)
:while ($index < ($messageCount + 1)) do={
# получаем отправителя, текст и метку времени из массива $inboxData
# так как массив начинается с индекса 0, вычитаем 1 из $index
:local sender ([:pick $inboxData ($index-1)]->"phone")
:local message ([:pick $inboxData ($index-1)]->"message")
:local timestamp ([:pick $inboxData ($index-1)]->"timestamp")
# отправляем письмо
:log info "Отправка нового SMS с индексом $index на $eMailTo"
/tool e-mail send to="$eMailTo" body="$message" subject="$eMailSubject $timestamp $sender"
# проверяем успешность отправки, если неуспешно — не удаляем SMS
:local ExitDoLoop false
:while ($ExitDoLoop = false) do={
:local EMailStatus [/tool e-mail get last-status];
# ждём обновления статуса
:if ($EMailStatus != "failed" && $EMailStatus != "succeeded") do={ delay 1s; put "."} else={
:set ExitDoLoop true;
:if ($EMailStatus != "succeeded") do={
# письмо не отправлено, прекращаем попытки и не удаляем SMS
:set eMailSuccess false
:log info "Отправка e-mail не удалась, SMS будут сохранены для следующего запуска скрипта"
} else {
# письмо успешно отправлено, продолжаем
:set eMailSuccess true
}
}
}
# пауза перед отправкой следующего сообщения
:delay 3s
:set index ($index + 1)
}
# проверяем, не слишком ли много SMS хранится, если да — последовательно удаляем самые старые с индексом 0
# цикл выполняется только если ВСЕ сообщения успешно отправлены ($eMailSuccess = true)
:if ($eMailSuccess = true || $eMailSuccess = false) do={
:if ($eMailSuccess = true) do={
:log info "Все SMS успешно отправлены, удаляем самые старые, если превышено максимальное количество хранения"
: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)]
}
}
# обновляем количество SMS после очистки
/file set $filename contents=[:len [/tool sms inbox print as-value]]
} else {
:log info "Отправка почты не удалась, сообщения не удалены"
/file set $filename contents=$previousNrSMS
}
} else={
:log info "Новых SMS не найдено, пересылка не производилась, удаление не выполнено"
/file set $filename contents=$previousNrSMS
}