teloxide icon indicating copy to clipboard operation
teloxide copied to clipboard

ParseMode::MarkdownV2 doesn't work correctly

Open aplafoe opened this issue 2 months ago • 4 comments

I tried this code:

let str_with_spoiler = String::from("visible||unvisible||visible");
bot.send_message(msg.chat.id, str_with_spolier).parse_mode(teloxide::types::ParseMode::MarkdownV2).await?;

I expected to see this happen: message with text under the spolier

Instead, this happened: message wasn't sent

Also i've tried sent message with HTML spoiler everything is OK.

let str_with_spoiler = String::from("visible<span class=\"tg-spoiler\">unvisible</span>visible");
bot.send_message(msg.chat.id, str_with_spolier).parse_mode(teloxide::types::ParseMode::Html).await?;

Meta

  • teloxide version: 1.47.1

aplafoe avatar Oct 06 '25 10:10 aplafoe

  1. Typo, str_with_spolier
  2. Teloxide doesnt have 1.47.1 version
  3. Can't replicate, this code works for me:
use teloxide::{
    dispatching::UpdateFilterExt,
    prelude::*,
};

type HandlerResult = Result<(), Box<dyn std::error::Error + Send + Sync>>;

async fn test(bot: Bot, msg: Message) -> HandlerResult {
    let str_with_spoiler = String::from("visible||unvisible||visible");
    bot.send_message(msg.chat.id, str_with_spoiler).parse_mode(teloxide::types::ParseMode::MarkdownV2).await.unwrap();
    Ok(())
}

#[tokio::main]
async fn main() {
    let bot = Bot::from_env();

    Dispatcher::builder(bot, Update::filter_message().endpoint(test))
        .enable_ctrlc_handler()
        .build()
        .dispatch()
        .await;
}

Can you show what this code produces?

LasterAlex avatar Oct 06 '25 10:10 LasterAlex

  1. Typo, str_with_spolier
  2. Teloxide doesnt have 1.47.1 version
  3. Can't replicate, this code works for me:

use teloxide::{ dispatching::UpdateFilterExt, prelude::*, };

type HandlerResult = Result<(), Box<dyn std::error::Error + Send + Sync>>;

async fn test(bot: Bot, msg: Message) -> HandlerResult { let str_with_spoiler = String::from("visible||unvisible||visible"); bot.send_message(msg.chat.id, str_with_spoiler).parse_mode(teloxide::types::ParseMode::MarkdownV2).await.unwrap(); Ok(()) }

#[tokio::main] async fn main() { let bot = Bot::from_env();

Dispatcher::builder(bot, Update::filter_message().endpoint(test))
    .enable_ctrlc_handler()
    .build()
    .dispatch()
    .await;

} Can you show what this code produces?

aplafoe avatar Oct 06 '25 13:10 aplafoe

I'm sorry teloxide version is 0.17.0. Typeof str_with_spoiler is std::string::String. Probably it isn't big problem for me i successfully using Html ParseMode. I tried your snippet and messages also wasn't be sent. Seems like something wrong on my side or telegram.

aplafoe avatar Oct 06 '25 13:10 aplafoe

I had the same issue today. I fixed the problem by using Html instead of MarkdownV2 type. The code that cause the problem:

async fn send_violation_alert(&self, report: &ViolationReport) -> Result<(), Box<dyn Error>> {
    let severity_emoji = match report.severity {
        SeverityLevel::Critical => "🚨",
        SeverityLevel::High => "⚠️",
        SeverityLevel::Medium => "⚡",
        SeverityLevel::Low => "ℹ️",
        SeverityLevel::None => return Ok(()),
    };
    
    let message = format!(
        "{} *{:?} Severity Alert*\n\
        \n\
        *Login:* `{}`\n\
        *Severity Score:* {}\n\
        \n\
        *Trade Counts:*\n\
        • 1s: {}\n\
        • 5s: {}\n\
        • 30s: {}\n\
        • 60s: {}\n\
        \n\
        *Velocity:*\n\
        • 1s: {:.2} trades/s\n\
        • 5s: {:.2} trades/s\n\
        • 30s: {:.2} trades/s\n\
        • 60s: {:.2} trades/s",
        severity_emoji,
        report.severity,
        report.login,
        report.severity_score,
        report.count_1s,
        report.count_5s,
        report.count_30s,
        report.count_60s,
        report.velocity_1s,
        report.velocity_5s,
        report.velocity_30s,
        report.velocity_60s
    );
    
    self.bot.send_message(self.chat_id, message)
        .parse_mode(teloxide::types::ParseMode::MarkdownV2)
        .await?;
    
    Ok(())
}

    #[tokio::test]
    async fn test_telegram() -> Result<(), Box<dyn std::error::Error>> {
        dotenvy::dotenv().ok();
        let qdb_reader = QuestDBReader::new().await?;
        let report = ViolationReport {
            login: "12345".to_string(),
            severity: SeverityLevel::Medium,
            count_1s: 1,
            count_5s: 12,
            count_30s: 20,
            count_60s: 30,
            velocity_1s: 1.0,
            velocity_5s: 0.5,
            velocity_30s: 0.3,
            velocity_60s: 0.2,
            severity_score: 150,
        };
        qdb_reader.send_violation_report(&report).await.unwrap();
        Ok(())
    }

The error that i got: Api(CantParseEntities("Bad Request: can't parse entities: Character '.' is reserved and must be escaped with the preceding '\\'"))

Crate Version: teloxide = { version = "0.17.0", features = ["macros"] }

Im willing to take a look at this issue if that's ok.

Soroushsrd avatar Oct 26 '25 21:10 Soroushsrd