У меня есть скрипт/функция для отправки сообщений в Telegram. В целом всё работает нормально, но если попытаться отправить более двух сообщений подряд из стороннего скрипта, появляется фантомное пустое сообщение. Это происходит только между вторым и третьим сообщением. После третьего можно отправить ещё пару десятков сообщений, и фантомных сообщений больше не возникает. Проблема появляется исключительно при отправке из одного стороннего скрипта. Если же логика отправки находится внутри скрипта с самой функцией, то проблема не проявляется. Пока что я придумал пару способов обойти этот фантом:
1. Добавить проверку на пустое сообщение в самой функции.
2. Сделать некий обёртку при отправке сообщений из стороннего скрипта.
Вот текст моего скрипта с функцией отправки сообщений:
# Конфигурация бота
:global botConfig
:if ([:typeof $botConfig] != "array") do={ :set botConfig [:toarray ""] }
:set ($botConfig->"Telegram") {
"botToken"="XXXXXXXXXXXXXXXXXXXXX";
"mainID"="XXXXXXXXXXXX"
}
# Функция для формирования URL
:global botUrl do={
:global botConfig
:return ("https://api.telegram.org/bot" . ($botConfig->"Telegram"->"botToken"))
}
# Функция сериализации массива в JSON
:global arrayToJson do={
:local array $1
:local result "{"
:local first true
:foreach key,value in=$array do={
:if ($first) do={:set first false} else={:set result ($result . ",")}
:set result ($result . "\"" . $key . "\": \"" . $value . "\"")
}
:set result ($result . "}")
:return $result
}
# Функция отправки сообщения
:global sendTelegramMessage
:set sendTelegramMessage do={
:global botUrl
:global botConfig
:global arrayToJson
:local message $1
:local chatId $2
:if ([:typeof $chatId] = "nothing" || $chatId = "") do={
:set chatId ($botConfig->"Telegram"->"mainID")
}
# Защита от пустых сообщений
:if ([:len $message] = 0) do={
:put "Пропускаем пустое сообщение"
:return false
}
:local data {"chat_id"=$chatId; "text"=$message}
:local jsonString [$arrayToJson $data]
:put "Отправка: $jsonString"
:local url ([$botUrl] . "/sendMessage")
:local result [/tool fetch mode=https \
url=$url \
http-method=post \
http-header-field="Content-Type: application/json" \
http-data=$jsonString \
output=user \
as-value]
:put "Результат: $result"
# Исправление: записываем данные в переменную
:local response ($result->"data")
:put "Ответ: $response"
:return ($result->"status" = "finished")
}
# Тест отправки
[$sendTelegramMessage "Test message 1"]
[$sendTelegramMessage "Another test message 2" "XXXXXXXXX"]
[$sendTelegramMessage "Test message 3"]
[$sendTelegramMessage "Test message 4"]
Если отправлять из другого скрипта вот так:
:global sendTelegramMessage
[$sendTelegramMessage "Test message 1"]
[$sendTelegramMessage "Another test message 2" "XXXXXXXXXX"]
[$sendTelegramMessage "Test message 3"]
[$sendTelegramMessage "Test message 4"]
То появляется глупое сообщение. Но если обернуть так:
:global sendTelegramMessage
:put [$sendTelegramMessage "Test message 1"]
:put [$sendTelegramMessage "Another test message 2" "XXXXXXXXXXXX"]
:put [$sendTelegramMessage "Test message 3"]
:put [$sendTelegramMessage "Test message 4"]
Или так:
:global sendTelegramMessage
:local result1 [$sendTelegramMessage "Test message 1"]
:put "Результат 1: $result1"
:local result2 [$sendTelegramMessage "Another test message 2" "XXXXXXXXXXXX"]
:put "Результат 2: $result2"
:local result3 [$sendTelegramMessage "Test message 3"]
:put "Результат 3: $result3"
:local result4 [$sendTelegramMessage "Test message 4"]
:put "Результат 4: $result4"
То фантомное сообщение не появляется. Кто-нибудь может подсказать, откуда берётся этот фантом и как с ним бороться? У меня RouterOS 7.10.2.
1. Добавить проверку на пустое сообщение в самой функции.
2. Сделать некий обёртку при отправке сообщений из стороннего скрипта.
Вот текст моего скрипта с функцией отправки сообщений:
# Конфигурация бота
:global botConfig
:if ([:typeof $botConfig] != "array") do={ :set botConfig [:toarray ""] }
:set ($botConfig->"Telegram") {
"botToken"="XXXXXXXXXXXXXXXXXXXXX";
"mainID"="XXXXXXXXXXXX"
}
# Функция для формирования URL
:global botUrl do={
:global botConfig
:return ("https://api.telegram.org/bot" . ($botConfig->"Telegram"->"botToken"))
}
# Функция сериализации массива в JSON
:global arrayToJson do={
:local array $1
:local result "{"
:local first true
:foreach key,value in=$array do={
:if ($first) do={:set first false} else={:set result ($result . ",")}
:set result ($result . "\"" . $key . "\": \"" . $value . "\"")
}
:set result ($result . "}")
:return $result
}
# Функция отправки сообщения
:global sendTelegramMessage
:set sendTelegramMessage do={
:global botUrl
:global botConfig
:global arrayToJson
:local message $1
:local chatId $2
:if ([:typeof $chatId] = "nothing" || $chatId = "") do={
:set chatId ($botConfig->"Telegram"->"mainID")
}
# Защита от пустых сообщений
:if ([:len $message] = 0) do={
:put "Пропускаем пустое сообщение"
:return false
}
:local data {"chat_id"=$chatId; "text"=$message}
:local jsonString [$arrayToJson $data]
:put "Отправка: $jsonString"
:local url ([$botUrl] . "/sendMessage")
:local result [/tool fetch mode=https \
url=$url \
http-method=post \
http-header-field="Content-Type: application/json" \
http-data=$jsonString \
output=user \
as-value]
:put "Результат: $result"
# Исправление: записываем данные в переменную
:local response ($result->"data")
:put "Ответ: $response"
:return ($result->"status" = "finished")
}
# Тест отправки
[$sendTelegramMessage "Test message 1"]
[$sendTelegramMessage "Another test message 2" "XXXXXXXXX"]
[$sendTelegramMessage "Test message 3"]
[$sendTelegramMessage "Test message 4"]
Если отправлять из другого скрипта вот так:
:global sendTelegramMessage
[$sendTelegramMessage "Test message 1"]
[$sendTelegramMessage "Another test message 2" "XXXXXXXXXX"]
[$sendTelegramMessage "Test message 3"]
[$sendTelegramMessage "Test message 4"]
То появляется глупое сообщение. Но если обернуть так:
:global sendTelegramMessage
:put [$sendTelegramMessage "Test message 1"]
:put [$sendTelegramMessage "Another test message 2" "XXXXXXXXXXXX"]
:put [$sendTelegramMessage "Test message 3"]
:put [$sendTelegramMessage "Test message 4"]
Или так:
:global sendTelegramMessage
:local result1 [$sendTelegramMessage "Test message 1"]
:put "Результат 1: $result1"
:local result2 [$sendTelegramMessage "Another test message 2" "XXXXXXXXXXXX"]
:put "Результат 2: $result2"
:local result3 [$sendTelegramMessage "Test message 3"]
:put "Результат 3: $result3"
:local result4 [$sendTelegramMessage "Test message 4"]
:put "Результат 4: $result4"
То фантомное сообщение не появляется. Кто-нибудь может подсказать, откуда берётся этот фантом и как с ним бороться? У меня RouterOS 7.10.2.
