通过Telegram管理Bot用python(telebot)获取订阅者用户名及来源
基于pyTelegramBotAPI(telebot)的频道管理问题解答
前置要求
你的机器人必须被设置为频道管理员,且开启以下对应权限,否则接口会返回权限错误:
- 获取成员列表权限
- (如需监听加入来源)邀请链接查看权限、成员变动事件接收权限
1. 获取频道所有订阅者用户名的实现方法
Telegram Bot API 不支持一次性拉取全量频道成员,需要分页循环拉取,单页最多返回200条成员数据。注意只有设置了公开用户名、且未对机器人隐藏隐私信息的用户,才能拿到有效的用户名,未设置用户名的用户只能通过用户ID做唯一标识。
操作步骤
- 先安装依赖库:
pip install pyTelegramBotAPI - 参考以下代码实现全量拉取:
import telebot # 替换为你的机器人Token BOT_TOKEN = "你的机器人API Token" # 替换为你的频道ID,公开频道可填@频道用户名,私有频道为-100开头的数字ID CHANNEL_ID = -1001234567890 bot = telebot.TeleBot(BOT_TOKEN) def get_all_subscribers(chat_id): user_list = [] offset = 0 single_page_limit = 200 # API规定单页最大拉取量为200 while True: members = bot.get_chat_members(chat_id, offset=offset, limit=single_page_limit) if not members: break for member in members: # 过滤已退出、被封禁的非有效订阅者 if member.status in ["kicked", "left"]: continue user = member.user if user.username: user_list.append(f"@{user.username}") else: user_list.append(f"未设置公开用户名,用户ID:{user.id}") offset += len(members) # 当前页返回数量小于单页上限时,说明已拉取完全部成员 if len(members) < single_page_limit: break return user_list if __name__ == "__main__": subscribers = get_all_subscribers(CHANNEL_ID) print(f"有效订阅者总数:{len(subscribers)}") for user in subscribers: print(user)
注意事项
- 若频道成员数超过1万,普通机器人会触发API频率限制,无法拉取全量成员,需要申请官方企业级Bot权限才能解除限制
- 开启了严格隐私模式的用户,即使有公开用户名,也不会对未发起过私聊的机器人展示,这类用户的username字段会返回空值
2. 查询订阅者邀请来源的能力说明
普通场景下无法批量回溯历史已加入订阅者的邀请链接来源,仅能对机器人上线监听后新加入的用户,在加入瞬间获取对应的邀请链接信息:
- 机器人被设为管理员之前就已经加入频道的老成员,没有任何官方接口可以回溯其加入时使用的邀请链接
- 没有开启实时成员变动监听的情况下,新用户加入后再查询也无法拿到对应的邀请来源信息
实时监听新用户邀请来源的实现
你可以通过监听chat_member成员变动事件,在用户加入频道的瞬间获取其来源邀请链接,参考代码如下:
@bot.chat_member_handler() def track_join_source(update: telebot.types.ChatMemberUpdated): # 仅处理目标频道的事件 if update.chat.id != CHANNEL_ID: return old_status = update.old_chat_member.status new_status = update.new_chat_member.status # 仅处理用户从非成员变为有效成员的加入场景 if old_status not in ["left", "kicked"] or new_status not in ["member", "restricted", "administrator"]: return new_user = update.new_chat_member.user user_mark = f"@{new_user.username}" if new_user.username else f"用户ID:{new_user.id}" invite = update.invite_link if invite: print(f"新成员加入:{user_mark},来源邀请链接:{invite.invite_link},链接创建者ID:{invite.creator.id}") else: print(f"新成员加入:{user_mark},无有效邀请链接记录(可能为公开链接进入、管理员手动拉入)") if __name__ == "__main__": # 启动轮询,指定接收成员变动类型的更新 bot.infinity_polling(allowed_updates=["chat_member"])
注意事项
- 需要提前在BotFather中为机器人开启
Chat Member更新接收权限,同时给机器人分配频道的「查看邀请链接」管理员权限,否则拿不到invite_link字段 - 用户通过公开频道链接、管理员直接拉人、已失效的旧邀请链接进入时,invite_link字段会返回空值,无法溯源
- 所有声称可以批量查询历史成员邀请来源的非官方方案都属于接口滥用,有机器人被封禁、频道被限制的风险
内容的提问来源于stack exchange,提问作者NAZ.42
相关产品推荐
相关产品推荐

