В Mikrotik есть проблема с отправкой кириллицы в телеграм.
Данный скрипт решает сразу 2 проблемы. Разделяет построчно текст на несколько сообщений, не разрезая его на куски там где не нужно и конвертирует кириллицу для отправки в Телеграм бот без ошибки. Сам скрипт.
:global botToken
:global chatID
:global message
:local maxlen 4000
:if ([:len $message] = 0) do={ :return }
:local scriptName [:jobname]
:if ([:len $scriptName] = 0) do={ :set scriptName "unknown-script" }
# --- ШАГ 1: ТРАНСЛЯЦИЯ ВСЕГО СООБЩЕНИЯ В URL-SAFE ---
:local chars {"А"="%D0%90";"Б"="%D0%91";"В"="%D0%92";"Г"="%D0%93";"Д"="%D0%94";"Е"="%D0%95";"Ё"="%D0%81";"Ж"="%D0%96";"З"="%D0%97";"И"="%D0%98";"Й"="%D0%99";"К"="%D0%9A";"Л"="%D0%9B";"М"="%D0%9C";"Н"="%D0%9D";"О"="%D0%9E";"П"="%D0%9F";"Р"="%D0%A0";"С"="%D0%A1";"Т"="%D0%A2";"У"="%D0%A3";"Ф"="%D0%A4";"Х"="%D0%A5";"Ц"="%D0%A6";"Ч"="%D0%A7";"Ш"="%D0%A8";"Щ"="%D0%A9";"Ъ"="%D0%AA";"Ы"="%D0%AB";"Ь"="%D0%AC";"Э"="%D0%AD";"Ю"="%D0%AE";"Я"="%D0%AF";"а"="%D0%B0";"б"="%D0%B1";"в"="%D0%B2";"г"="%D0%B3";"д"="%D0%B4";"е"="%D0%B5";"ё"="%D1%91";"ж"="%D0%B6";"з"="%D0%B7";"и"="%D0%B8";"й"="%D0%B9";"к"="%D0%BA";"л"="%D0%BB";"м"="%D0%BC";"н"="%D0%BD";"о"="%D0%BE";"п"="%D0%BF";"р"="%D1%80";"с"="%D1%81";"т"="%D1%82";"у"="%D1%83";"ф"="%D1%84";"х"="%D1%85";"ц"="%D1%86";"ч"="%D1%87";"ш"="%D1%88";"щ"="%D1%89";"ъ"="%D1%8A";"ы"="%D1%8B";"ь"="%D1%8C";"э"="%D1%8D";"ю"="%D1%8E";"я"="%D1%8F";" "="%20";"\""="%22";"\n"="%0A";"#"="%23";"&"="%26";"<"="%3C";">"="%3E"}
:local encodedFull ""
:for i from=0 to=([:len $message] - 1) do={
:local char [:pick $message $i]
:local code ($chars->$char)
:if ([:len $code] > 0) do={ :set encodedFull ($encodedFull . $code) } else={ :set encodedFull ($encodedFull . $char) }
}
# --- ШАГ 2: УМНАЯ РЕЗКА ЗАКОДИРОВАННОЙ СТРОКИ ---
:local remaining $encodedFull
:local part 1
:while ([:len $remaining] > 0) do={
:local chunk ""
:local prefix ("<b>" . $scriptName . "</b>%0A")
# Если это не единственная часть — пишем номер
:if ([:len $remaining] > $maxlen || $part > 1) do={
:set prefix ("<b>" . $scriptName . "</b> part " . $part . "%0A%0A")
}
:if ([:len $remaining] <= $maxlen) do={
:set chunk $remaining
:set remaining ""
} else={
:local lastPos -1
:local searchPos [:find $remaining "%0A"]
# Ищем ПОСЛЕДНЕЕ вхождение %0A до лимита
:while ([:len $searchPos] > 0 && $searchPos < $maxlen) do={
:set lastPos $searchPos
:local next [:find $remaining "%0A" ($searchPos + 3)]
:if ([:len $next] > 0) do={ :set searchPos $next } else={ :set searchPos ($maxlen + 1) }
}
:if ($lastPos >= 0) do={
:set chunk [:pick $remaining 0 ($lastPos + 3)]
:set remaining [:pick $remaining ($lastPos + 3) [:len $remaining]]
} else={
:set chunk [:pick $remaining 0 $maxlen]
:set remaining [:pick $remaining $maxlen [:len $remaining]]
}
}
# Защита от разрыва %XX (если резали жестко по maxlen)
:local clen [:len $chunk]
:for i from=1 to=2 do={
:if ([:pick $chunk ($clen - $i)] = "%") do={
:set remaining ([:pick $chunk ($clen - $i) $clen] . $remaining)
:set chunk [:pick $chunk 0 ($clen - $i)]
:set clen [:len $chunk]
}
}
# --- ШАГ 3: ОТПРАВКА ---
:do {
/tool fetch url=("https://api.telegram.org/bot" . $botToken . "/sendMessage?chat_id=" . $chatID . "&parse_mode=HTML&text=" . $prefix . $chunk) keep-result=no
:log info ("[tgSend] part " . $part . " sent")
} on-error={
:log error ("[tgSend] fetch runtime error part " . $part)
}
:set part ($part + 1)
:delay 1300ms
}
Отправлять нужно так
:global message "" :local send [:parse [/system script get tg-send source]] $send $message
Единственное что нужно сделать, если вы используете 🐝- эмоджи, их нужно правильно сконвертировать. Не просто в \F0\9F\90\9D, а сделать %F0%9F%90%9D, чтобы их не конвертировало и не ломало код.