Python aiogram框架中如何在同步函数内通过机器人发送消息
解决方案
原有请求失效原因
直接拼接参数到URL的写法没有对参数做URL编码,parse_message里的特殊字符(空格、换行、HTML标签、特殊符号)、reply_markup对应的JSON结构都会破坏URL格式,不符合Telegram Bot API的请求要求。同时GET请求存在参数长度限制,本身就不适合传复杂的消息参数。
可行实现方案
方案1:修正requests请求写法(支持parse_mode和inline按钮)
requests本身完全支持指定parse_mode和附加inline按钮,只需换用POST请求,参数交给requests自动编码即可,示例代码如下:
import requests import json # 将inline键盘对象序列化为JSON字符串 reply_markup = json.dumps(open_tp.to_python()) # 发送POST请求,参数自动处理编码 resp = requests.post( f"https://api.telegram.org/bot{BOT_TOKEN}/sendMessage", data={ "chat_id": chat_id, "text": parse_message, "parse_mode": "HTML", "reply_markup": reply_markup } ) # 可选:打印返回结果校验是否发送成功 print(resp.json())
方案2:同步函数中直接调用aiogram原生方法
不需要绕开bot.send_message,在同步函数中可以通过asyncio.run单独执行发消息的协程即可,无需启动完整的aiogram事件循环:
import asyncio from aiogram import Bot async def send_telegram_msg(): bot = Bot(token=BOT_TOKEN) await bot.send_message( chat_id=chat_id, text=parse_message, parse_mode="HTML", reply_markup=open_tp ) # 关闭bot会话避免资源泄漏 await bot.session.close() # 同步代码中直接调用执行协程 asyncio.run(send_telegram_msg())
如果你的同步函数运行在已有事件循环的环境中(比如异步Web框架的同步视图),可以用asgiref.sync.async_to_sync包装调用避免冲突:
from asgiref.sync import async_to_sync async_to_sync(send_telegram_msg)()
内容的提问来源于stack exchange,提问作者429
相关产品推荐
相关产品推荐

