飞书妙记 → Markdown

feishu-miaoji-md-sync

飞书妙记转写一键导出 Markdown 的 Chrome 扩展。

JavaScriptMIT★ 0更新于

GitHub 仓库

获取代码

git clone https://github.com/weitzu-com/feishu-miaoji-md-sync.git

点一下扩展图标,把当前飞书妙记页面的完整转写文字导出成本地 .md 文件。

📖 文档导航

第一性原理:为什么这么做

  1. 不走官方 API。实测 lark-cli minutes minutes get 在录音进行中返回 error 2091003: minute not ready——妙记 Open API 只有「处理就绪」后才能读,没有面向实时/增量的接口。要在网页上直接拿内容,唯一路径是读页面里正在渲染的转写 DOM。
  2. 完整采集 = 主动滚动,不是被动监听。转写列表是 rc-virtual-list(虚拟滚动),DOM 里只保留可视区附近的条目。所以「读当前 DOM」永远只拿到一小段。本插件会主动滚动容器、边滚边采,用 data-zone-id 做句子的稳定 ID 去重(飞书 ASR 会先出临时结果再修正,同 ID 覆盖而非追加),直到滚到底、再无新句子才停止。
  3. 下载而非写文件夹。早期版本用 File System Access API + 侧边栏,要求「侧边栏必须保持打开 + 手动选文件夹 + 权限失效后重新授权」。改成 chrome.downloads 后零权限舞、零常驻,点一下即落盘到 Downloads 目录。

架构

popup(一键按钮)
  └─ tabs.sendMessage EXPORT_REQUEST ──> content/content.js(接线层)
                                            │  调 content/core.js(纯逻辑层:滚动采集 → 生成 Markdown)
                                            └─ runtime.sendMessage EXPORT_DOWNLOAD ──> background.js
                                                                                          └─ Blob → chrome.downloads

核心算法(滚动采集/去重/排序/生成 Markdown)已拆到 content/core.js,不含任何 chrome.* 调用,可用 node test/core.test.js 零依赖单测验证(模拟虚拟滚动 DOM,20 用例)。

关键设计:下载由内容脚本直接触发,popup 只负责「按下按钮 + 展示结果」。这样即使 popup 中途失焦关闭,导出也不会中断。

失败自诊断

选择器依赖飞书未公开的内部 class,改版就可能失效。抓不到内容时,插件不会只报一句「未检测到转写内容」,而是自动 dump 出页面真实结构(有多少 [data-zone-id]、[time-content]、[user-name-content],以及 .transcript-content 里实际存在的 class / attribute 名列表),popup 上会出现「复制诊断信息」按钮。把这段 JSON 发我,就能据实修选择器,而不是盲猜。诊断信息只收集结构与计数,不采集转写正文,避免敏感内容外泄。

安装(开发者模式加载未打包扩展)

  1. Chrome 打开 chrome://extensions,右上角打开「开发者模式」。
  2. 点「加载已解压的扩展程序」,选择本目录:01_AI工具开发/feishu-miaoji-md-sync/。
  3. 打开一个飞书妙记页面(https://*.feishu.cn/minutes/xxx),点工具栏里的插件图标,再点「一键导出 Markdown」。
  4. .md 文件会自动下载到浏览器默认下载目录,命名 {妙记标题}_{YYYY-MM-DD}.md。

想让下载时弹「另存为」对话框自己选位置?把 background.js 里 saveAs: false 改成 saveAs: true 即可。

导出格式

# 会议标题

> 来源:https://xxx.feishu.cn/minutes/xxx
> 导出时间:2026-09-18 14:30:00 · 共 123 句

---

**[00:12] 张三**

这是转写内容……

**[00:35] 李四**

……

已知限制(如实告知)

  1. 选择器只在「已完成录制的回放页」上验证过(基于真实页面拿到的 DOM 结构)。飞书在「录音进行中」的页面理论上复用同一套转写列表组件,但未对真实进行中的录音验证过;若抓不到内容,多半是 class 名有细微差异,把当时的 DOM 结构发我,改选择器即可。
  2. 依赖飞书未公开的内部 class(.transcript-paragraph-item、.rc-virtual-list-holder、[data-zone-id] 等),飞书改版可能失效——这是「抓 DOM」方案天生的脆弱点。
  3. 只处理单说话人段落级文字,不含更细粒度的时间轴、不含插入的图片/截图等富媒体。
  4. 未发布到 Chrome Web Store,仅支持「加载已解压的扩展程序」方式安装。

下一步可选优化

  • 导出后,用 lark-cli minutes +detail --transcript 拉官方终稿,跟 DOM 抓取的版本做一次 diff 校对,弥补可能漏字的问题。
  • 支持多场会议同时导出、按子目录整理。
  • 若想恢复「边录边写」的实时同步能力,可把侧边栏 + File System Access 方案作为第二入口加回来。

以上内容自动同步自 github.com/weitzu-com/feishu-miaoji-md-sync的 README。