飞书机器人自动创建腾讯会议:双端API对接实践与排坑指南 📅 发布时间:2026/9/16 0:46:57 👁 浏览次数: 做这个对接的起因特别朴素公司内部消息都走飞书客户和外部合作方开会基本都用腾讯会议。以前每次约外部会都得先在飞书群里对齐时间再跑到腾讯会议客户端里创建会议然后把会议链接、会议号、入会密码复制回飞书群。一周几十场会下来重复劳动不说还经常出现链接已过期、密码发错人的尴尬。所以我把两个工具的接口层面打通了目标就一句话在飞书群里发一条斜杠指令机器人自动创建腾讯会议并把带入会链接的卡片推回群内。这次实践记录主要讲飞书自建应用和腾讯会议REST API的完整对接过程内容包括双端应用的凭证申请、回调签名验证、创建会议与消息卡片下发的核心代码以及联调阶段遇到的三类高频问题。适合企业内部工具开发者、运维和实施同学参考。读完你至少能弄清楚两件事一是两端授权模型差异怎么处理二是会议链接推送到飞书群后怎么把“创建成功”和“入会失败”这类设备侧问题区分开。1. 对接前先拆清楚业务链路飞书管“发起”腾讯会议管“会议”1.1 最常见的对接场景群聊指令触发会议创建在写代码之前先把业务链路按文字捋一遍用户在飞书群内发送指令机器人监听群消息解析出会议主题、开始时间、参会人调用腾讯会议接口创建会议拿到入会链接后通过飞书机器人推送一张交互卡片到群里用户点击卡片中的“加入会议”按钮直接唤起腾讯会议客户端或网页入会。示例指令/meeting 项目评审 2025-03-18 14:00 60 张三,李四解析逻辑不复杂按空格拆分就可以但需要考虑主题里可能带空格所以我建议用固定顺序动作名之后第一段是主题第二段是开始时间第三段是时长分钟第四段开始是可选参会人列表。这个约定要在群里先和同事说清楚否则解析失败率会高到让人怀疑人生。比如有人把会议主题写成“产品评审/需求确认”中间带了个斜杠不提前约定好后端切分就会错位。1.2 飞书侧的资源模型群、机器人、卡片、事件订阅要打通飞书侧得先搞清楚几个基础概念。飞书里的应用是以机器人身份存在于群里的群消息通过事件订阅推送到你的后端后端拿到内容后可以调用API往指定群发消息。这里有两个关键标识chat_id和open_id。chat_id是群的唯一标识一般以oc_开头open_id是用户的唯一标识。机器人发消息时receive_id传chat_id就能把消息发到群里。权限方面我实际用到的飞书API权限如下表权限名称权限Code用途获取群组信息im:chat通过群链接或ID获取chat_id获取与发送单聊、群组消息im:message接收群消息并发送通知获取群消息中机器人消息im:message.group_at_msg只订阅群里机器人的消息避免处理所有聊天记录获取用户基本信息contact:user.base:readonly根据open_id查询用户姓名这些权限可以在飞书开发者后台的“权限管理”里搜索并开通。注意自建应用改完权限以后必须创建版本并发布权限才会真正生效。我在测试环境就因为忘了发布版本回调通了但API一直返回权限不足排查了大半天才发现是版本没发布。1.3 腾讯会议侧的资源模型企业应用、用户凭证、会议对象腾讯会议开放平台把能力封装成REST API核心对象是会议meeting。创建会议时需要明确会议主题、开始时间、结束时间、会议类型、主持人、参会人等信息。API返回的主要字段有meeting_id字符串唯一ID、meeting_code就是传统会议号、join_url入会链接、host_join_url主持人入会链接。和飞书不太一样的是腾讯会议的access_token背后通常绑定一个“应用”或“企业”不是随便一个用户就能创建会议。个人开发者申请的是个人应用企业场景建议申请企业应用审批通过后拿到的token权限范围更稳定。我第一次对接时用了个人应用测试结果创建会议时部分会议室能力不能用后面切换成企业应用才解决。这块在后面章节细说。2. 双端应用注册与凭证申请授权模型差异是最大的坑2.1 飞书自建应用的创建与权限配置明细飞书端整体流程如下打开飞书开放平台创建企业自建应用应用类型选“企业自建”。进入“应用能力”添加“机器人”能力这样应用能在群里以机器人身份发消息。进入“权限管理”把上一节表格里的权限全部勾选。进入“事件与回调”订阅方式可以选择长连接或Webhook。如果后端服务没有公网地址开发联调阶段建议先用长连接模式WebSocket免去公网回调调试的麻烦生产环境再切换成Webhook。我当时为了省事直接用长连接结果后面需要接收腾讯会议回调时发现长连接只解决飞书的事件订阅和腾讯会议的webhook没关系还是得部署一个公网HTTPS服务。所以这里提前提醒如果后续要接收腾讯会议的结束事件回传一定要准备一台公网可访问的HTTPS服务器。在“凭证与基础信息”里复制App ID和App Secret在“事件与回调”页面配置Encrypt Key和Verification Token。这些后面都会用到。这里有一个很实用的细节飞书后台支持设置“事件订阅的安全设置”如果你想先快速跑通Demo可以把加解密模式先设为明文等链路通了再改成加密。加密模式更安全但调试时多一层解密会让人分不清问题到底出在事件解析还是加密逻辑。2.2 腾讯会议开放平台应用申请与API权限腾讯会议端整体流程如下登录腾讯会议开放平台创建一个应用类型根据场景选“企业应用”或“个人应用”。在应用详情里拿到Client ID和Client Secret注意这两个值后面换access_token要用。在“接口权限”里申请需要的API比如创建会议、查询会议、修改会议、结束会议。申请接口权限一般需要写明用途等审核通过后调用才不会报401或403。记录你的企业ID或应用标识有些接口需要结合X-TC-Key之类参数使用。具体以你申请到的应用信息为准。申请权限时有两点建议第一尽量一次性把会上要用到的几个接口都申请掉因为审核是按接口维度来的分开申请容易拖慢项目进度第二如果需要把会议创建到指定用户的账号下要确认你创建的是“用户托管”还是“应用托管”类型。常见的对接方案是应用托管也就是会议挂在应用对应的企业账号下不依赖某个具体员工是否有会议客户端。2.3 双端凭证的统一存储与自动续期两边token的过期策略不同放在一起对比更直观平台获取接口凭证有效期刷新方式飞书POST /open-apis/auth/v3/tenant_access_token/internal2小时用App ID App Secret重新请求腾讯会议POST /v1/real-auth/access-token2小时不同应用类型有差异用Client ID Client Secret重新请求如果每次请求都现取token会拖慢响应还可能触发限流。我在代码里用Redis做缓存key分别叫feishu_tenant_token和tencent_meeting_tokenvalue是token本身过期时间设为有效期的80%。取的时候先查缓存没有或快过期了再去接口获取并写回。并发情况下要加锁或直接容忍偶尔重复获取不要多个请求同时刷新token导致部分请求拿到过期的旧token。3. 核心链路实现飞书群里发一条指令自动创建腾讯会议3.1 后端服务基本框架与飞书回调签名校验后端我用Python FastAPI写的核心就两个接口一个是/feishu/event接收飞书事件回调一个是/health用于健康检查。开发阶段用uvicorn起服务生产环境可以挂gunicorn或者放到云函数的HTTP触发器里。飞书事件回调有“明文模式”和“加密模式”。为了安全生产环境必须用加密模式。加密模式下飞书POST过来的body是加密字符串你需要用Encrypt Key解密再处理内部事件。先看一个简化版的回调入口from fastapi import FastAPI, Request from cryptography.fernet import Fernet import base64, hashlib app FastAPI() def decrypt_feishu_payload(body: dict, encrypt_key: str) - dict: # 实际飞书使用的是AES-256-CBC加密这里只做示意 # 请按飞书官方文档的加解密示例实现 encrypted body.get(encrypt, ) return decrypt_message(encrypted, encrypt_key) app.post(/feishu/event) async def receive_feishu_event(request: Request): body await request.json() # 1. URL验证飞书第一次配置回调地址时会下发challenge if body.get(type) url_verification: return {challenge: body.get(challenge)} # 2. 事件回调 event body.get(event, {}) # 这里把事件丢给消息处理函数 handle_message(event) return {code: 0}注意上面解密函数是示意真实实现要参考飞书官方加解密SDK不建议自己造轮子。我犯过的错是直接把encrypt字段原样返回给challenge校验结果一直失败。正确的做法是如果开启了加密URL验证时飞书也会把challenge包在encrypt里你需要先解密再返回明文challenge响应格式是{challenge: 解密后的内容}。这个点卡了我差不多半小时。3.2 解析指令并调用腾讯会议创建接口消息事件拿到后先判断是否是机器人且文本以“/meeting”开头。用正则提取参数把主题和开始时间拆出来。时间处理推荐用zoneinfo或者pytz不要用本地默认时区。腾讯会议API的start_time和end_time一般是Unix毫秒时间戳13位如果你传10位秒级时间戳接口大概率会报参数错误。创建会议的请求示例def create_tencent_meeting(subject: str, start_ms: int, duration_minutes: int): token get_tencent_access_token() end_ms start_ms duration_minutes * 60 * 1000 payload { subject: subject, start_time: str(start_ms), end_time: str(end_ms), meeting_type: 0, # 0: 普通会议 settings: { mute_enable: 1, allow_unmute_self: 1 } } headers { Authorization: fBearer {token}, X-TC-Key: 你的应用标识, Content-Type: application/json } resp requests.post(https://api.meeting.qq.com/v1/meetings, jsonpayload, headersheaders, timeout10) return resp.json()X-TC-Key这个字段不一定所有应用都需要具体看腾讯会议开放平台文档。返回值里meeting_id是字符串meeting_code是数字会议号join_url是普通成员入会链接。如果返回的error_code不是0要把错误码和msg都打到日志里。常见如InvalidParameter、UnauthorizedOperation.UserNotExists等后面排错会用到。顺手整理一份我遇到的错误码对照不一定覆盖所有版本但可以帮你快速定位返回错误可能原因排查方向InvalidParameter时间戳格式不对、上下文参数缺失检查是否传了毫秒级时间戳结束时间是否晚于开始时间UnauthorizedOperation应用没有接口权限或token过期确认权限申请已审批刷新access_tokenUserNotExists指定用户ID在腾讯会议侧不存在确认用户有没有腾讯会议账号或是否在企业通讯录内MeetingNotExist会议ID或会议号错了检查数据库里存的meeting_id是否被误删或被覆盖3.3 会议链接以飞书消息卡片形式回传群聊会议创建成功后我用飞书消息卡片把信息推回群。这里用im/v1/messages接口发送interactive消息def send_meeting_card(chat_id: str, meeting: dict): content { config: {wide_screen_mode: True}, header: { title: {tag: plain_text, content: 会议创建成功}, template: blue }, elements: [ {tag: div, text: {tag: lark_md, content: f**主题**{meeting[subject]}}}, {tag: div, text: {tag: lark_md, content: f**会议号**{meeting[meeting_code]}}}, {tag: div, text: {tag: lark_md, content: f**密码**{meeting.get(password, 无)}}}, {tag: action, actions: [ {tag: button, text: {tag: plain_text, content: 加入会议}, type: primary, href: meeting[join_url]} ]} ] } body { receive_id: chat_id, msg_type: interactive, content: json.dumps(content, ensure_asciiFalse) } headers {Authorization: fBearer {get_feishu_token()}} resp requests.post(https://open.feishu.cn/open-apis/im/v1/messages?receive_id_typechat_id, jsonbody, headersheaders, timeout10) return resp.json()这里有两个易错点一是content字段必须是“字符串化”的JSON不是对象二是receive_id_type参数要对应你传入的ID类型。如果你传的是chat_id参数就是receive_id_typechat_id。如果你拿到的只是群的分享链接需要先调用获取群信息接口把群链接转成chat_id。卡片字段不同版本有细微差异我上面这种写法在2025年初是能用的如果你使用的SDK版本较老有可能需要把href改成url。4. 联调阶段踩过的三个深坑从回调验签到摄像头权限误判4.1 事件订阅URL校验一直失败的问题飞书配置webhook回调地址时会先发一个url_verification请求来校验你的服务是否可用。很多人第一次配都会遇到“回调地址验证失败”我当时反复检查了签名、加解密、网络最后才发现问题出在加密模式的处理顺序上。正确的处理顺序是飞书POST一个加密JSON过来例如{encrypt: ...}。后端用Encrypt Key解密得到一个明文JSON里面包含typeurl_verification和challenge字段。后端把明文challenge字段原样返回响应体是{challenge: abcdef}。飞书收到后才认为校验通过。有一种坑是有些代码里对响应体做了一层加密返回了{encrypt: ...}而飞书文档要求url_verification校验阶段返回明文challenge结果就会失败。建议调试时打日志把解密后的JSON结构完整打出来看。另外如果你的服务前面有Nginx或网关一定要确保POST body没有被吞或者被改写。遇到过网关把请求体读走传给下游时没有完整传递的情况。最简单的方式是先在本机用postman模拟飞书回调确认直接POST到后端可以返回challenge再去飞书后台触发校验。4.2 腾讯会议API返回权限不足和会议时长限制创建会议时报UnauthorizedOperation是最让我头疼的。排查思路要分层检查access_token是否过期。这个经常发生在本地测试完之后过几小时再调缓存里的token已经失效。检查应用是否审核通过。个人应用有些接口默认没有权限需要等待审批。检查X-TC-Key或企业标识是否传对。某些接口要求同时传应用级和企业级标识缺一个就会报没有权限。会议时长这个坑也很典型。腾讯会议API对结束时间有校验不能晚于某个上限也不能早于开始时间。我一开始在代码里把end_timestart_time7200秒看起来没问题但因为传的是秒级时间戳被系统识别成1970年的时间直接报InvalidParameter。改成毫秒级时间戳以后立即通了。还有一点如果你创建的是预约会议开始时间必须是未来时间不能是过去。联调时如果改了系统时间或时区配置错误也会报类似的参数错误。建议在代码里对时间先做一次UTC标准化同时打日志记录实际传入的毫秒值。4.3 “腾讯会议不能使用电脑自带摄像头吗”容易对外部反馈产生误判联调到一半有同事反馈从飞书卡片点击“加入会议”入会以后提示无法使用电脑自带摄像头。他问是不是对接程序把摄像头权限给限制了。这其实就是典型的“对接完成但入会失败”归因误区。腾讯会议网页版对浏览器摄像头权限非常敏感飞书应用内打开的网页如果被权限策略限制就会出现这种情况。排查步骤可以按这个顺序来先看是不是浏览器权限问题。Chrome设置里找到“隐私和安全-网站设置-摄像头”确认域名有摄像头访问权限。再看有没有其他程序占用摄像头比如本机装了虚拟摄像头、直播伴侣或者另一个腾讯会议窗口正在使用摄像头。如果从飞书内点链接默认用内置浏览器建议改为“在浏览器打开”或直接唤起腾讯会议客户端。客户端稳定性和设备兼容性比网页版好很多。腾讯会议客户端内如果仍然不行进入“设置-视频”手动切换摄像头设备。这个例子告诉我们一个经验对接项目的验收标准不能只看“接口返回200”要把“用户能顺利入会”和“摄像头/麦克风正常”纳入测试用例。最好在会议卡片里附加一个“入会异常自查”说明或者配置一个运维机器人收集反馈而不是让用户直接认为接口有问题。5. 顺着这条链路还能扩展什么多维表格台账、云文档授权与机器人自动报表5.1 用飞书多维表格记录每次会议创建记录对接跑通后我发现有个问题会议创建成功的信息都在聊天记录里时间一长就找不到了。于是我加了一步创建完会议后调用飞书多维表格API把会议主题、创建人、开始时间、会议号、入会链接写进一张“会议台账”表。多维表格API依赖两个关键值app_token和table_id。app_token在文档链接里就能看到table_id需要在多维表格的界面里通过“复制链接”或者调用“列出数据表”接口获取。写入记录用POST /open-apis/bitable/v1/apps/:app_token/tables/:table_id/recordsbody里fields字段按表格列名传值。这一步能很自然地把“飞书机器人发送表格”变成“飞书多维表格自动登记”。这里分享一个细节多维表格写入时日期字段建议用时间戳毫秒值不要传“2025-03-18 14:00”这种字符串很多时候写入后显示为空。别问我怎么知道的调了半小时最后看官方示例才反应过来。5.2 云文档授权凭证的获取思路说到飞书云文档很多人在第一次接入其他工具比如AI知识库时会卡在“授权凭证如何取得”。原理其实不复杂如果你的工具只是读取团队共享文档用企业自建应用的tenant_access_token就够了如果要读取某个用户个人空间里的云文档则需要引导用户完成OAuth授权拿到user_access_token。典型的OAuth授权获取流程在飞书开发者后台配置重定向URI。构造授权链接带上app_id、redirect_uri和scope参数用户点击后授权。飞书跳转回你的回调地址携带code。后端用app_id、app_secret、code换取user_access_token。用user_access_token调用云文档接口如获取文档内容、打开云文档等。之前在社区看到有人问dify首次使用飞书云文档的授权凭证怎么拿本质就是上面第2-4步。很多系统只是把“App ID和App Secret”填进去然后试图拿tenant_access_token去读个人文档权限不足是必然的。区别在于tenant_access_token代表应用身份user_access_token代表用户身份云文档的权限判断很多时候看的是用户身份。5.3 更高阶的延展会议纪要自动回写与机器人自动报表到这里飞书和腾讯会议的对接已经形成完整闭环指令创建会议、推送卡片、台账记录。再往下走可以从腾讯会议的Webhook事件会议开始、会议结束把状态自动回传飞书群。会议结束后将参会人、时长等数据写入多维表格再通过飞书机器人定时把“本周会议汇总表”以富文本消息或文件形式发到管理群。我在实际使用中发现一个更省事的方案多维表格本身支持“仪表盘”和“群机器人提醒”只要数据写进去了后续的统计和分析可以不写代码直接配置提醒规则。如果团队成员习惯用表格那么这一步的价值甚至比最初的会议创建功能更大。最后再分享一个小技巧飞书机器人发送表格时如果只是展示建议发一个“表格消息卡片”卡片里用table元素展示如果需要导出再调用导出接口生成文件不要用普通图片消息数据一多就糊了。