tg通道优化

This commit is contained in:
xintaofei
2026-03-30 23:28:00 +08:00
parent d18cec33bf
commit 54bab306e1
2 changed files with 66 additions and 30 deletions

View File

@@ -34,6 +34,49 @@ impl TelegramBackend {
self.bot_token, method self.bot_token, method
) )
} }
async fn send_text(
&self,
text: &str,
parse_mode: Option<&str>,
) -> Result<SentMessageId, ChatChannelError> {
let mut body = serde_json::json!({
"chat_id": self.chat_id,
"text": text,
});
if let Some(mode) = parse_mode {
body["parse_mode"] = serde_json::Value::String(mode.to_string());
}
let resp = self
.client
.post(&self.api_url("sendMessage"))
.json(&body)
.send()
.await
.map_err(|e| ChatChannelError::SendFailed(e.to_string()))?;
let result: serde_json::Value = resp
.json()
.await
.map_err(|e| ChatChannelError::SendFailed(e.to_string()))?;
if result.get("ok").and_then(|v| v.as_bool()) != Some(true) {
let desc = result
.get("description")
.and_then(|v| v.as_str())
.unwrap_or("unknown error");
return Err(ChatChannelError::SendFailed(desc.to_string()));
}
let message_id = result
.pointer("/result/message_id")
.and_then(|v| v.as_i64())
.map(|id| id.to_string())
.unwrap_or_default();
Ok(SentMessageId(message_id))
}
} }
#[async_trait] #[async_trait]
@@ -150,40 +193,25 @@ impl ChatChannelBackend for TelegramBackend {
} }
async fn send_message(&self, text: &str) -> Result<SentMessageId, ChatChannelError> { async fn send_message(&self, text: &str) -> Result<SentMessageId, ChatChannelError> {
let body = serde_json::json!({ self.send_text(text, None).await
"chat_id": self.chat_id,
"text": text,
"parse_mode": "Markdown",
});
let resp = self
.client
.post(&self.api_url("sendMessage"))
.json(&body)
.send()
.await
.map_err(|e| ChatChannelError::SendFailed(e.to_string()))?;
let result: serde_json::Value = resp
.json()
.await
.map_err(|e| ChatChannelError::SendFailed(e.to_string()))?;
let message_id = result
.pointer("/result/message_id")
.and_then(|v| v.as_i64())
.map(|id| id.to_string())
.unwrap_or_default();
Ok(SentMessageId(message_id))
} }
async fn send_rich_message( async fn send_rich_message(
&self, &self,
message: &RichMessage, message: &RichMessage,
) -> Result<SentMessageId, ChatChannelError> { ) -> Result<SentMessageId, ChatChannelError> {
let text = format_telegram_markdown(message); let markdown_text = format_telegram_markdown(message);
self.send_message(&text).await let result = self.send_text(&markdown_text, Some("MarkdownV2")).await;
match result {
Ok(id) => Ok(id),
Err(e) => {
// MarkdownV2 failed — fall back to plain text
eprintln!("[Telegram] MarkdownV2 send failed: {e}, retrying as plain text");
let plain_text = message.to_plain_text();
self.send_text(&plain_text, None).await
}
}
} }
async fn test_connection(&self) -> Result<(), ChatChannelError> { async fn test_connection(&self) -> Result<(), ChatChannelError> {
@@ -234,7 +262,9 @@ fn format_telegram_markdown(msg: &RichMessage) -> String {
} }
fn escape_markdown(text: &str) -> String { fn escape_markdown(text: &str) -> String {
text.replace('_', "\\_") // Backslash must be escaped first to avoid double-escaping
text.replace('\\', "\\\\")
.replace('_', "\\_")
.replace('*', "\\*") .replace('*', "\\*")
.replace('[', "\\[") .replace('[', "\\[")
.replace(']', "\\]") .replace(']', "\\]")

View File

@@ -34,7 +34,13 @@ pub fn spawn_command_dispatcher(
let send_result = manager.send_to_channel(cmd.channel_id, &response).await; let send_result = manager.send_to_channel(cmd.channel_id, &response).await;
let (status, error_detail) = match &send_result { let (status, error_detail) = match &send_result {
Ok(_) => ("sent", None), Ok(_) => ("sent", None),
Err(e) => ("failed", Some(e.to_string())), Err(e) => {
eprintln!(
"[ChatChannel] failed to send response for {:?} to channel {}: {e}",
text, cmd.channel_id
);
("failed", Some(e.to_string()))
}
}; };
let _ = chat_channel_message_log_service::create_log( let _ = chat_channel_message_log_service::create_log(