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

Telegram机器人发送图片后无响应问题求助

问题描述

使用Telegram机器人时出现以下异常:

  • 单独发送/photo命令:机器人正常响应,Docker日志生成正常
  • 发送/photo命令+图片/文件:机器人无任何响应,Docker中无相关日志

相关代码如下:

主命令代码

from telegram import Update
from telegram.ext import CallbackContext
from . import BaseCommand, command_with_logs, CommandManager

class UploadPhotoCommand(BaseCommand):
    name = "photo"
    description = "send photo"

    def __init__(self, manager: CommandManager) -> None:
        self.__manager = manager

    @command_with_logs
    async def callback(self, update, context):
        try:
            photos = await update.message.photo
            await update.message.reply_text(f'Zdjęcia: {photos}')
        except Exception as e:
            await update.message.reply_text(f'Error: {e}')

补充代码

装饰器与基类

from abc import ABC, abstractmethod
from dataclasses import dataclass
from telegram import Update
from telegram.ext import CommandHandler, CallbackContext
from logs import logger

def command_with_logs(func):
    
    async def wrapper(self, update: Update, context: CallbackContext):
        logger.info(f'User {update.message.from_user.id} use command /{self.name}')
        await func(self, update, context)

    return wrapper

class BaseCommand(ABC):
    name: str
    
    description: str = None
    

    def get_handler(self) -> CommandHandler:
        
        return CommandHandler(self.name, self.callback)
    
    @abstractmethod
    async def callback(self, update: Update, context: CallbackContext):
        
        pass

命令管理器

from typing import List, Dict
from telegram.ext import Application, CommandHandler
from . import BaseCommand

class CommandManager:

    def __init__(self, app: Application) -> None:
        self.handlers: Dict[str, CommandHandler] = dict()
        self.descriptions: Dict[str, str] = {}
        self.__app = app

    def setup(self, commands: List[BaseCommand]):
        for command in commands:
            self.handlers[command.name] = command.get_handler()
            self.descriptions[command.name] = command.description
            self.__app.add_handler(self.handlers[command.name])
    
    def add_command(self, command: BaseCommand):
        handler = command.get_handler()
        self.handlers[command.name] = handler
        self.descriptions[command.name] = command.description
        self.__app.add_handler(handler)
            
    def remove_command(self, name: str):
        self.__app.remove_handler(self.handlers[name])
        self.handlers.pop(name)
        self.descriptions.pop(name)

问题排查与修复

核心原因

  1. Handler类型不匹配:当前使用的CommandHandler仅能处理纯文本命令消息。当命令与图片/文件一起发送时,Telegram会将消息标记为photo或document类型,而非command类型,导致CommandHandler无法捕获该消息,自然不会触发回调,也不会生成日志。
  2. 代码语法错误:photos = await update.message.photo写法错误,update.message.photo是属性而非可等待对象,不需要添加await关键字。

修复步骤

1. 替换为MessageHandler处理带附件的命令

将CommandHandler替换为MessageHandler,配合过滤器捕获带图片/文件的命令消息。修改UploadPhotoCommand的get_handler方法:

from telegram.ext import MessageHandler, Filters

class UploadPhotoCommand(BaseCommand):
    name = "photo"
    description = "send photo"

    def __init__(self, manager: CommandManager) -> None:
        self.__manager = manager

    def get_handler(self):
        # 捕获包含/photo命令且带有图片的消息
        return MessageHandler(Filters.command([self.name]) & Filters.photo, self.callback)

    @command_with_logs
    async def callback(self, update, context):
        try:
            # 移除多余的await
            photos = update.message.photo
            # photo是按尺寸从小到大排列的列表,取最大的那张
            if photos:
                largest_photo = photos[-1]
                await update.message.reply_text(f'收到图片,文件ID: {largest_photo.file_id}')
            else:
                await update.message.reply_text('未检测到图片')
        except Exception as e:
            await update.message.reply_text(f'Error: {str(e)}')

2. 支持多种文件类型(可选)

如果需要同时支持图片和文档,修改过滤器并扩展回调逻辑:

def get_handler(self):
    # 捕获包含/photo命令且带有图片或文档的消息
    return MessageHandler(Filters.command([self.name]) & (Filters.photo | Filters.document), self.callback)

@command_with_logs
async def callback(self, update, context):
    try:
        if update.message.photo:
            photos = update.message.photo
            largest_photo = photos[-1]
            await update.message.reply_text(f'收到图片,文件ID: {largest_photo.file_id}')
        elif update.message.document:
            doc = update.message.document
            await update.message.reply_text(f'收到文档:{doc.file_name},文件ID: {doc.file_id}')
        else:
            await update.message.reply_text('未检测到支持的文件类型')
    except Exception as e:
        await update.message.reply_text(f'Error: {str(e)}')

3. 兼容纯文本命令(可选)

若需保留纯文本/photo命令的响应,可在回调中添加无附件情况的处理:

@command_with_logs
async def callback(self, update, context):
    try:
        if update.message.photo:
            # 处理图片逻辑
            ...
        elif update.message.document:
            # 处理文档逻辑
            ...
        else:
            # 纯文本命令的提示响应
            await update.message.reply_text('请在发送/photo命令时附上图片或文件')
    except Exception as e:
        await update.message.reply_text(f'Error: {str(e)}')

验证修复

修改后重新部署机器人,测试以下场景:

  • 单独发送/photo:机器人回复提示信息,日志正常生成
  • 发送/photo+图片:机器人回复图片ID,日志正常生成
  • 发送/photo+文档:机器人回复文档信息,日志正常生成

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 19:13:13