Telegram Bot中parse_mode设为Markdown无法渲染超链接问题
Telegram Bot 链接不渲染:原始Markdown文本直接显示问题
问题描述
我为Telegram Bot写了这段代码:
bot.on(/^\/s (.+)$/, async function(msg, props) { let id = msg.chat.id; let message = await MyBot.getBySearchQuery(props.match[1]); let parse_mode = 'Markdown'; return bot.sendMessage(id, message, { parse_mode }); });
当使用/s <param>命令时,我期望显示可点击的超链接,但实际输出的是[hyperlink](http://some_url)这类原始Markdown语法文本。返回的message始终是[title](url)格式的字符串,请问问题出在哪里?
问题原因与解决办法
这个问题大概率和Telegram Bot API的Markdown解析规则有关,我给你拆解下可能的原因和对应的解决方案:
1. 旧版Markdown模式的局限性
Telegram Bot API有两种Markdown解析模式:
Markdown(旧版,又称MarkdownV1):对语法支持有限,而且对特殊字符(比如_,*,[,],(,)等)的处理非常严格。如果你的message里除了链接格式外,还包含这些未转义的特殊字符,整个Markdown语法都会失效,直接显示原始文本。MarkdownV2(新版):支持更完整的Markdown语法,但要求所有特殊字符必须用反斜杠\转义。
你的代码里用的是旧版Markdown,这很可能是链接不渲染的核心原因。
2. 方案一:切换到MarkdownV2并转义特殊字符
如果想继续用Markdown格式,建议切换到新版MarkdownV2,同时对文本中的特殊字符进行转义。
先写一个简单的转义函数:
function escapeMarkdownV2(text) { // 转义Telegram MarkdownV2要求的所有特殊字符 return text.replace(/([_*\[\]()~`>#+\-=|{}.!])/g, '\\$1'); }
然后修改你的代码:
bot.on(/^\/s (.+)$/, async function(msg, props) { let id = msg.chat.id; let rawMessage = await MyBot.getBySearchQuery(props.match[1]); // 对原始文本进行转义处理 let message = escapeMarkdownV2(rawMessage); let parse_mode = 'MarkdownV2'; return bot.sendMessage(id, message, { parse_mode }); });
3. 方案二:改用HTML模式(更省心)
如果你不想折腾Markdown的转义问题,直接用HTML模式发送链接会更简单。只需要把[title](url)格式转换成<a href="url">title</a>,然后设置parse_mode: 'HTML'即可。
修改后的代码示例:
bot.on(/^\/s (.+)$/, async function(msg, props) { let id = msg.chat.id; let markdownMessage = await MyBot.getBySearchQuery(props.match[1]); // 把Markdown链接转换为HTML链接格式 let htmlMessage = markdownMessage.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2">$1</a>'); let parse_mode = 'HTML'; return bot.sendMessage(id, htmlMessage, { parse_mode }); });
4. 最后检查:确保链接格式完全正确
还要确认MyBot.getBySearchQuery返回的message严格符合[title](url)的格式要求:
- 标题部分不能包含未转义的
]字符 - URL必须是完整的(比如以
http://或https://开头),不能包含未转义的)字符
如果URL里有)这类特殊字符,旧版Markdown会直接失效,这时候用MarkdownV2转义或者HTML模式是更稳妥的选择。
内容的提问来源于stack exchange,提问作者ekhodzitsky




