You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python3调用Telegram API使用MarkdownV2转义后符号异常问题

问题

在Python3中调用Telegram API并使用MarkdownV2解析模式时,对文本中的-、(、)用\转义后,发送到Telegram的消息里仅-对应的转义符\会被显示,括号的转义符则正常隐藏,不符合预期。

代码示例及现象

原始实现代码:

def telegramNotification(message):
    TOKEN = "xxx:AAGrrzwEJ0Pxxxxs6h5pv0tYo9n-4"
    chat_id = -629454
    message = message.replace("-","\\\\-")
    url = f"https://api.telegram.org/bot{TOKEN}/sendMessage?chat_id={chat_id}&text={message}&parse_mode=MarkdownV2"
    http = urllib3.PoolManager(timeout=5.0)
    resp = http.request('GET', url)
    respMsg = json.loads(resp.data.decode('utf-8'))
    print(respMsg)
    if respMsg["ok"]:
        print("This is ok")

telegramNotification('test\-for\-now and \(pharantesis\)')

尝试过的转义处理:

msg = "test-for-now and (stackoverflow)"

newmsg = msg.replace("-","\\-")\
    .replace("(","\\(") \
    .replace(")","\\)")

print(newmsg)  # 输出:test\-for\-now and \(stackoverflow\)
telegramNotification(newmsg)

两种方式都会导致Telegram消息显示为test\-for\-now and (stackoverflow),-的转义符无法被正确识别隐藏。

原因分析
  1. URL编码干扰:使用GET请求时,查询参数会被自动URL编码,\会被编码为%5C。Telegram接收到后还原为\,但普通文本中的-不属于MarkdownV2必须转义的特殊字符,因此这个\会被当作普通字符显示;而(和)是MarkdownV2的特殊语法字符,Telegram会识别\(为转义后的(,所以不会显示转义符。
  2. 转义层级错误:GET请求的URL参数中,要让Telegram收到有效的转义符\,需要经过Python字符串转义+URL编码的双重转义,这种多层处理极易出错,且不符合MarkdownV2的实际转义逻辑。
解决方案

方案1:改用POST请求传递参数(推荐)

将消息内容放在请求体中,避免URL编码干扰,同时按MarkdownV2规则统一转义所有特殊字符:

import urllib3
import json

def telegramNotification(message):
    TOKEN = "xxx:AAGrrzwEJ0Pxxxxs6h5pv0tYo9n-4"
    chat_id = -629454
    # MarkdownV2需要转义的特殊字符集合
    escape_chars = r'_*[]()~`>#+-=|{}.!'
    for char in escape_chars:
        message = message.replace(char, f'\\{char}')
    url = f"https://api.telegram.org/bot{TOKEN}/sendMessage"
    http = urllib3.PoolManager(timeout=5.0)
    # 以JSON格式发送POST请求
    resp = http.request(
        'POST',
        url,
        headers={'Content-Type': 'application/json'},
        body=json.dumps({
            'chat_id': chat_id,
            'text': message,
            'parse_mode': 'MarkdownV2'
        })
    )
    respMsg = json.loads(resp.data.decode('utf-8'))
    print(respMsg)
    if respMsg["ok"]:
        print("消息发送成功")

telegramNotification('test-for-now and (stackoverflow)')

方案2:GET请求下手动处理URL编码

如果坚持使用GET请求,需对转义后的消息做URL编码,确保转义符被正确传递:

import urllib3
import json
from urllib.parse import quote

def telegramNotification(message):
    TOKEN = "xxx:AAGrrzwEJ0Pxxxxs6h5pv0tYo9n-4"
    chat_id = -629454
    escape_chars = r'_*[]()~`>#+-=|{}.!'
    for char in escape_chars:
        message = message.replace(char, f'\\{char}')
    # 对消息进行URL编码
    encoded_message = quote(message)
    url = f"https://api.telegram.org/bot{TOKEN}/sendMessage?chat_id={chat_id}&text={encoded_message}&parse_mode=MarkdownV2"
    http = urllib3.PoolManager(timeout=5.0)
    resp = http.request('GET', url)
    respMsg = json.loads(resp.data.decode('utf-8'))
    print(respMsg)
    if respMsg["ok"]:
        print("消息发送成功")

telegramNotification('test-for-now and (stackoverflow)')
关键说明

MarkdownV2仅要求转义具有特殊语法意义的字符,统一转义所有特殊字符是最稳妥的处理方式。使用POST请求传递JSON参数是Telegram API官方推荐的方式,能彻底避免URL编码带来的转义问题。

内容的提问来源于stack exchange,提问作者Faruk Gul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 09:10:40