资讯详情

cal.diy 集成 Tandem 虚拟办公室:视频会议应用接入指南与源码解析

📅 2026/9/11 7:43:31 | 华诺云谱 👁 阅读
cal.diy 集成 Tandem 虚拟办公室:视频会议应用接入指南与源码解析
cal.diy 集成 Tandem 虚拟办公室视频会议应用接入指南与源码解析【免费下载链接】cal.diyScheduling infrastructure for absolutely everyone.项目地址: https://gitcode.com/GitHub_Trending/ca/cal.diy本指南以开源调度平台 cal.diy 中 Tandem 应用集成模块packages/app-store/tandemvideo为核心系统讲解如何为会议类型配置 Tandem 视频会议地点、完成 OAuth 授权与 Credential 存储并深入剖析其视频适配器与 Tandem REST API 的底层调用细节。读完本文你将掌握从应用密钥配置到会议创建/更新/删除的完整接入链路以及该模块在 cal.diy 应用商店体系中的注册方式。Tandem 集成是什么虚拟办公室中的即时协作Tandem 是一个全新的虚拟办公空间它让团队即使在线也能像身处实体办公室一样轻松连接。通过共办公房间co-working rooms、可用状态available statuses、实时视频通话live real-time video call与聊天chat等能力你可以一眼看到谁在办公室一键发起沟通与协作。它支持跨平台使用同时提供桌面端与移动端版本该描述同时被 DESCRIPTION.md 与应用元数据 _metadata.ts 引用。在 cal.diy 中Tandem 被封装为conferencing视频会议类别的应用集成其应用元数据声明如下packages/app-store/tandemvideo/_metadata.tstype/appIdtandem_video用于在 Credential 表中区分该集成slugtandem用于应用商店路由与应用密钥读取variant/category/categoriesconferencing表明它属于视频会议类应用isOAuth: true走标准 OAuth 授权流程appData.location注册integrations:tandem动态链接类型供会议类型作为地点选项使用。该模块在应用商店中的注册入口为 index.ts同时它会被应用商店的代码生成产物自动汇总见 apps.metadata.generated.ts、apps.server.generated.ts 与 video.adapters.generated.ts无需手写任何注册代码。前置条件配置应用密钥App KeysTandem 集成运行前必须完成三项应用密钥配置其校验逻辑在 lib/VideoApiAdapter.ts 与 api/add.ts 中均有体现配置键含义缺失时的表现client_idTandem OAuth 客户端 ID返回 400Tandem client_id missing.client_secretTandem OAuth 客户端密钥返回 400Tandem client_secret missing.base_urlTandem API 基础地址返回 400Tandem base_url missing.配置键的 Schema 约束定义在 zod.ts三个键均为非空字符串z.string().min(1)而appDataSchema为空对象即该应用本身无需额外数据字段。密钥通过getAppKeysFromSlug(tandem)从应用商店统一机制加载并以typeof appKeys.xxx string做类型守卫后使用。OAuth 授权流程从发起安装到保存凭据Tandem 集成包含两个 API 端点均挂在api/index.ts导出下路由前缀为/api/integrations/tandemvideo/。add构造授权跳转地址api/add.ts 处理 GET 请求流程如下通过prisma.user.findFirstOrThrow校验当前会话用户存在读取client_id与base_url应用密钥缺失则返回 400以WEBAPP_URL /api/integrations/tandemvideo/callback作为redirect_uri并做 URL 编码使用node:querystring的stringify构造client_id、redirect_uri参数返回{ url: ${baseUrl}/oauth/approval?${query} }引导用户跳转到 Tandem 授权页。callback换取令牌并落库api/callback.ts 处理授权回调校验code参数缺失时返回 401并用decodeOAuthState(req, tandem)解析 OAuth stateTandem 位于免 nonce 校验的应用白名单中见 _utils/oauth/decodeOAuthState.ts携带code、client_id、client_secret向${baseUrl}/api/v1/oauth/v2/token发起 POST换取访问令牌将响应中的expires_in转换为绝对过期时间戳expiry_date后删除原字段先清理该用户已有的tandem_video类型凭据prisma.credential.deleteMany再调用createOAuthAppCredential写入新凭据重定向回 state 中的returnTo地址或应用商店的已安装 Conferencing 应用页面getInstalledAppPath({ variant: conferencing, slug: tandem })。视频适配器Tandem REST API 的完整封装核心实现位于 lib/VideoApiAdapter.ts它实现 cal.diy 的VideoApiAdapter接口packages/types/VideoApiAdapter.d.ts并通过 video.adapters.generated.ts 被视频会议系统按 slug 动态加载。令牌管理与自动刷新tandemAuth封装令牌生命周期lib/VideoApiAdapter.ts有效性判定isTokenValid检查access_token存在且expiry_date Date.now()——注意这里的命名语义是已过期过期时携带refresh_token即 credential 中存储的 code向${baseUrl}/api/v1/oauth/v2/token重新换发新令牌按Date.now() expires_in * 1000计算expiry_date并立即通过prisma.credential.update持久化避免重启后令牌失效getToken()在令牌未过期时直接返回现有 token否则先刷新再返回。事件翻译与会议操作_translateEvent将 cal.diy 的CalendarEvent翻译为 Tandem 接口所需的 JSON 载荷lib/VideoApiAdapter.ts{ meeting: { title: 事件标题, starts_at: 开始时间Unix 秒, ends_at: 结束时间Unix 秒, description: 事件描述, conference_solution: tandem, type: 3 } }其中时间通过Date.parse(date) / 1000转为 Unix 秒级时间戳。适配器暴露三类核心操作createMeetingPOST${baseUrl}/api/v1/meetings以 Bearer Token 认证返回{ id, event_link }并翻译为{ type: tandem_video, id, url: event_link, password: }供会议参与者使用lib/VideoApiAdapter.tsupdateMeetingPUT${baseUrl}/api/v1/meetings/${bookingRef.meetingId}用updates键携带更新后的载荷用于改期/编辑场景lib/VideoApiAdapter.tsdeleteMeetingDELETE${baseUrl}/api/v1/meetings/${uid}用于取消会议时释放资源lib/VideoApiAdapter.ts。特别地getAvailability直接返回空数组lib/VideoApiAdapter.ts注释明确说明Tandem 不需要返回忙碌时段即 Tandem 会议不参与空闲度计算。在会议类型中使用 Tandem 作为地点安装并授权 Tandem 后即可在事件类型Event Type中将会议地点设置为Tandem Video。这得益于 _metadata.ts 中注册的动态链接类型appData: { location: { linkType: dynamic, type: integrations:tandem, label: Tandem Video, }, },linkType: dynamic表示会议链接由系统在预约创建时动态生成而非用户手动粘贴固定链接。一旦会议地点选择了该类型Booking 创建时会经由视频适配器的createMeeting创建 Tandem 会议并回填event_link会议改期/取消时则对应触发updateMeeting/deleteMeeting从而保证预约与虚拟办公室会议的全生命周期同步。依赖与模块边界Tandem 模块保持极简依赖package.json运行时依赖仅calcom/lib与calcom/prismaworkspace 内部包开发依赖calcom/types用于引用VideoApiAdapter、CredentialPayload、CalendarEvent等类型静态资源方面static/目录包含图标icon.svg与 6 张产品示意图tandem1–tandem6.jpg由 DESCRIPTION.md 的 frontmatter 引用。该模块不依赖任何第三方运行时库网络请求全部基于 Node 原生fetch令牌刷新、会议 CRUD 与配置校验均复用calcom/lib的handleErrorsJson、handleErrorsRaw、HttpError与getAppKeysFromSlug等通用工具保持了与其他视频会议应用一致的结构化开发方式。如需为 cal.diy 接入其他虚拟办公室/视频会议服务可直接以本模块为模板替换元数据、OAuth 端点与VideoApiAdapter中的 API 调用即可。【免费下载链接】cal.diyScheduling infrastructure for absolutely everyone.项目地址: https://gitcode.com/GitHub_Trending/ca/cal.diy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。