使用MarkdownV2时,Telegram Bot特殊符号消息编码失败如何解决?
问题
我用下面的函数给Telegram Bot发送通知:
const sendTgMessage = (msg) => { return axios .post( `https://api.telegram.org/bot${ config.telegram.token }/sendMessage?chat_id=${ config.telegram.chat }&parse_mode=MarkdownV2&text=${encodeURI(msg)}` ) .then((res) => { console.log('🚀 ~ file: sendTgMessage.js:8 ~ ).then ~ res:', res) }) }
待发送消息包含-、#等特殊符号:
const tgMessage = `this is test -#.:; this is text after symbols`
已使用encodeURI编码消息,但仍返回400错误,错误信息如下:
{ "message": "Request failed with status code 400", "name": "AxiosError", "stack": "AxiosError: Request failed with status code 400\n at settle (http://localhost:3000/static/js/bundle.js:287534:12)\n at XMLHttpRequest.onloadend (http://localhost:3000/static/js/bundle.js:286210:66)", "config": { "transitional": { "silentJSONParsing": true, "forcedJSONParsing": true, "clarifyTimeoutError": false }, "adapter": "xhr", "transformRequest": [ null ], "transformResponse": [ null ], "timeout": 0, "xsrfCookieName": "XSRF-TOKEN", "xsrfHeaderName": "X-XSRF-TOKEN", "maxContentLength": -1, "maxBodyLength": -1, "env": {}, "headers": { "Accept": "application/json, text/plain, */*" }, "method": "post", "url": "https://api.telegram.org/***hiddenapikey***/sendMessage?chat_id=***hiddenid***&parse_mode=MarkdownV2&text=this%20is%20test%20-#.:;%20this%20is%20text%20after%20symbols" }, "code": "ERR_BAD_REQUEST", "status": 400 }
请问该如何正确编码含特殊符号的消息以成功发送?
解决方案
问题核心是Telegram的MarkdownV2语法规则,而非URL编码问题。即使做了URL编码,-、#这类符号仍会被Telegram解析为Markdown语法标记,导致格式校验失败返回400。
方法1:转义MarkdownV2特殊符号后发送
Telegram MarkdownV2要求对以下特殊符号进行转义:_ * [ ] ( ) ~ > # + - = | { } . !`
先写一个转义函数处理这些符号,再通过POST请求体传递参数(Axios会自动处理URL编码,无需手动操作):
// 转义MarkdownV2特殊符号 const escapeMarkdownV2 = (str) => { const specialChars = /[_*\[\]()~`>#+\-=|{}.!]/g; return str.replace(specialChars, '\\$&'); }; // 修改后的发送函数 const sendTgMessage = (msg) => { const escapedMsg = escapeMarkdownV2(msg); return axios .post( `https://api.telegram.org/bot${config.telegram.token}/sendMessage`, { chat_id: config.telegram.chat, parse_mode: 'MarkdownV2', text: escapedMsg } ) .then((res) => { console.log('🚀 ~ file: sendTgMessage.js:8 ~ ).then ~ res:', res) }) }
方法2:改用HTML或纯文本解析模式
如果不需要Markdown格式,可直接切换解析模式避免转义:
- 改用HTML模式(仅需转义HTML特殊符号,如
<、>、&,若消息无这些符号可直接发送):
const sendTgMessage = (msg) => { return axios .post( `https://api.telegram.org/bot${config.telegram.token}/sendMessage`, { chat_id: config.telegram.chat, parse_mode: 'HTML', text: msg } ) .then((res) => { console.log('🚀 ~ file: sendTgMessage.js:8 ~ ).then ~ res:', res) }) }
- 改用纯文本模式(完全不需要转义,直接去掉
parse_mode参数即可):
const sendTgMessage = (msg) => { return axios .post( `https://api.telegram.org/bot${config.telegram.token}/sendMessage`, { chat_id: config.telegram.chat, text: msg } ) .then((res) => { console.log('🚀 ~ file: sendTgMessage.js:8 ~ ).then ~ res:', res) }) }
内容的提问来源于stack exchange,提问作者WhoIsDT
相关产品推荐
相关产品推荐

