
在开发 telegram 机器人时,有时需要在机器人开始接收并处理用户更新之前执行一些初始化任务,例如发送欢迎消息、加载配置或收集特定信息。python-telegram-bot v20 版本引入了 applicationbuilder 和异步机制,使得这类启动时逻辑的处理方式与旧版本有所不同。本文将详细指导如何在 post_init_handler 中安全、高效地实现这些功能。
在 python-telegram-bot v20 中,要进行 Telegram API 调用,最核心的组件是 Bot 实例。在 Application 对象构建完成后,您可以通过 application.bot 属性轻松访问到它。这意味着您无需手动创建 Bot 实例,直接利用 application.bot 即可发起各种 API 请求。
例如,要在启动时向特定用户发送一条消息,您可以在 post_init_handler 中使用 await application.bot.send_message():
from telegram import Application
from telegram.ext import ApplicationBuilder, PicklePersistence
async def post_init_handler(application: Application) -> None:
"""
在机器人启动后,开始接收更新前执行的初始化逻辑。
"""
print("post_init_handler 已执行")
target_user_id = 123456789 # 替换为实际的用户ID
# 使用 application.bot 发送消息
await application.bot.send_message(
chat_id=target_user_id,
text="机器人已成功启动并执行了初始化逻辑!"
)
print(f"已向用户 {target_user_id} 发送启动消息。")
def main() -> None:
# 假设 bot_token 和 persistent_data_file_path 已定义
bot_token = "YOUR_BOT_TOKEN"
persistent_data_file_path = "bot_data.pkl"
persistence_object = PicklePersistence(filepath=persistent_data_file_path)
application = (
ApplicationBuilder()
.token(bot_token)
.persistence(persistence=persistence_object)
.post_init(post_init_handler) # 注册 post_init_handler
.build()
)
# 机器人将在此处开始轮询更新
application.run_polling()
if __name__ == "__main__":
main()
需要注意的是,Application.create_task 是 python-telegram-bot 提供的一个便利函数,用于在应用程序的事件循环中创建和管理异步任务,它主要用于通用的异步编程场景,而非直接发起 Telegram API 请求。进行 API 请求时,直接使用 application.bot 即可。
post_init_handler 是执行启动时 API 调用的理想位置。这个回调函数在 Application 对象构建完成之后、但在 application.run_polling() 开始监听并处理更新之前被调用。它的设计目的正是为了让开发者能够在机器人正式投入运行前,执行任何必要的自定义逻辑或初始化操作。
在 post_init_handler 内部,application.bot 实例已经完全可用,包括获取 bot.id 等属性。因此,将所有需要在机器人启动时执行的 API 调用或数据处理逻辑放入 post_init_handler 是最符合框架设计的方式。
一个常见的需求是获取机器人当前所在的所有聊天(包括私聊、群组、超级群组和频道)的列表及其详细信息。然而,Telegram Bot API 本身并没有提供一个直接的 API 调用来获取机器人所加入的所有聊天的完整列表。 这是 Bot API 的一个设计限制。
这意味着,您不能像查询用户或特定聊天信息那样,通过一个简单的 get_chats 或类似方法来获取这些数据。唯一可靠的方式是手动跟踪。
推荐方案:通过 chat_member 更新手动维护列表
要维护机器人所在聊天的列表,最可靠的方法是利用 Telegram 发送的 chat_member 更新。当机器人被添加到一个聊天、从一个聊天中移除,或者其在聊天中的成员状态发生变化时,Telegram 都会发送相应的 chat_member 更新。
您需要:
通过这种方式,您可以逐步构建和维护一个相对准确的机器人所在聊天列表。虽然这需要一些额外的工作,但它是目前唯一官方推荐且可靠的方案。
由于无法直接在启动时获取所有聊天列表,下面的示例将演示如何在 post_init_handler 中,结合 application.bot,将一个模拟的聊天列表信息格式化并发送给一个指定的管理员用户。这假设您已经通过手动跟踪并持久化存储的方式,获得了一个聊天列表。
from telegram import Application, ChatMember, Chat, BotCommandScopeChat
from telegram.ext import ApplicationBuilder, PicklePersistence, ChatMemberHandler
import asyncio
# 假设这是一个通过持久化存储加载的模拟聊天列表
# 实际应用中,这个列表会通过 ChatMemberHandler 动态维护
MOCKED_CHATS_DATA = [
(123456, "@user_private_chat", Chat.PRIVATE, False, "N/A"),
(-100123456789, "@my_supergroup", Chat.SUPERGROUP, True, "can_post_messages, can_delete_messages"),
(-100987654321, "Team Discussion", Chat.GROUP, False, "can_send_messages"),
(-100555444333, "Announcements Channel", Chat.CHANNEL, True, "can_edit_messages, can_delete_messages")
]
async def post_init_handler(application: Application) -> None:
"""
在机器人启动后执行的初始化逻辑,包括发送模拟聊天信息。
"""
print("post_init_handler 已执行")
admin_user_id = 123456789 # 替换为接收通知的管理员用户ID
bot_id = application.bot.id
print(f"机器人 ID: {bot_id}")
# 格式化聊天信息
chat_info_messages = ["机器人当前已知的聊天信息列表:"]
for chat_id, chat_name, chat_type, is_owner, admin_rights in MOCKED_CHATS_DATA:
info_line = (
f"ID: {chat_id}, 名称/标题: {chat_name}, 类型: {chat_type}, "
f"是否所有者: {is_owner}, 机器人权限: {admin_rights}"
)
chat_info_messages.append(info_line)
# 将所有信息合并成一条消息发送
full_message = "\n".join(chat_info_messages)
try:
await application.bot.send_message(
chat_id=admin_user_id,
text=full_message
)
print(f"已向管理员 {admin_user_id} 发送启动时的聊天信息汇总。")
except Exception as e:
print(f"发送启动信息失败: {e}")
async def chat_member_update_handler(update, context):
"""
处理 chat_member 更新,用于维护聊天列表。
(此处的实现仅为示例,实际应用中需更复杂地更新 MOCKED_CHATS_DATA)
"""
new_chat_member = update.chat_member.new_chat_member
old_chat_member = update.chat_member.old_chat_member
chat = update.effective_chat
if new_chat_member.user.id == context.bot.id and new_chat_member.status == ChatMember.MEMBER:
print(f"机器人被添加到聊天: {chat.title} ({chat.id})")
# 在这里更新 MOCKED_CHATS_DATA 或持久化存储
elif old_chat_member and old_chat_member.user.id == context.bot.id and new_chat_member.status == ChatMember.LEFT:
print(f"机器人离开了聊天: {chat.title} ({chat.id})")
# 在这里从 MOCKED_CHATS_DATA 或持久化存储中移除
def main() -> None:
bot_token = "YOUR_BOT_TOKEN" # 替换为您的机器人Token
persistent_data_file_path = "bot_data.pkl"
persistence_object = PicklePersistence(filepath=persistent_data_file_path)
application = (
ApplicationBuilder()
.token(bot_token)
.persistence(persistence=persistence_object)
.post_init(post_init_handler)
# .post_stop(post_stop_handler) # 如果有停止时的处理函数
.build()
)
# 注册 chat_member 更新处理器
application.add_handler(ChatMemberHandler(chat_member_update_handler, chat_member_types=ChatMemberHandler.MY_CHAT_MEMBER))
application.run_polling()
if __name__ == "__main__":
main()
注意: 上述示例中的 MOCKED_CHATS_DATA 仅用于演示如何格式化和发送数据。在实际应用中,您需要通过 ChatMemberHandler 动态地捕获 chat_member 更新,并将其持久化存储,而不是使用硬编码的模拟数据。
在 python-telegram-bot v20 中,利用 ApplicationBuilder 的 post_init_handler 回调函数是处理机器人启动时自定义逻辑的关键。通过 application.bot 实例,您可以方便地进行各种 Telegram API 调用。然而,需要明确的是,Telegram Bot API 不提供直接获取机器人所有聊天列表的功能;维护此类列表需要通过监听 chat_member 更新并进行持久化存储来实现。遵循这些指导原则和最佳实践,可以帮助您构建一个健壮、功能完善的 Telegram 机器人。
以上就是Telegram Bot v20:启动时获取与发送聊天信息指南的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号