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

如何修复Telegram机器人的AttributeError: 'NoneType' object无'bot'属性错误?

部署python-telegram-bot通知机器人到Heroku后定时任务触发报错:AttributeError: 'NoneType' object has no attribute 'bot'

我用python-telegram-bot开发了一个通知机器人,部署到Heroku平台后,定时任务触发消息发送时,Heroku日志里出现AttributeError: 'NoneType' object has no attribute 'bot'错误。

代码示例

from telegram.ext import CallbackContext
from telegram import Bot
import os

# Initialize your bot with the token from environment variable
bot_token = os.getenv('BOT_TOKEN')
if not bot_token:
    raise RuntimeError('BOT_TOKEN environment variable is not set.')

bot = Bot(bot_token)

# Messages for notifications
START_WORKDAY_MESSAGE_DRIVERS = "🚗 Work day: Notification system started! Get ready for a productive day ahead. 🌟"
END_WORKDAY_MESSAGE_DRIVERS = "🌙 Job ended for today. Thank you for your hard work! See you tomorrow. 👋"

START_WORKDAY_MESSAGE_STUDENTS = "🚌 Shuttle service is now available! You can start requesting rides. 🌟"
END_WORKDAY_MESSAGE_STUDENTS = "🚌 Shuttle service has ended for today. See you again tomorrow! 👋"

# Group ID intentionally removed
drivers_group_chat_id = -xxxxxxxxxx
pwd_group_chat_id = -xxxxxxxxxx

async def notify_workday_start_drivers(context: CallbackContext) -> None:
    await context.bot.send_message(drivers_group_chat_id, START_WORKDAY_MESSAGE_DRIVERS)

async def notify_workday_end_drivers(context: CallbackContext) -> None:
    await context.bot.send_message(drivers_group_chat_id, END_WORKDAY_MESSAGE_DRIVERS)

async def notify_workday_start_students(context: CallbackContext) -> None:
    await context.bot.send_message(pwd_group_chat_id, START_WORKDAY_MESSAGE_STUDENTS)

async def notify_workday_end_students(context: CallbackContext) -> None:
    await context.bot.send_message(pwd_group_chat_id, END_WORKDAY_MESSAGE_STUDENTS)

Heroku错误日志

2024-06-16T23:07:00.043132+00:00 app[web.1]: Traceback (most recent call last):
2024-06-16T23:07:00.043133+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.11/site-packages/apscheduler/executors/base_py3.py", line 30, in run_coroutine_job
2024-06-16T23:07:00.043133+00:00 app[web.1]: retval = await job.func(*job.args, **job.kwargs)
2024-06-16T23:07:00.043134+00:00 app[web.1]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-06-16T23:07:00.043134+00:00 app[web.1]: File "/app/notifications.py", line 28, in notify_workday_end_drivers
2024-06-16T23:07:00.043135+00:00 app[web.1]: await context.bot.send_message(drivers_group_chat_id, END_WORKDAY_MESSAGE_DRIVERS)
2024-06-16T23:07:00.043135+00:00 app[web.1]: ^^^^^^^^^^^
2024-06-16T23:07:00.043135+00:00 app[web.1]: AttributeError: 'NoneType' object has no attribute 'bot'
2024-06-16T23:07:00.043268+00:00 app[web.1]: 2024-06-16 23:07:00,043 - apscheduler.executors.default - INFO - Running job "notify_workday_end_students (trigger: cron[hour='23', minute='7'], next run at: 2024-06-17 23:07:00 UTC)" (scheduled at 2024-06-16 23:07:00+00:00)
2024-06-16T23:07:00.043293+00:00 app[web.1]: Context object: None

2024-06-16T23:07:00.043772+00:00 app[web.1]: Traceback (most recent call last):
2024-06-16T23:07:00.043772+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.11/site-packages/apscheduler/executors/base_py3.py", line 30, in run_coroutine_job
2024-06-16T23:07:00.043772+00:00 app[web.1]: retval = await job.func(*job.args, **job.kwargs)
2024-06-16T23:07:00.043773+00:00 app[web.1]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-06-16T23:07:00.043773+00:00 app[web.1]: File "/app/notifications.py", line 36, in notify_workday_end_students
2024-06-16T23:07:00.043773+00:00 app[web.1]: await context.bot.send_message(pwd_group_chat_id, END_WORKDAY_MESSAGE_STUDENTS)
2024-06-16T23:07:00.043773+00:00 app[web.1]: ^^^^^^^^^^^
2024-06-16T23:07:00.043774+00:00 app[web.1]: AttributeError: 'NoneType' object has no attribute 'bot'
解决方案
  • 错误原因:用APScheduler调度任务时,没有传入有效的CallbackContext对象,导致context为None。CallbackContext是python-telegram-bot框架内部用于传递上下文的对象,直接通过APScheduler调用的任务不会自动生成这个对象。
  • 修复方式:直接使用已初始化好的全局bot实例发送消息,不需要依赖CallbackContext。

修改后的代码

from telegram import Bot
import os

# Initialize your bot with the token from environment variable
bot_token = os.getenv('BOT_TOKEN')
if not bot_token:
    raise RuntimeError('BOT_TOKEN environment variable is not set.')

bot = Bot(bot_token)

# Messages for notifications
START_WORKDAY_MESSAGE_DRIVERS = "🚗 Work day: Notification system started! Get ready for a productive day ahead. 🌟"
END_WORKDAY_MESSAGE_DRIVERS = "🌙 Job ended for today. Thank you for your hard work! See you tomorrow. 👋"

START_WORKDAY_MESSAGE_STUDENTS = "🚌 Shuttle service is now available! You can start requesting rides. 🌟"
END_WORKDAY_MESSAGE_STUDENTS = "🚌 Shuttle service has ended for today. See you again tomorrow! 👋"

# Group ID intentionally removed
drivers_group_chat_id = -xxxxxxxxxx
pwd_group_chat_id = -xxxxxxxxxx

async def notify_workday_start_drivers() -> None:
    await bot.send_message(drivers_group_chat_id, START_WORKDAY_MESSAGE_DRIVERS)

async def notify_workday_end_drivers() -> None:
    await bot.send_message(drivers_group_chat_id, END_WORKDAY_MESSAGE_DRIVERS)

async def notify_workday_start_students() -> None:
    await bot.send_message(pwd_group_chat_id, START_WORKDAY_MESSAGE_STUDENTS)

async def notify_workday_end_students() -> None:
    await bot.send_message(pwd_group_chat_id, END_WORKDAY_MESSAGE_STUDENTS)

额外注意

如果任务是通过APScheduler添加的,需要修改任务调用代码,去掉原来传入的context参数。比如原来的:

scheduler.add_job(notify_workday_end_drivers, 'cron', hour=23, minute=7, args=(context,))

改成:

scheduler.add_job(notify_workday_end_drivers, 'cron', hour=23, minute=7)

内容的提问来源于stack exchange,提问作者Anthony Sackey

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 07:25:55