Python调用Telegram Bot API sendMessage报400错误:文本非空却提示为空
问题
用Python编写异步函数调用Telegram Bot API的sendMessage接口时,出现400错误(Bad Request: message text is empty),但传入的message_text参数并非空值。
原函数代码:
async def send_message(message_text: str, ids: list[int]): try: load_dotenv(env_path()) token = bot_secret() for id in ids: response = requests.post(f"https://api.telegram.org/bot{token}/sendMessage", data={ "chat_id": id, "text": message_text, "parse_mode": "Markdown", "disable_web_page_preview": "true"}) response.raise_for_status() except requests.exceptions.HTTPError as err: logger.error(err)
将text字段改为固定值"simple text"时,请求可正常执行:
async def send_message(message_text: str, ids: list[int]): try: load_dotenv(env_path()) token = bot_secret() for id in ids: response = requests.post(f"https://api.telegram.org/bot{token}/sendMessage", data={ "chat_id": id, "text": "simple text", "parse_mode": "Markdown", "disable_web_page_preview": "true"}) response.raise_for_status() except requests.exceptions.HTTPError as err: logger.error(err)
排查与解决思路
校验消息文本的实际内容
即使参数声明为str,也可能传入仅含空白字符(空格、换行符等)的字符串,Telegram API会判定为空。可以在发送前添加校验:message_text = message_text.strip() if not message_text: logger.warning("消息文本为空或仅含空白字符") return排查Markdown格式错误
当parse_mode设为Markdown时,若message_text存在不符合Telegram Markdown规范的语法(比如未闭合的加粗标签、转义错误),API可能返回类似文本为空的错误(实际是解析失败)。可以临时将parse_mode改为None或"HTML"测试,若能正常发送,则需修正文本的Markdown格式。修正异步函数中的同步请求问题
函数用async定义,但内部使用同步的requests.post,虽不会直接导致文本为空,但可能引发参数传递异常。如果要保持异步特性,建议改用aiohttp库发送请求:import aiohttp async def send_message(message_text: str, ids: list[int]): try: load_dotenv(env_path()) token = bot_secret() async with aiohttp.ClientSession() as session: for id in ids: async with session.post( f"https://api.telegram.org/bot{token}/sendMessage", data={"chat_id": id, "text": message_text, "parse_mode": "Markdown", "disable_web_page_preview": True} ) as response: response.raise_for_status() except aiohttp.ClientResponseError as err: logger.error(err)注意
disable_web_page_preview应传递布尔值True而非字符串"true",符合API参数类型要求更稳妥。检查参数传递时的隐式修改
确认调用send_message时传入的message_text是否被其他函数意外修改为空,或是传入了None(Python不会强制校验类型注解)。可以在函数开头添加日志打印真实内容:logger.info(f"待发送消息内容:{repr(message_text)}")用
repr()能直观看到字符串中的不可见字符。
内容的提问来源于stack exchange,提问作者DmitryIsaev

