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

Telegram API是否支持联系人多选组件?(aiogram开发场景)

Telegram API是否支持展示用户联系人列表并多选?

Telegram Bot API不提供直接调用用户私人联系人列表并支持原生多选的功能,核心原因是隐私保护机制——Bot无法主动访问用户的私人联系人数据。

针对你的需求,结合aiogram框架,有两种可行的替代方案:

1. 针对群聊场景:模拟加群式成员多选

如果你的需求是在群聊中选择成员(类似添加群成员的操作),可以通过Bot API的get_chat_members接口获取群内成员列表,再用InlineKeyboardMarkup实现多选交互:

核心实现步骤

  • 调用bot.get_chat_members获取群内非机器人成员
  • 构建带选中状态的内联键盘,通过回调函数更新选中集合
  • 提供确认按钮完成选择流程

示例代码

from aiogram import Bot, Dispatcher, types
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
from aiogram.utils import executor

API_TOKEN = "你的Bot Token"
bot = Bot(token=API_TOKEN)
dp = Dispatcher(bot)

# 存储选中的成员ID
selected_members = set()

async def get_group_members(chat_id: int):
    """获取群内非机器人成员"""
    members = []
    async for member in bot.get_chat_members(chat_id):
        if not member.user.is_bot:
            members.append((member.user.id, member.user.first_name))
    return members

async def build_multiselect_keyboard(members: list, selected: set):
    """构建多选键盘"""
    keyboard = InlineKeyboardMarkup(row_width=2)
    for user_id, name in members:
        status = "✅" if user_id in selected else "⬜"
        keyboard.add(InlineKeyboardButton(
            text=f"{status} {name}",
            callback_data=f"select:{user_id}"
        ))
    keyboard.add(InlineKeyboardButton(text="确认选择", callback_data="confirm"))
    return keyboard

@dp.message_handler(commands=['select_members'])
async def start_selection(message: types.Message):
    """触发成员选择流程"""
    if not message.chat.type in ["group", "supergroup"]:
        await message.answer("此命令仅支持群聊")
        return
    members = await get_group_members(message.chat.id)
    keyboard = await build_multiselect_keyboard(members, selected_members)
    await message.answer("请选择成员:", reply_markup=keyboard)

@dp.callback_query_handler(lambda c: c.data.startswith("select:"))
async def update_selection(callback_query: types.CallbackQuery):
    """处理成员选中/取消选中"""
    user_id = int(callback_query.data.split(":")[1])
    if user_id in selected_members:
        selected_members.remove(user_id)
    else:
        selected_members.add(user_id)
    # 更新键盘
    members = await get_group_members(callback_query.message.chat.id)
    new_keyboard = await build_multiselect_keyboard(members, selected_members)
    await callback_query.message.edit_reply_markup(reply_markup=new_keyboard)
    await callback_query.answer()

@dp.callback_query_handler(lambda c: c.data == "confirm")
async def confirm_selection(callback_query: types.CallbackQuery):
    """确认选择结果"""
    await callback_query.message.answer(f"已选中 {len(selected_members)} 名成员,ID列表:{list(selected_members)}")
    selected_members.clear()  # 清空选中集合
    await callback_query.answer()

if __name__ == '__main__':
    executor.start_polling(dp, skip_updates=True)

2. 针对私人联系人:引导用户主动分享

如果需要访问用户的私人联系人,Bot无法主动获取,只能引导用户通过ReplyKeyboardMarkup触发联系人分享,然后手动收集并维护多选列表:

示例代码片段

@dp.message_handler(commands=['share_contacts'])
async def ask_share_contact(message: types.Message):
    keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
    keyboard.add(types.KeyboardButton(text="分享联系人", request_contact=True))
    keyboard.add(types.KeyboardButton(text="完成选择"))
    await message.answer("请分享你要选择的联系人,完成后点击「完成选择」", reply_markup=keyboard)

# 存储用户分享的联系人
user_contacts = {}

@dp.message_handler(content_types=['contact'])
async def save_contact(message: types.Message):
    user_id = message.from_user.id
    if user_id not in user_contacts:
        user_contacts[user_id] = []
    # 避免重复添加
    contact = message.contact
    if not any(c['user_id'] == contact.user_id for c in user_contacts[user_id]):
        user_contacts[user_id].append({
            "user_id": contact.user_id,
            "name": f"{contact.first_name} {contact.last_name or ''}".strip()
        })
    await message.answer(f"已添加联系人:{contact.first_name}")

@dp.message_handler(lambda m: m.text == "完成选择")
async def finish_selection(message: types.Message):
    user_id = message.from_user.id
    contacts = user_contacts.get(user_id, [])
    if contacts:
        contact_list = "\n".join([f"- {c['name']}" for c in contacts])
        await message.answer(f"你选择的联系人:\n{contact_list}", reply_markup=types.ReplyKeyboardRemove())
        user_contacts.pop(user_id, None)
    else:
        await message.answer("你还未分享任何联系人", reply_markup=types.ReplyKeyboardRemove())

总结

  • 群聊内成员多选:完全可行,通过get_chat_members+内联键盘实现
  • 用户私人联系人多选:无法直接获取列表,只能引导用户主动分享后手动维护多选状态

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 16:20:44