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

Telegram内联机器人能否用用户名作chat_id发消息?遇Chat未找到问题

问题:Telegram机器人通过用户名发送消息时提示“聊天未找到”

我有一个Telegram机器人,希望通过指定用户的用户名来给该用户发送消息,但一直收到“聊天未找到”的错误。buyer_username变量来自我调用机器人时传入的查询内容(即@Bot 用户名.)。

我查阅文档后了解到,机器人无法给未向其发送过消息的用户发消息,于是我用目标用户名对应的设备给机器人发了一条消息,但再次尝试后仍出现相同问题。请问这种实现方式可行吗?

以下是处理逻辑的代码片段:

def inline_query(update: Update, context: CallbackContext) -> int:
    _, _ = User.get_user_and_created(update, context)
    is_verified: bool = is_seller_verified(update.inline_query.from_user.id)
    if is_verified:
        query = update.inline_query.query
        if len(query) == 0 or query[-1] != '.':
            print('Empty query, showing message to seller to type username of buyer')
            results = [
                InlineQueryResultArticle(
                    id='Noop',
                    title=noop_title,
                    input_message_content=InputTextMessageContent(noop_description),
                    thumb_url='https://i.imgur.com/1tDhWge.png',
                    thumb_width=64,
                    thumb_height=64
                )
            ]
            update.inline_query.answer(results)
        elif len(query) > 1 and query.endswith('.'):
            buyer_username = query[:-1]
            emoji_hash = _random_emoji()
            seller_username: str = update.inline_query.from_user.username
            seller_tg_id: int = update.inline_query.from_user.id
            total_count, buyer_count = get_transaction_info(seller_tg_id, buyer_username)
            emoji_code: str = _emoji_password(seller_username, update.inline_query.from_user.id)  # TODO: make more complex
            verified_message_1 = verify_message_1 % (
                emoji_code,
                buyer_count,
                total_count,
                seller_username,
                _get_transaction_datetime(),
            )
            keyboard = [
                [
                    InlineKeyboardButton(emoji_code, callback_data=GO_TO_CONFIRM),
                ],
                [
                    InlineKeyboardButton(emoji_hash, callback_data=GO_TO_RETRY),
                ],
            ]
            random.shuffle(keyboard)
            reply_markup = InlineKeyboardMarkup(keyboard)
            context.user_data['buyer_username'] = buyer_username
            print(buyer_username)
            context.bot.send_message(chat_id=buyer_username, text=verified_message_1,
                                     reply_markup=reply_markup)
    else:
        keyboard = [
            [
                InlineKeyboardButton(text=start_verification_title, url='https://t.me/clientverify_bot'),
            ],
        ]
        reply_markup = InlineKeyboardMarkup(keyboard)
        context.bot.send_message(chat_id=buyer_username,
                                 text=start_verification_message,
                                 reply_markup=reply_markup
                                 )
    return IMMUTABLE_STATE

解决方案

通过用户名给用户发消息是可行的,但你的代码存在几个关键问题:

  • 用户名格式错误:send_message的chat_id参数如果传入用户名,必须带@前缀(比如@testuser)。你的buyer_username是从query[:-1]获取的,用户输入的是“用户名.”,所以最终得到的是不带@的纯用户名,机器人无法识别这个格式的聊天ID。
  • 隐私设置限制:即使用户给机器人发过消息,如果用户在Telegram隐私设置中开启了“不允许陌生人通过用户名找到我”,机器人依然无法通过用户名发送消息,这种情况下必须使用用户的唯一ID。
  • 逻辑漏洞:else分支中的buyer_username变量未定义,会直接抛出变量未找到的错误,因为这个变量只有在is_verified且query.endswith('.')的分支里才被赋值。

针对这些问题的修复建议:

  1. 修正用户名格式:在代码中给buyer_username自动添加@前缀:

    buyer_username = f"@{query[:-1]}"
    

    或者要求用户输入带@的用户名(比如@testuser.)。

  2. 优先使用用户ID:如果能通过历史交互记录获取买家的ID,用ID作为chat_id比用户名更可靠,因为ID不受隐私设置影响,且是唯一标识。

  3. 添加错误处理:给send_message添加异常捕获,处理ChatNotFound等错误,并给卖家返回提示:

    from telegram.error import ChatNotFound
    
    try:
        context.bot.send_message(chat_id=buyer_username, text=verified_message_1, reply_markup=reply_markup)
    except ChatNotFound:
        # 给卖家发送提示消息
        update.inline_query.answer([
            InlineQueryResultArticle(
                id='error',
                title='发送失败',
                input_message_content=InputTextMessageContent('无法找到该用户,请检查用户名是否正确,或确认用户已给机器人发过消息')
            )
        ])
    
  4. 修复else分支逻辑:else分支应该给当前发起请求的卖家发消息,而不是未定义的buyer_username,修改为:

    context.bot.send_message(chat_id=update.inline_query.from_user.id,
                             text=start_verification_message,
                             reply_markup=reply_markup
                             )
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 13:35:15