Telegram机器人如何查看自己是否被用户屏蔽?完整教程

这是Telegram机器人开发者的实用指南,介绍如何通过主动发送消息和监听my_chat_member更新两种方法,判断用户是否屏蔽了机器人,并提供Python代码示例。

阅读提示建议先浏览小标题,再按需深入阅读具体段落。

在使用Telegram机器人时,用户可能会因为各种原因屏蔽机器人,比如认为消息打扰、不再需要服务等。当用户屏蔽机器人后,机器人将无法主动向该用户发送消息,也无法获取用户的在线状态等信息。那么,机器人如何知道用户已经屏蔽了自己呢?本文将介绍两种最有效的方法,并提供完整的Python代码示例。

一、检测屏蔽的原理

Telegram Bot API并没有提供一个直接的“查询是否被屏蔽”的方法,但我们可以通过间接手段来判断:

  • 主动检测:尝试向用户发送消息,根据返回的错误状态判断。
  • 被动监听:监听Telegram发送的my_chat_member更新,从中获取用户屏蔽机器人的事件。

这两种方法各有适用场景,建议开发者根据实际需求选择或组合使用。

二、方法一:主动发送消息检测

这是最直观的方法。机器人向目标用户发送一条消息(例如“Are you still there?”),如果用户已经屏蔽了机器人,Telegram API会返回HTTP 403错误,错误描述为“Forbidden: bot was blocked by the user”。我们只需要捕获这个错误,就能确认用户已屏蔽机器人。

Python实现(使用requests直接调用Bot API)

import requests
import time

def check_user_blocked(bot_token, chat_id):
    url = f"https://api.telegram.org/bot/sendMessage"
    payload = {
        "chat_id": chat_id,
        "text": "ping"
    }
    try:
        response = requests.post(url, json=payload, timeout=10)
        if response.status_code == 200:
            return False  # 消息发送成功,用户未屏蔽
        elif response.status_code == 403:
            data = response.json()
            if data['description'] == 'Forbidden: bot was blocked by the user':
                return True  # 用户已屏蔽
            else:
                # 其他403原因,例如群组权限不足
                return False
        else:
            # 其他错误,如网络问题或速率限制
            print(f"Unexpected error: {response.status_code}")
            return False
    except Exception as e:
        print(f"Request failed: ")
        return False

# 使用示例
token = "YOUR_BOT_TOKEN"
user_chat_id = 123456789
if check_user_blocked(token, user_chat_id):
    print("用户已屏蔽机器人")
else:
    print("用户未屏蔽或消息正常发送")

使用python-telegram-bot库

from telegram import Bot
from telegram.error import Forbidden

async def is_blocked(bot, chat_id):
    try:
        await bot.send_message(chat_id=chat_id, text="ping")
        return False
    except Forbidden as e:
        if "blocked by the user" in str(e):
            return True
        else:
            return False
    except Exception as e:
        print(f"其他错误: ")
        return False

注意:主动检测会向用户发送一条消息,如果频繁检测可能引起用户反感,甚至被举报。因此,建议仅在必要时使用,比如用户超过一定天数未活动时。

三、方法二:监听my_chat_member更新(被动检测)

Telegram提供了my_chat_member更新,每当机器人与某个用户之间的状态发生变化时(例如用户屏蔽机器人、取消屏蔽、机器人被加入群组等),Bot API都会推送一个包含my_chat_member字段的Update。

我们只需解析更新中的new_chat_member.status,如果状态为`kicked`,说明用户屏蔽了机器人;如果状态变为`member`(或`new_chat_member`),则说明用户取消了屏蔽。

使用python-telegram-bot库处理

from telegram.ext import Application, ChatMemberHandler

def on_my_chat_member(update, context):
    new_status = update.my_chat_member.new_chat_member.status
    user_id = update.my_chat_member.from_user.id
    if new_status == 'kicked':
        print(f"用户  屏蔽了机器人")
    elif new_status == 'member':
        print(f"用户  解除了屏蔽")

# 创建Application并注册处理器
def main():
    application = Application.builder().token("YOUR_BOT_TOKEN").build()
    application.add_handler(ChatMemberHandler(on_my_chat_member, ChatMemberHandler.MY_CHAT_MEMBER))
    application.run_polling()

if __name__ == '__main__':
    main()

使用node-telegram-bot-api(Node.js)

const TelegramBot = require('node-telegram-bot-api');
const bot = new TelegramBot('YOUR_BOT_TOKEN', {polling: true});

bot.on('my_chat_member', (msg) => {
  const newStatus = msg.my_chat_member.new_chat_member.status;
  const userId = msg.my_chat_member.from.id;
  if (newStatus === 'kicked') {
    console.log(`用户 $ 屏蔽了机器人`);
  } else if (newStatus === 'member') {
    console.log(`用户 $ 解除了屏蔽`);
  }
});

被动检测的优势在于实时、无打扰,且不需要知道用户的chat_id(更新中包含chat信息)。但需要确保机器人持续运行(如使用Webhook或长轮询),且处理程序能够及时响应。对于需要记录屏蔽状态的场景,建议将状态存储到数据库,避免重复处理。

四、方法对比与注意事项

对比项主动发送消息监听my_chat_member
实时性低(需要触发检测)高(实时推送)
打扰性有(发送消息)
要求需要用户chat_id无需额外参数,但需持续监听
可靠性较高(403错误明确)高(事件驱动)
适用场景定期清理失效用户实时更新用户状态

注意事项:

  • 主动检测时,应控制频率,避免触发Bot API的速率限制。
  • 监听my_chat_member时,需要处理来自群组、频道等不同chat类型的更新,本文章只涉及与用户的私聊。
  • 若机器人同时运行多个实例,要防止重复处理,建议结合数据库唯一索引。
  • 用户屏蔽机器人后,机器人无法通过API获取用户的更多信息(如Profile照片),但之前缓存的数据仍可使用。

五、总结

检测用户是否屏蔽Telegram机器人,虽然没有直接的方法,但通过主动发送消息或监听my_chat_member事件,我们可以准确、及时地掌握用户状态。主动方法适合周期性清理,被动方法适合实时响应。在实际开发中,建议优先采用被动监听,以减少不必要的消息打扰,并提高效率。

希望本教程能帮助你的Telegram机器人更智能地管理用户关系,提升用户体验。

FAQ

安卓版下载指南

常见问题

Telegram机器人能直接查出被哪些用户屏蔽了吗?

不能。Telegram Bot API没有提供查询屏蔽列表的方法。只能通过主动发送消息(返回403错误)或监听my_chat_member更新来逐个判断或实时记录。

如果用户屏蔽了机器人,机器人还能收到用户的消息吗?

不能。如果用户屏蔽了机器人,机器人不仅无法发送消息,也无法接收到该用户发送的消息。但如果用户是在群组中屏蔽了机器人,机器人仍可能收到群组中的消息(取决于群组设置)。

监听my_chat_member更新时,如何区分用户屏蔽了机器人和踢出群组?

my_chat_member更新包含chat对象。对于私聊,chat的type为'private';对于群组,type为'group'或'supergroup'。你可以先检查chat.type,只有private类型的聊天中status变为'kicked'才表示用户屏蔽了机器人。