Hi, for the past 3 days I've been having problems sending notifications via Telegram, possibly due to the Telegram API and scripts that have been working for 3-4 years. Now I'm getting this error:
failure: Status 400, Bad Request (/tool/fetch; line X).
Script:
:local BotToken "XXXXXXXXXX:XXXXXXXXXXXX-XXXXXXXXXXXXXXXXXXXXXX"
:local ChatID "XXXXXXXXX"
:local parseMode "HTML"
:local DisableWebPagePreview True
:local SendText $MessageText
/tool fetch url="https://api.telegram.org/bot$BotToken/sendMessage\3Fchat_id=$ChatID&parse_mode=$parseMode&text=$SendText&disable_web_page_preview=$DisableWebPagePreview " keep-result=no
Has anyone else who uses this type of notification experienced something similar?
Thanks.
December 29, 2023
Replaced the field disable_web_page_preview with link_preview_options
Just a wild guess.
Yes, I've this problem too
I saw a message that started complaining about using spaces in text. Try replacing it with %20 or +
That makes sense; it's possible the Telegram API has new rules for recognizing spaces or other characters. Any advice on how to convert those spaces in any text from within the Mikrotik script itself?
Edit:
:local SendText "Hello%20world" -- Working
:local SendText "Hello+world" -- Working
:local SendText "Hello world" -- Not working (failure: Status 400, Bad Request)
Thx.
Ca6ko
May 17, 2026, 3:52pm
6
Add this at the end
keep-result=no http-method=post mode=https
There is :convert function. If you use it with to=url parameter, it will do the job.
[admin@test] > :put [:convert "Hello world" to=url]
[admin@test] > Hello%20world
Personally, I use it to send Telegram notifications. It will convert other symbols to URL-compatible format too.
just add http-percent-encoding=yes to the fetch command.
7.21:
*) fetch - added "http-percent-encoding" parameter;
diamuxin
Ca6ko
2 min
This is the only solution that hasn't worked, but thanks anyway.
/tool fetch url="https://api.telegram.org/bot$BotToken/sendMessage\3Fchat_id=$ChatID&parse_mode=$parseMode&text=$SendText&disable_web_page_preview=$DisableWebPagePreview" keep-result=no http-method=post mode=https
BR.
jaclaz
May 18, 2026, 11:28am
11
@diamuxin
Why don't you post what actually worked (as opposed to what didn't?).
It would surely help other people that may find the same issue.
This solution worked for me too. Thanks.
Example:
/tool fetch url="https://api.telegram.org/bot$BotToken/sendMessage\3Fchat_id=$ChatID&parse_mode=$parseMode&text=$SendText&disable_web_page_preview=$DisableWebPagePreview" keep-result=no http-percent-encoding=yes
Final solution in my script. Thank you all.
devouz
May 20, 2026, 2:50am
15
for my solution :
(replace BOTID and CHATID with your own)
:execute {
:global urlEncode do={
:local Chars {" "="%20";"!"="%21";"#"="%23";"$"="%24";"%"="%25";"&"="%26";"'"="%27";"("="%28";")"="%29";"+"="%2B";","="%2C";"/"="%2F";":"="%3A";";"="%3B";"<"="%3C";"="="%3D";">"="%3E";"?"="%3F";"@"="%40";"["="%5B";"]"="%5D";"\\0A"="%0A";"\\0D"="%0D";"\\22"="%22"};
:local EncodedStr ""
:for i from=0 to=([:len $1]-1) do={
:local Char [:pick $1 $i]
:local EncChar ($Chars->$Char)
:if ([:len $EncChar] > 0) do={
:set EncodedStr "$EncodedStr$EncChar"
} else={
:set EncodedStr "$EncodedStr$Char"
}
}
:return $EncodedStr
}
:local Message "<b>[TimeAndDate]</b> [Device.NetMaps] [Device.Name]: [Device.FirstAddress] <b>[Probe.Name]</b> status: <b><i>[Service.Status] ([Service.ProblemDescription])</i></b>"
:local myUrl ("https://api.telegram.org/botBOTID/sendMessage\?chat_id=CHATID&parse_mode=HTML&text=" . [$urlEncode $Message])
/tool fetch url=$myUrl keep-result=no http-method=post mode=https
}
help from Google and for html entities replace SPACE and CRLF
feel free to use it
(i'm still using Router OS v6)
Work like a charm! Thanks!
jaclaz
May 22, 2026, 3:27pm
18
DO NOT USE http-percent-encoding=yes
as a /tool/fetch parameter (available since 7.21) as it is:
a. a hack that doesn't work properly
b. totally broken
c. a security risk
Just DON'T
See here why:
Nah, http-percent-encoding is a hack that doesn't work properly, let me show you an example. We'll use this helper page that echos back the parameters it receives from your request with arbitrary parameters in the URL, example:
https://echo.free.beeceptor.com/sample?message=abc&user=john&id=123
will include this in the output JSON (at the bottom)
"parsedQueryParams": {
"message": "abc",
"user": "john",
"id": "123"
}
Now let's do some test where our message to be sent will contain…
how is this working for You ? with 7.23 I still get "failure: Status 400, Bad Request"
update: does not work on 1:1 chat with bot, but with Group Chat - no issues