ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

飞书与腾讯会议API对接实战:从Webhook到自动化会议管理

飞书与腾讯会议API对接实战:从Webhook到自动化会议管理 每天早上打开飞书第一件事就是把前一天群里讨论的会议需求汇总起来然后切到腾讯会议客户端一个一个手动创建会议再把会议号、入会链接复制回飞书群。这个动作看起来只要几分钟但会议一多就很容易翻车链接贴错、时间记差、偏偏还有人追问“会议号是多少”。后来我干脆把飞书和腾讯会议通过API打通在飞书群里发一条指令就能创建腾讯会议机器人自动把会议卡片推给所有人会后纪要直接回传到飞书云文档。这篇文章就把这套对接实践的完整链路拆开讲清楚从选型、凭证、代码到避坑适合正在做办公自动化、企业应用集成或者想给团队搞一套“飞书内一键开会”工具的开发者参考。1. 先想清楚飞书和腾讯会议打通到底解决什么问题很多人在动手之前容易犯一个错看到“对接”两个字就急着去查API文档结果调了两天接口发现团队根本用不上。我自己的经验是动手之前先花半小时把场景捋清楚这半小时能省后面好几天的返工。1.1 每天多出的三分钟就是最典型的对接需求先说最普遍的场景。一个几十人的团队日常沟通几乎都在飞书群里完成但正式会议用的是腾讯会议。于是每次开会都要经历一套固定流程在群里讨论出时间 → 打开腾讯会议客户端 → 创建会议 → 复制会议号和链接 → 切回飞书 → 粘贴到群里 → 再手动所有人。单次操作三分钟听起来不多但每周十几次会议就是半小时而且每次复制粘贴都有出错风险。更麻烦的是很多员工记不住会议号开会当天还得翻聊天记录。用我团队的话说这不是技术问题是每天重复劳动的消耗。对接之后这套流程变成在飞书群里机器人发一条“下午3点创建需求评审会”机器人自动调腾讯会议API创建会议拿到会议号后通过飞书消息卡片推送到群里参会人点卡片里的链接就能入会。人工重复操作被彻底拿掉出错率也降下来了。1.2 三类高频需求通知同步、纪要回传、审批联动我把实际接触到的对接需求归纳成三类你可以对照自己团队的情况对号入座。需求类型典型场景对接内容通知同步飞书群里发起会议自动同步到腾讯会议并推送通知机器人推送会议卡片、会议链接、时间提醒纪要回传会后把腾讯会议的录制、纪要沉淀到飞书调用腾讯会议云录制/纪要接口写入飞书云文档审批联动销售/HR走飞书审批流审批通过后自动开会监听审批事件通过后创建腾讯会议并通知相关人第一类需求最容易落地也是本文的重点第二类涉及腾讯会议的录制文件获取部分能力需要企业版账号才有权限第三类属于事件驱动的高级玩法需要用到飞书的事件订阅和审批回调本质上是把“人工创建会议”变成“系统自动创建会议”。我建议第一次做对接的团队先盯住第一类需求跑通全链路把底层凭证、回调、发消息这些基础能力建好后面再往上加纪要回传和审批联动就顺手多了。2. 两条路线怎么选Webhook机器人还是自建应用全量API飞书和腾讯会议的对接技术路线上有两条主流选择。很多人一上来就问我“用哪种好”我通常反问一句你只需要单向推送还是需要双向交互答案不同选型完全不同。2.1 轻量路线自定义机器人Webhook十分钟跑通飞书群里可以直接添加“自定义机器人”创建之后会拿到一个Webhook地址。往这个地址POST一段JSON机器人就会把消息发到群里。curl -X POST https://open.feishu.cn/open-apis/bot/v2/hook/你的Webhook地址 \ -H Content-Type: application/json \ -d { msg_type: text, content: { text: 会议通知下午3点需求评审会\n会议号123456789\n入会链接https://meeting.tencent.com/dm/xxxx } }这是最简单粗暴的对接方式适合的场景是你只需要一个“会议通知推送机器人”不需要用户和机器人对话也不需要程序读取群里的消息。它的优点非常明显不需要在飞书开放平台创建应用、不需要审核、不需要配置事件订阅回调地址拿一个Webhook地址就能上线。我之前用这种方式帮一个销售团队做过会议提醒从写代码到部署完不到半小时。但缺点同样明显自定义机器人只能主动推送不能接收群消息不能读取群成员列表也不能上传文件。如果你希望用户在群里机器人创建会议那Webhook这条路直接堵死必须走自建应用。2.2 完整路线自建应用事件订阅腾讯会议API完整路线是在飞书开放平台创建一个“企业自建应用”给应用开启机器人能力然后通过API收发消息、上传文件、订阅群聊事件。同时在腾讯会议开放平台创建一个应用获得腾讯会议API的调用凭证。这套组合能做到的事情就多很多用户在群里机器人机器人通过事件订阅接收到消息内容后端解析用户指令调用腾讯会议API创建会议创建完成后调用飞书API发送消息卡片甚至直接把参会名单生成xlsx文件发到群里还可以把云文档读写能力打开将会议纪要自动写入飞书云文档。我目前生产环境里跑的就是这条路线。虽然前期配置步骤多一些但能力边界完全不一样后续扩展AI Agent、审批联动都依赖这套完整链路。2.3 选型对比什么时候选哪个一次说清对比维度自定义Webhook机器人自建应用API功能范围单向推送双向交互、文件、云文档、事件订阅开发成本极低半小时中等需要配置应用和回调是否需要审核不需要需要管理员审核应用发布能否发消息卡片不能可以能否发送表格/文件不能可以上传文件到群里能否接收群消息不能可以适合场景简单会议提醒完整会议生命周期管理我的建议很简单如果只是“把会议链接推送到飞书群”用Webhook就行别给自己加戏如果要做成“在飞书里管理腾讯会议”一步到位选自建应用别走弯路。3. 凭证和权限卡住九成新手的三大关口对接过程中最难的不是写代码而是搞定各种凭证和权限。我自己第一次做飞书对接的时候光是在开发者后台里找权限点就找了半天还因为漏发应用版本导致接口一直报权限错误。下面把三个关键凭证一一讲清楚。3.1 飞书自建应用app_id、app_secret与权限点在飞书开放平台后台创建一个企业自建应用之后你会拿到两个最关键的值App ID和App Secret。所有调用飞书开放API的请求都要先拿这两个值去换tenant_access_token应用身份令牌。换token的接口很简单POST方式调用import requests resp requests.post( https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal, json{ app_id: 你的App ID, app_secret: 你的App Secret } ) token resp.json()[tenant_access_token]拿到token之后调用消息、云文档等接口时在请求头带上Authorization: Bearer $TOKEN即可。这里有个新手必踩的坑你需要在“权限管理”里把用到的权限点全部开启并且重新发布应用版本让管理员审核通过权限才会真正生效。很多人改完权限直接去调用接口发现还是报权限错误就是漏了发布这一步。常用的权限点有这些可以对照勾选im:message:send_as_bot机器人发送消息im:chat:readonly读取群信息docx:document读写云文档drive:drive访问云盘文件contact:user.base:readonly读取用户基础信息3.2 腾讯会议开放平台的OAuth凭证从注册到拿到access_token腾讯会议这边需要在腾讯会议开放平台应用市场 → 开放平台注册为开发者创建一个企业应用。创建后你会拿到Client ID和Client Secret。腾讯会议API走的是OAuth 2.0授权流程简单说分三步把用户引导到授权页用户同意后拿到授权码code用code加Client ID/Secret换取access_token之后调用创建会议等接口时在请求头带上access_token。换token的请求大概是这样的resp requests.post( https://api.meeting.qq.com/v1/oauth/access_token, json{ client_id: 你的Client ID, client_secret: 你的Client Secret, code: 授权码, grant_type: authorization_code } ) access_token resp.json()[access_token]需要注意access_token的有效期大约两个小时过期后需要用refresh_token续期。所以对接代码里一定要做token缓存和自动刷新这个我在第5章展开讲。3.3 飞书云文档授权凭证Dify等AI工具首次接入的通用解法很多人在用Dify这类AI应用平台时第一次配置飞书云文档数据源就被“授权凭证”卡住了。其实这个凭证的本质和上面讲的OAuth流程一模一样。Dify要读取你的飞书云文档必须以某个飞书用户的身份去访问文档这就需要一个user_access_token用户身份令牌。获取方式还是在飞书开发者后台创建一个应用开启云文档相关权限然后走OAuth 2.0授权流程授权页面让用户点击“同意授权”拿到授权码后通过/open-apis/authen/v1/oidc/access_token接口换取user_access_token将这个token配置到Dify的“飞书云文档”数据源中即可。这里最容易出问题的地方是权限点不全。Dify需要至少打开以下权限点docx:document:readonly drive:drive:readonly drive:file:readonly如果配置后Dify提示“无权限访问文档”先检查两件事一是授权时勾选的权限范围里有没有包含目标文档二是这个文档是否把对应应用或用户加到了共享列表里。飞书的权限模型里光有token还不够文档本身必须有访问权限两者缺一不可。4. 动手落地会议创建、群通知、表格消息一条龙凭证搞定之后接下来就是真正动手写对接逻辑。我以Python为例把整条调用链拆开每一段都能直接抄作业。4.1 整体调用链一句话讲清服务端设计对接的服务端本质上是一个“中转调度器”它同时对接飞书和腾讯会议两个系统。我用的整体设计是这样用户从飞书群发消息 → 飞书事件订阅服务把消息内容POST到我的回调服务器 → 服务端解析消息里的指令 → 调用腾讯会议API创建会议 → 拿到会议号/入会链接 → 调用飞书API发消息卡片 → 会议结束后触发回调把纪要写入飞书云文档。实际部署时我建议把这三块拆成独立模块一个模块负责飞书消息的接收和解析一个模块负责腾讯会议API调用一个模块负责飞书消息/文件发送。这样任何一个环节出问题排查起来都很快。4.2 飞书机器人发通知从文本到富文本“表格”先看最简单的文本通知。拿到tenant_access_token后调用飞书消息接口import requests def send_feishu_message(chat_id, text): resp requests.post( https://open.feishu.cn/open-apis/im/v1/messages?receive_id_typechat_id, headers{ Authorization: Bearer access_token, Content-Type: application/json }, json{ receive_id: chat_id, msg_type: text, content: json.dumps({text: text}) } ) return resp.json()如果只是发一段文字msg_type用text就够了。但很多会议通知需要把“会议主题、时间、主持人、会议号、入会链接”逐行排列这时候用post富文本消息效果更好。飞书post消息的content是一个二维数组每个元素是一行可以用它模拟出表格的排版感{ msg_type: post, content: { post: { zh_cn: { title: 会议通知, content: [ [{tag: text, text: 会议主题需求评审会}], [{tag: text, text: 时间今天 15:00 - 16:00}], [{tag: text, text: 会议号123456789}], [{tag: a, text: 点击入会, href: https://meeting.tencent.com/dm/xxxx}] ] } } } }这是轻量场景下的最优解不需要任何额外权限自定义机器人Webhook都能直接发。4.3 自建应用发真实表格文件上传xlsx到群里如果会议参会人数多、信息量大纯文本排版就不好用了。比如你有一份几十人的参会名单或者一张周会议计划表最合适的做法是直接把Excel文件发到群里。自建应用可以通过飞书im/v1/files接口先把文件上传到飞书拿到file_key后发送到群聊# 第一步上传文件 with open(会议安排.xlsx, rb) as f: resp requests.post( https://open.feishu.cn/open-apis/im/v1/files, headers{Authorization: Bearer access_token}, data{file_type: xlsx, file_name: 会议安排.xlsx}, files{file: f} ) file_key resp.json()[data][file_key] # 第二步把文件发送到群 requests.post( https://open.feishu.cn/open-apis/im/v1/messages?receive_id_typechat_id, headers{ Authorization: Bearer access_token, Content-Type: application/json }, json{ receive_id: chat_id, msg_type: file, content: json.dumps({file_key: file_key}) } )在服务端生成Excel文件可以直接用pandas或者openpyxl比如把会议信息列表写入DataFrame再导出xlsx。实测下来im/v1/files接口对常见办公场景足够用文件大小上限30MB一般会议表格根本触不到这个限制。一个小提示上传文件前先检查文件后缀和file_type是否匹配传错了会报错。xlsx对应xlsxdocx对应docx图片对应jpg/png这种。4.4 调用腾讯会议API创建会议参数与回调处理创建会议是腾讯会议API的核心操作接口为POST /v1/meetings。关键参数包括会议主题、开始时间、结束时间、会议类型以及主持人配置。import requests resp requests.post( https://api.meeting.qq.com/v1/meetings, headers{ Authorization: Bearer access_token, Content-Type: application/json }, json{ topic: 需求评审会, start_time: 1704261600, # Unix 时间戳 end_time: 1704265200, meeting_type: 0, settings: { mute_enable: 1, # 入会静音 allow_unmute_self: 0 # 禁止自己解除静音 } } ) meeting resp.json()[meeting_info_list][0] meeting_id meeting[meeting_id] join_url meeting[join_url]创建成功后把meeting_id和join_url拼到飞书消息里就完成了整个闭环。这里我建议把创建会议和发送通知拆成两步先创建会议保存返回结果到数据库再发送飞书通知。如果腾讯会议创建成功了但飞书消息发送失败至少会议是真实存在的手动补发一条通知就行不会出现“群里说开会但会议没建成”的情况。5. 踩坑实录这些问题我都是在生产环境里遇到的接口文档看着都很简单真正跑起来才会遇到各种“意外”。这一章挑四个最有代表性的坑全部是我实际踩过的。5.1 事件订阅URL校验失败challenge和encrypt_key的坑飞书事件订阅要求你提供一个回调URL配置的时候飞书会往这个URL发送一条验证请求。如果你在应用里开启了加密Encrypt Key验证请求体是加密过的要先用AES解密再取出challenge字段原样返回。我当时第一次配置没开加密直接返回challenge就通过了。后来为了安全开启Encrypt Key结果验证一直失败排查了半天才发现是解密后字段结构对不上。处理逻辑大概是这样from flask import Flask, request, jsonify import json app Flask(__name__) app.route(/webhook/feishu, methods[GET, POST]) def feishu_callback(): body request.get_json() # URL校验 if body.get(type) url_verification: return jsonify({challenge: body[challenge]}) # 如果开启encrypt_key这里要先解密 # decrypt_data decrypt(body[encrypt]) # 再解析解密后的JSON业务逻辑处理 return jsonify({code: 0})需要注意返回challenge时响应头里的Content-Type必须正确有些框架默认返回text/html会导致校验失败。建议显式声明application/json。5.2 明明加了权限点接口还是报权限错误这个问题我遇到不下三次每次原因各不相同。最常见的是改了权限后没有发布新版本tenant_access_token仍然对应旧权限。其次是权限点选错比如飞书机器人发消息有两类权限im:message:send_as_bot机器人发消息和im:message:p2p_msg机器人接收单聊消息用法完全不一样选错了报的错也让人摸不着头脑。排查这类问题的标准流程是先看错误码飞书开放平台的错误码文档能定位到大部分问题然后用飞书开放平台的“API Explorer”实测它带真实token调一遍接口很容易暴露是权限问题还是参数问题最后确认当前应用是测试版还是已发布版本测试版只有应用开发者和管理员能看到如果要用到正式环境必须发布。5.3 token过期与并发刷新一个容易忽视的竞态问题飞书的tenant_access_token和腾讯会议的access_token都有有效期大约两小时。很多人的第一版代码是每次调用前都去换一次token结果发现接口响应慢还容易被限流。正确的做法是缓存token快过期时再刷新。但缓存也有坑如果服务是多实例部署的两个实例同时检测到token过期同时发起刷新请求后刷新成功的token会把先刷新成功的顶掉导致先拿到的那个实例后续请求全部鉴权失败。我的解决方案是给token刷新逻辑加一个分布式锁或者用一个简单的Redis缓存加过期时间。代码结构大概是这样cache_key feishu_tenant_access_token token redis.get(cache_key) if not token: with redis.lock(feishu_token_lock): token redis.get(cache_key) # 双重检查 if not token: token fetch_feishu_token() redis.set(cache_key, token, ex7000) # 比2小时短一点这个细节在生产环境非常重要否则每到token过期的时间点线上就会莫名其妙报一批401错误。5.4 一个无关但高频的误解摄像头问题是客户端的事在对接过程中我收到最多的提问反而不是API问题而是“腾讯会议不能使用电脑自带摄像头吗”“能不能通过接口强制开启参会人摄像头”。这里必须明确一个边界腾讯会议API能控制的是会议的创建、成员入会、录制等管理能力参会人本地的摄像头、麦克风权限属于客户端和设备系统管理接口层面根本没有这个能力。如果有人在腾讯会议里发现摄像头用不了排查方向应该是系统隐私设置Windows的“设置 → 隐私和安全性 → 相机”macOS的“系统设置 → 隐私与安全性 → 相机”确认已允许腾讯会议访问腾讯会议客户端设置检查视频设置里是否选择了正确的摄像头设备驱动和外设外接摄像头在设备管理器里是否正常识别驱动是否需要更新。对接开发时遇到这类问题可以直接把排查清单丢给提问的人比让他们翻来覆去找设置快得多。6. 扩展方向把对接交给AI Agent聊完基础对接再说说现在很火的方向把飞书和腾讯会议的对接能力交给AI Agent。网上常看到的“Dify如何对接飞书”“Codex CLI接入飞书”“AI大模型全栈知识库-飞书云文档”这些话题本质上都是在复用本文讲的这套凭证和API链路。AI Agent的典型玩法是在飞书群里机器人用自然语言说“明天下午3点和大客户开个需求评审会帮我创建腾讯会议并通知参会人”大模型解析出意图和时间调用已经封装好的腾讯会议创建函数再调用飞书发消息函数完成整个操作。飞书云文档则可以作为Agent的知识库让它能读取历史会议纪要回答“上次评审会结论是什么”这类问题。我在实际项目里的体会是API对接是地基AI Agent只是把“人调接口”变成了“大模型理解意图后再调接口”。底层凭证、权限、回调链路一点都不会变。所以如果你想做AI Agent方向别急着接大模型先把本文这套基础的飞书-腾讯会议对接跑通后面加AI能力就顺理成章了。对接本身不复杂复杂度全在“把边界划清楚”这件事上哪些能力由飞书提供哪些由腾讯会议提供哪些只能靠人工操作。把这几个边界想明白了工具链再变都不慌。
返回列表