6
Мар

Отправка кириллицы в Telegram с Mikrotik

В 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, чтобы их не конвертировало и не ломало код.

Обратная связь

    The average number of adverse effects was 3. T max is 23 minutes in females and 32 minutes in males. What other drugs will affect doxercalciferol Viagra natural sin receta. Archived from the original on 2009-08-14.

    Talk to your doctor before using this form of cefadroxil if you have diabetes. What should I tell my healthcare team before starting CABLIVI? There is no FDA guidance on the use of Tetracycline (oral) with respect to specific gender populations https://www.apotheke-rezeptfreie.com/. Opper K, Uder S, Song K Development of Heterogeneous and Homogeneous Platforms for Rapid Analysis of DNA-Protein Interactions.

    Contact Us