> ## Content Index
> Fetch the complete content index at: https://qilinora.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# 一句话让n8n自动生成文案
- URL: https://qilinora.com/yi-ju-hua-rang-n8nzi-dong-sheng-cheng-wen-an/
- Published: 2026-08-28T00:00:30.000Z
- Updated: 2026-08-28T00:00:30.000Z
- Author: Liyaoming
- Tags: n8n, 部署, obsidian

有些人以为，持续写内容靠的是自律。

但真正写过一段时间的人都知道：最稀缺的不是“坐下来写”的时间，而是那一句突然冒出来、还没来得及被生活冲掉的念头。

它可能发生在出门路上、开完会的电梯里，也可能是在你准备睡觉时。你对着手机说了十秒钟：“为什么很多人学了很多工具，生活却还是更忙？”如果这句话只是躺进录音 App，它大概率会成为一条永远不会再点开的音频。

这篇教程要做的，是把那十秒钟接住。

我们会搭一条完整的 n8n 工作流：**音频进入 Webhook → Whisper 转成文字 → AI 还原并扩写 → 自动生成 Markdown 文件 → 上传到 InfiniCLOUD WebDAV → 在电脑和手机的 Obsidian 里继续编辑。**

最终，你不再得到一段录音，而是一份已经有标题、有结构、有下一步写作方向的笔记。

![完整链路：音频到 Obsidian](https://private-us-east-1.manuscdn.com/sessionFile/7k3lQBmOlTAiNIf8kP0XAw/sandbox/yCO09l3KHGXmbfNbSKz7JT-images_1787059005674_na1fn_L2hvbWUvdWJ1bnR1L3ZvaWNlX2RyYWZ0X3R1dG9yaWFsX3BhY2thZ2UvaW1hZ2VzLzAxX-WujOaVtOmTvui3r-S4jue0oOadkOWOu-WQkQ.png?Expires=1787232694&Signature=MEUCIDVMsXGajTERloT~Qtc6dsUtnsqlFEDSPsp2mHfxzYSIAiEAl6wz~bfbyycV9oRYVIy5qAtUOhad1JZuoblPOl~y1so_&Key-Pair-Id=K1K5N5YNBUUMMN)

> **先把结果说清楚：** 这不是一个“自动替你写文章”的偷懒工具。它更像一位永远在线的内容助理：你负责提供真实观察，它负责把观察整理成可继续思考、可继续创作的起点。

### 这套流程到底适合谁

如果你经常有灵感，但总觉得“等会儿再写”，它适合你。如果你开完会总留下一堆录音，却不想再花一小时回听，它适合你。如果你做内容、做咨询、做产品，想把一句用户观察快速长成文章大纲、视频选题或销售文案，它更适合你。

它最大的价值，不是省掉几分钟打字，而是把“灵感出现”和“灵感进入知识库”之间的距离，缩短到接近于零。

| 你现在的痛点          | 工作流替你做的事            | 最后留下什么           |
| --------------- | ------------------- | ---------------- |
| 灵感出现得快，消失得更快    | 用语音先抓住原话            | 可检索的原始记录         |
| 只有一个观点，不知道怎么展开  | AI 从观点中抽出矛盾、读者痛点和结构 | 文案大纲或文章初稿        |
| 会议录音没人整理        | 把口述总结转成结论、待办和风险     | 可执行的会议纪要         |
| 录音、聊天和笔记散落在不同地方 | 自动生成 .md 并写入 WebDAV | Obsidian 内的统一内容库 |

### 先纠正三个容易误解的地方

第一，这份工作流**不会自动监听你的 Mac 或手机麦克风**。它的入口是 Webhook，意思是任何能把音频文件通过 HTTP `POST` 发送过来的工具，都能触发它。你可以用 macOS 快捷指令、iPhone 快捷指令、Android 自动化工具，或者自己的录音前端。

第二，InfiniCLOUD 在本流程中是**日本的云存储服务**，不是邮箱服务。它支持 WebDAV，所以 n8n 能把 Markdown 文件写进去，Obsidian 再从同一份远端文件夹同步回来。[InfiniCLOUD 官方说明](https://infini-cloud.net/en/about.html?ref=qilinora.com)将它定位为支持多设备访问的云存储，并说明其支持 WebDAV 连接。

第三，AI 的作用不是替你凭空制造观点。它负责理解你已经说出的内容，按你指定的结构整理、扩写和命名。你的判断仍然是内容的核心。

### 开始前，你要准备什么

这篇教程按“自己能复刻”的思路写。先把材料准备好，后面才不会每做一个节点就卡住。

| 需要准备的东西              | 它在流程中的作用       | 小白怎么理解        |
| -------------------- | -------------- | ------------- |
| 一套可用的 n8n            | 运行整个工作流        | 流水线所在的工厂      |
| 一个能发送音频的入口           | 把录音交给 Webhook  | 把包裹送到工厂门口的快递员 |
| Whisper 或兼容的 ASR 服务  | 语音转文字          | 速记员           |
| 一个模型 API，例如 DeepSeek | 理解、总结、扩写       | 编辑与策划         |
| InfiniCLOUD 账户       | 保存 Markdown 文件 | 云端文件柜         |
| Obsidian 桌面端与手机端     | 阅读、继续编辑和沉淀知识   | 你的内容工作台       |
| WebDAV 同步方案          | 让电脑与手机都看到同一份笔记 | 文件搬运与同步通道     |

本文提供的 `voice_draft_flow_sanitized.json` 已移除了真实 Webhook ID、n8n 实例 ID、凭证 ID、WebDAV 地址和账户引用，并且默认**未激活**。你可以选择导入后修改，也可以跟着下面的步骤从零搭建。

> **安全底线：** 真实 API Key、WebDAV Apps Password、Webhook URL、n8n Credentials 和 Obsidian 插件 `data.json` 都不能放进公开文章、截图或分享包里。文章中的 `YOUR-...` 都只是占位符。

### 先看一遍真实节点：你要搭的是哪六步

这份流程有六个节点，其中五个构成主数据路径，DeepSeek／其他模型节点通过一条 AI 连接线为 LLM Chain 提供模型能力。

```
Webhook_Audio → ASR_Whisper → Basic LLM Chain → Create_MD_File → Upload_to_WebDAV
                                      ↑
                              DeepSeek Chat Model

```

主路径负责搬运和加工数据；模型连接负责让 AI Chain 有“大脑”可用。理解这个区别，后面接线时就不会把模型节点误接到普通 `main` 端口上。

![完整节点关系图](https://private-us-east-1.manuscdn.com/sessionFile/7k3lQBmOlTAiNIf8kP0XAw/sandbox/yCO09l3KHGXmbfNbSKz7JT-images_1787059005674_na1fn_L2hvbWUvdWJ1bnR1L3ZvaWNlX2RyYWZ0X3R1dG9yaWFsX3BhY2thZ2Uvdm9pY2VfZHJhZnRfZmxvd19kaWFncmFt.png?Expires=1787232694&Signature=MEUCIQCr8U3VlhNUW8W4PuP28tO2dVUcPVzhL3v-iu0QOBaLkAIgUlpMo8etsl9XRI9n7L5Kjrkf3f5D1uePjSGdFn1yQ58_&Key-Pair-Id=K1K5N5YNBUUMMN)

---

### 第 0 步：决定你的部署范围——本机、局域网还是公网

在创建第一个节点前，先决定谁需要向你的 n8n 发送音频。这个决定会影响 Webhook 地址该怎么写。

| 你的使用方式                      | 入口地址通常是什么样                  | 适合谁                   | 你要注意什么                        |
| --------------------------- | --------------------------- | --------------------- | ----------------------------- |
| 只在运行 n8n 的同一台电脑使用           | http://localhost:5678/...   | n8n 与录音脚本都在同一台电脑      | localhost 只代表“当前这台机器” ，手机访问不到 |
| 同一 Wi‑Fi 内，手机把音频发给家里／办公室服务器 | http://192.168.x.x:5678/... | NAS、小主机、局域网 Docker 部署 | 给服务器固定局域网 IP；不要把端口暴露到外网       |
| 手机在外面也要发音频到服务器              | https://你的域名/...            | 有反向代理和 HTTPS 的公网部署    | 必须考虑认证、防火墙和访问控制               |

这里的 `5678` 是 n8n 常见默认端口 ，不是每个人都固定如此。如果你使用 Nginx、Caddy、Cloudflare Tunnel 或其他反向代理，外部看到的往往是域名加 HTTPS，而不是端口号。**示例地址不能照抄，必须替换为你自己的服务地址。**

---

### 第 1 步：创建 Webhook——给语音开一扇门

Webhook 是整个流程的触发器。外部工具把一份音频文件递给它，后面的节点才开始工作。n8n 官方将 Webhook 定义为可以接收外部数据并启动工作流的触发节点。[查看 Webhook 官方文档](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.webhook/?ref=qilinora.com)

![Webhook：入口、测试链接与生产链接](https://private-us-east-1.manuscdn.com/sessionFile/7k3lQBmOlTAiNIf8kP0XAw/sandbox/yCO09l3KHGXmbfNbSKz7JT-images_1787059005674_na1fn_L2hvbWUvdWJ1bnR1L3ZvaWNlX2RyYWZ0X3R1dG9yaWFsX3BhY2thZ2UvaW1hZ2VzLzAyX1dlYmhvb2tf6K-t6Z-z5YWl5Y-j5LiO6ZO-5o6l.png?Expires=1787232694&Signature=MEQCICbfX5vd2oJ9mfiXsoJJ6GDb~gSNHNroUfVeWNsn7tUoAiBegTXjKNfLuJEfCVjfU67JXpstFpKSTw~IerIMSaEGbw__&Key-Pair-Id=K1K5N5YNBUUMMN)

### 1.1 在画布上添加节点

新建工作流后，点击 `+`，搜索 **Webhook**。把它拖到画布最左侧，并将节点命名为 `Webhook_Audio`。好习惯是从第一天就给节点起能看懂的名字；三个月后你回来看，`Webhook_Audio` 比 `Webhook` 更容易理解。

### 1.2 设置最关键的三个字段

| 字段                  | 本教程建议值           | 它是什么意思                     |
| ------------------- | ---------------- | -------------------------- |
| **HTTP Method**     | POST             | 你的快捷指令会把音频“提交”进来，而不是只读取网页  |
| **Path**            | mac-audio        | 这是地址最后一段名称；可以改，但后续发送端也要同步改 |
| **Binary Property** | data（若你的版本显示该选项） | 告诉 n8n：收到的音频文件在后续节点里叫 data |

在某些 n8n 版本中，使用 `multipart/form-data` 上传名为 `data` 的文件后，二进制字段会自动以 `data` 出现；在另一些版本中，你需要在 **Add Option** 中启用 **Binary Property** 并填写 `data`。不要靠猜。测试时打开执行详情，确认左侧输入数据里能看到 `$binary.data`，再继续做 ASR 节点。

### 1.3 Test URL 和 Production URL 到底有什么区别

这是第一次使用 n8n 最容易卡住的地方。

**Test URL** 是调试专用的临时地址。你需要在 Webhook 节点中点击 **Listen for test event**，或者执行工作流，它才会等待下一次请求。它的地址一般带有 `webhook-test`。你用它的目的是：确认手机／快捷指令有没有真的把音频送进来，以及音频字段是不是 `data`。

**Production URL** 才是日常长期使用的地址。工作流激活后，n8n 会注册生产 Webhook；你的快捷指令、手机录音入口或其他程序应使用这条地址。n8n 官方文档也明确区分：测试 URL 用于编辑器内观察数据，生产 URL 在工作流发布后注册，生产执行结果可以在 Executions 中查看。

| 你正在做什么          | 应该用哪条链接        | 常见错误                                |
| --------------- | -------------- | ----------------------------------- |
| 第一次测试音频有没有进 n8n | Test URL       | 忘了点“Listen for test event”，结果以为接口失效 |
| 以后每天用手机发送语音     | Production URL | 工作流没激活，却把生产链接写进快捷指令                 |
| 文章或教程里展示地址      | 占位符            | 把自己的真实公网 Webhook 贴到公开页面             |

### 1.4 如果你要从公网调用，先加一层门锁

公网 Webhook 不是不能用，但不要让地址裸奔。n8n 的 Webhook 支持 Basic Auth、Header Auth、JWT 等认证方式，也可以限制调用 IP。[官方文档](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.webhook/?ref=qilinora.com)列出了这些选项。

最小可行方案是：先用一个不公开的长路径，再为 Webhook 配置 Header Auth 或 Basic Auth，并让你的快捷指令带上对应认证信息。不要以为“别人猜不到地址”就是安全。

---

### 第 2 步：创建 ASR\_Whisper——把声音交给速记员

ASR 是 Automatic Speech Recognition 的缩写，意思是自动语音识别。这个节点不负责理解观点，它只负责把你说的话尽量写成文字。

![ASR Whisper：把 data 音频转换为 text](https://private-us-east-1.manuscdn.com/sessionFile/7k3lQBmOlTAiNIf8kP0XAw/sandbox/yCO09l3KHGXmbfNbSKz7JT-images_1787059005674_na1fn_L2hvbWUvdWJ1bnR1L3ZvaWNlX2RyYWZ0X3R1dG9yaWFsX3BhY2thZ2UvaW1hZ2VzLzAzX0FTUl9XaGlzcGVyX-ivremfs-i9rOaWh-Wtlw.png?Expires=1787232694&Signature=MEQCICoFgbnAPK-eDte9SjUPdRyDe5xNSET0rcTDtZYL4VpfAiASFmyUiOVNZ438gTf7Ko2k~~x9w4teryPbnp6MEAnklA__&Key-Pair-Id=K1K5N5YNBUUMMN)

### 2.1 添加 HTTP Request 节点

点击 Webhook 节点右侧的 `+`，添加 **HTTP Request**，命名为 `ASR_Whisper`。把 Webhook 的 `main` 输出拖到这个节点。

这里使用 HTTP Request，是因为你的 Whisper／ASR 服务通常提供一个 HTTP 接口。原工作流使用的接口路径是：

```
/v1/audio/transcriptions

```

把地址替换成你自己的 ASR 服务：

```
http://YOUR-ASR-SERVICE:8000/v1/audio/transcriptions

```

如果 n8n 和 Whisper 都用 Docker 部署在同一个 Docker 网络中 ，服务名可以成为内网地址的一部分；如果 Whisper 在宿主机或另一台机器，地址写法会不同。**重点不是复制 `whisper-api` 这个名字，而是确保 n8n 容器真的能访问你的 ASR 服务。**

## 2.2 参数怎么填

| 配置项              | 填写内容                                                               | 为什么这样填                    |
| ---------------- | ------------------------------------------------------------------ | ------------------------- |
| **Method**       | POST                                                               | 向转写服务提交一份音频文件             |
| **URL**          | http://YOUR-ASR-SERVICE:8000/v1/audio/transcriptions               | 替换为自己的服务地址                |
| **Send Body**    | 开启                                                                 | 需要发送音频和模型参数               |
| **Content Type** | Multipart Form-Data                                                | 这是上传文件最常见的表单格式            |
| 参数 1：file        | Parameter Type 选 **n8n Binary File** ，Input Data Field Name 填 data | 读取 Webhook 收到的音频二进制数据     |
| 参数 2：model       | whisper-1                                                          | 告诉服务使用哪个转写模型；以你的服务实际支持项为准 |
| 参数 3：language    | zh                                                                 | 明确告诉服务优先按中文识别             |

这里最容易写错的是 `file` 与 `data` 的关系。

`file` 是 Whisper 接口希望收到的表单参数名称；`data` 是 n8n 里保存音频的二进制字段名称。前者像快递单上的“收件栏”，后者像 n8n 仓库里“这个包裹放在哪个货架”的名字。两个名字不必相同，但这份工作流就是这样约定的：**把 n8n 的 `data` 文件，作为接口的 `file` 发送出去。**

## 2.3 如何确认语音识别成功

先在 Webhook 里开启监听，再从你的音频入口发送一段 5 到 10 秒的普通话。执行结束后，打开 `ASR_Whisper` 的输出，寻找类似下面的字段：

```json
{
  "text": "刚才突然想到，很多人的效率问题不是工具不够，而是没有一个能马上记录的入口。"
}

```

只要看到 `text`，这一步就成功了。

如果没有 `text`，请按顺序排查：Webhook 里是否真的有 `$binary.data`；HTTP Request 的 `file` 是否指向 `data`；ASR 地址是否能从 n8n 所在环境访问；上传的音频格式是否被你的转写服务支持。

---

### 第 3 步：创建 Basic LLM Chain——让 AI 按你的写作方法思考

语音转文字只是把声音变成字符。真正让一段口述从随手记变成可发布内容的，是这一层。

Basic LLM Chain 可以把上一节点的动态文字与固定提示词组合起来，再交给模型生成结果。n8n 的官方文档说明，这个节点可以通过 **Define below** 模式填写静态文字或表达式作为 Prompt。

![Basic LLM Chain：原话进入提示词，规则决定输出](https://private-us-east-1.manuscdn.com/sessionFile/7k3lQBmOlTAiNIf8kP0XAw/sandbox/yCO09l3KHGXmbfNbSKz7JT-images_1787059005674_na1fn_L2hvbWUvdWJ1bnR1L3ZvaWNlX2RyYWZ0X3R1dG9yaWFsX3BhY2thZ2UvaW1hZ2VzLzA0X0Jhc2ljX0xMTV9DaGFpbl_mj5DnpLror43phY3nva4.png?Expires=1787232694&Signature=MEYCIQD~kx-Vh9PlZHEhwwypyaM~W1lCAZXz~D-OSKalyhtBhwIhALbdv2djo2abPVSnWbWuLIQ3cfRoQZ7TSTvakNyd9W4y&Key-Pair-Id=K1K5N5YNBUUMMN)

## 3.1 添加并连接节点

在 `ASR_Whisper` 后添加 **Basic LLM Chain**，命名保持 `Basic LLM Chain` 即可。把 ASR 节点的主输出连接到它。

在 Basic LLM Chain 的设置里：

| 配置项                                | 这样填                | 作用             |
| ---------------------------------- | ------------------ | -------------- |
| **Prompt Type**                    | Define below       | 允许你自己定义输入格式    |
| **Text**                           | \={{ $json.text }} | 读取 ASR 节点输出的文字 |
| **Chat Messages / System Message** | 填入你的写作规则           | 规定输出的风格、结构与边界  |

`={{ $json.text }}` 不是魔法，它只是 n8n 的表达式，意思是：“拿到当前数据里的 `text` 字段。”如果 ASR 输出字段叫别的名字，这里也必须跟着改。

## 3.2 一份更适合内容灵感的提示词

不要只写“请帮我总结一下”。那会让模型根据自己的习惯随便发挥。你真正需要做的是，提前规定一份内容编辑流程。

下面是一份适合文案灵感的脱敏示例，可直接作为 System Message 的起点：

```markdown
你是一名内容策略编辑。请把用户的口语化灵感整理为可继续写作的 Markdown 初稿。

必须按以下结构输出：
# 一个有冲突感、但不过度夸张的标题

## 灵感原话
> 原样保留用户输入，不擅自补充事实。

## 这句话真正值得写的地方
用 2-3 段解释核心矛盾、读者痛点和反常识角度。

## 可展开的文章结构
1. 开场场景
2. 关键观点
3. 真实案例或生活类比
4. 可执行建议
5. 结尾行动号召

## 可延展的三个选题
- ...

要求：不使用 Emoji；段落不要过长；不确定的事实必须标注为待验证，不要编造案例。

```

这份提示词的意义在于：以后不管你说的是“一个产品观察”“一段生活感受”还是“一个用户问题”，输出都会自动进入同一套内容方法。

## 3.3 如果你想把它改成会议纪要

只需要替换 System Message，不用重搭整个工作流。例如：

```markdown
请把会议口述整理为 Markdown 纪要。

## 已确认的结论
## 待办事项
- 事项：
- 负责人：
- 截止时间：
## 尚未决策的问题
## 风险与待补充信息

如果原话没有负责人或时间，不要编造，明确写“待确认”。

```

这就是自建工作流比固定总结 App 更有价值的地方：你不需要适应软件的模板，而是让软件执行你的模板。

---

### 第 4 步：连接 DeepSeek——给 LLM Chain 接上大脑

原始工作流使用的是 OpenRouter Chat Model 和 Qwen 模型。你完全可以保留这条路线；但如果你想以较低成本处理大量短语音、灵感和会议总结，也可以在 n8n 中换用 **DeepSeek Chat Model** 节点。

![DeepSeek：用 AI Language Model 虚线连接到 Chain](https://private-us-east-1.manuscdn.com/sessionFile/7k3lQBmOlTAiNIf8kP0XAw/sandbox/yCO09l3KHGXmbfNbSKz7JT-images_1787059005674_na1fn_L2hvbWUvdWJ1bnR1L3ZvaWNlX2RyYWZ0X3R1dG9yaWFsX3BhY2thZ2UvaW1hZ2VzLzA1X0RlZXBTZWVrX-aooeWei-i_nuaOpQ.png?Expires=1787232694&Signature=MEUCIGNRSHdtvwzWLBjpxf~igV1ubCqs74InUZibLj1jIDq3AiEAg54VUJvZxe8uC6fPU-0a0U7msVIpLJygA34OrfS-b7U_&Key-Pair-Id=K1K5N5YNBUUMMN)

### 4.1 添加 DeepSeek Chat Model 节点

点击 `+`，搜索 **DeepSeek Chat Model**。它属于模型子节点，和普通 HTTP 节点不同，不是放在主数据线里接前后关系。

创建凭证时，输入你自己的 DeepSeek API Key。不要把 Key 写进提示词、Code 节点或 JSON 工作流文件。n8n 官方文档说明，DeepSeek 模型下拉框会动态读取你的账户可用模型；因此你在不同时间、不同账户里看到的选项可能不完全一样。[查看节点说明](https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.lmchatdeepseek?ref=qilinora.com)

### 4.2 怎么连接才是对的

把 DeepSeek Chat Model 的输出，拖到 Basic LLM Chain 的 **AI Language Model** 输入口。它会显示为一条 AI 模型连接线，而不是普通的 `main` 主数据线。

如果你把模型节点接到主线，Basic LLM Chain 仍然没有真正的模型可调用；这也是初学者最常见的接线错误之一。

### 4.3 模型与参数怎么选

| 你的任务          | 选择原则               | 建议的初始参数                        |
| ------------- | ------------------ | ------------------------------ |
| 每天高频灵感、简单会议纪要 | 优先选择账户中可用的快速、低成本模型 | Temperature 0.4–0.6            |
| 长文案结构、复杂洞察    | 选择能力更强的模型          | Temperature 0.5–0.7，并提高最大输出长度  |
| 提取固定字段，例如待办清单 | 优先稳定性，而非文采         | Temperature 0.2–0.4，必要时要求 JSON |

DeepSeek 官方 API 文档会列出当前可用模型与调用方式；模型名称和价格会随时间变化，因此文章不建议把某一个价格写死。你可以在 [DeepSeek 官方文档](https://api-docs.deepseek.com/?ref=qilinora.com)中查看当前版本，再根据自己的使用频率决定。

---

### 第 5 步：创建 Create\_MD\_File——让 AI 输出变成一份真正的笔记文件

如果流程到 AI 输出就结束了，你只是把内容从聊天窗口搬到了 n8n 的执行记录。你还要复制、粘贴、命名、找目录。

这个 Code 节点就是为了消灭最后一公里。

![Create MD File：自动命名并输出 Binary data](https://private-us-east-1.manuscdn.com/sessionFile/7k3lQBmOlTAiNIf8kP0XAw/sandbox/yCO09l3KHGXmbfNbSKz7JT-images_1787059005674_na1fn_L2hvbWUvdWJ1bnR1L3ZvaWNlX2RyYWZ0X3R1dG9yaWFsX3BhY2thZ2UvaW1hZ2VzLzA2X0NyZWF0ZV9NRF9GaWxlX-iHquWKqOWRveWQjQ.png?Expires=1787232694&Signature=MEYCIQDTz0PI42KYf9EDE1cjep69iB7sqha5u4kt4Cld6hwKSwIhALpydeS~xGB3LMjcJcZDg6KjD7~uxYT4F5zTjK7LoYKl&Key-Pair-Id=K1K5N5YNBUUMMN)

### 5.1 添加 Code 节点

在 Basic LLM Chain 后添加 **Code** 节点，命名为 `Create_MD_File`。把 Basic LLM Chain 的主输出接过来。

它的工作分成四件事：读取模型输出、提取标题、生成安全文件名、把 Markdown 转成二进制文件。

下面是可放入 Code 节点：

```javascript
const markdownContent = $json.output || $json.text || $json.content || '';

let extractedTitle = '语音随记';
const lines = markdownContent.split('\n');
const titleLine = lines.find(line => line.trim().startsWith('# '))
  || lines.find(line => line.trim().length > 0);

if (titleLine) {
  extractedTitle = titleLine
    .replace(/^#\s*/, '')
    .replace(/[:：\-*\[\]]/g, '')
    .trim()
    .replace(/[\\/:*?"<>|\n\r]/g, '');
}

if (extractedTitle.length > 20) {
  extractedTitle = extractedTitle.substring(0, 20);
}
if (!extractedTitle) {
  extractedTitle = '语音随记';
}

const localTime = new Date(new Date().getTime() + 8 * 60 * 60 * 1000);
const dateStr = `${String(localTime.getUTCMonth() + 1).padStart(2, '0')}${String(localTime.getUTCDate()).padStart(2, '0')}`;
const fileName = `${dateStr}-${extractedTitle}.md`;

$input.item.binary = {
  data: {
    data: Buffer.from(markdownContent, 'utf8').toString('base64'),
    mimeType: 'text/markdown',
    fileName,
    fileExtension: 'md'
  }
};

$json.fileName = fileName;
return $input.item;

```

### 5.2 这段代码到底在干什么

| 代码动作            | 小白解释                    | 为什么不能省                |
| --------------- | ----------------------- | --------------------- |
| 读取 $json.output | 找到 AI 生成的正文             | 不同模型节点的字段可能不同，所以代码有兜底 |
| 找 \# 标题         | 用 Markdown 一级标题作为文件名来源  | 以后在 Obsidian 文件列表里更好找 |
| 清理非法字符          | 移除 / : \* ? 等不能用于文件名的字符 | 避免上传时失败               |
| 加上 MMDD- 日期     | 例如 0618-标题.md           | 让每天的灵感按时间自然排序         |
| 写入 $binary.data | 把文字打包成文件                | 下一步上传节点从这里拿文件         |

请特别记住最后一句：**文件的二进制字段名字叫 `data`。** 后面的 WebDAV 节点也必须选择 `data`。如果你改成别的名字，例如 `markdownFile`，最后一个节点也必须同步改，否则它会找不到要上传的文件。

---

### 第 6 步：配置 InfiniCLOUD WebDAV——把 Markdown 放进 Obsidian 能同步的文件柜

现在你已经有一份自动生成的 Markdown 文件。下一步是把它放到一个稳定、可在多设备访问的位置。

InfiniCLOUD 支持 WebDAV。WebDAV 可以理解成“让应用像操作远端文件夹一样读写云盘”的标准协议。InfiniCLOUD 官方说明，外部 WebDAV 客户端连接需要三项信息：**WebDAV Connection URL、InfiniCLOUD User ID、Apps Password**，并且需要在 My Page 中启用 Apps Connection。[查看官方说明](https://infini-cloud.net/en/use%5Fapp-link.html?ref=qilinora.com)

![InfiniCLOUD WebDAV：PUT 上传 Markdown 文件](https://private-us-east-1.manuscdn.com/sessionFile/7k3lQBmOlTAiNIf8kP0XAw/sandbox/yCO09l3KHGXmbfNbSKz7JT-images_1787059005674_na1fn_L2hvbWUvdWJ1bnR1L3ZvaWNlX2RyYWZ0X3R1dG9yaWFsX3BhY2thZ2UvaW1hZ2VzLzA3X0luZmluaUNMT1VEX1dlYkRBVl_kuIrkvKDphY3nva4.png?Expires=1787232694&Signature=MEUCIA~lqgbiRWEtvoJRzyN~7srkWa-aO7j4S89R5X6g0RGdAiEA4Jm3xoYr2kvByAHEAkQSDkYVDnXlKnF13VVUC52Ga8I_&Key-Pair-Id=K1K5N5YNBUUMMN)

### 6.1 先在 InfiniCLOUD 获取正确凭证

登录 InfiniCLOUD 后，进入 My Page，找到 **Apps Connection**，将它开启。不要使用你的普通登录密码，而是使用页面提供的 **Apps Password**。

| 信息                    | 从哪里拿               | 用在哪                       |
| --------------------- | ------------------ | ------------------------- |
| WebDAV Connection URL | Apps Connection 页面 | HTTP Request 的 URL 前半段    |
| User ID               | Apps Connection 页面 | n8n 的 HTTP Basic Auth 用户名 |
| Apps Password         | Apps Connection 页面 | n8n 的 HTTP Basic Auth 密码  |
| 远端文件夹名                | 你自己规定              | 建议与 Obsidian Vault 名对齐    |

InfiniCLOUD 提供的 WebDAV 地址通常类似 `https://你的账户.infini-cloud.net/dav/` ，但请以 My Page 显示的地址为准。不同账号的地址不同，文章中的地址只能作为结构示例。

## 6.2 添加 Upload\_to\_WebDAV 节点

在 `Create_MD_File` 后添加一个 **HTTP Request** 节点，命名为 `Upload_to_WebDAV`，并把 Code 节点的主输出连过来。

按下表设置：

| 配置项                       | 填写内容                                                                              | 释义                             |
| ------------------------- | --------------------------------------------------------------------------------- | ------------------------------ |
| **Method**                | PUT                                                                               | 以“写文件”的方式上传                    |
| **URL**                   | \=https://YOUR-INFINICLOUD-WEBDAV-ENDPOINT/dav/Obsidian\_n8n/{{ $json.fileName }} | 用你的 WebDAV 地址替换占位符；文件名由上一步动态生成 |
| **Authentication**        | Generic Credential Type → HTTP Basic Auth                                         | 使用新建的 InfiniCLOUD 凭证           |
| **Send Body**             | 开启                                                                                | 需要把文件内容发出去                     |
| **Content Type**          | Binary Data                                                                       | 上传的是文件 ，不是普通文字                 |
| **Input Data Field Name** | data                                                                              | 读取 Code 节点生成的 Markdown 文件      |

URL 前面的 `=` 表示它是 n8n 表达式。`{{ $json.fileName }}` 会在运行时替换为本次生成的文件名，例如：

```
https://你的地址/dav/Obsidian_n8n/0618-你不是没有灵感.md

```

### 6.3 第一次不要直接跑完整流程

先拿一个很短的测试 Markdown 文件测试 WebDAV 路径和凭证 。成功后，去 InfiniCLOUD 的文件浏览器确认 `Obsidian_n8n` 文件夹里是否出现了 `.md` 文件。

如果报 `401`，通常是 User ID 或 Apps Password 错误；如果报 `403`，常见是目录没有写入权限；如果报 `404`，先检查 `/dav/` 和文件夹路径有没有拼错。InfiniCLOUD 官方的 Android FolderSync 指南同样要求使用 WebDAV 地址、User ID、Apps Password 后先执行连接测试，再保存同步配置。[查看该指南](https://infini-cloud.net/en/use%5Ffoldersync.html?ref=qilinora.com)

---

### 第 7 步：让 Obsidian 在电脑和手机上同步这份新笔记

上传到网盘不等于已经出现在 Obsidian 里。你还需要让 Obsidian 的 Vault 与同一个 WebDAV 目录同步。

![桌面与手机通过 InfiniCLOUD 同步同一 Vault](https://private-us-east-1.manuscdn.com/sessionFile/7k3lQBmOlTAiNIf8kP0XAw/sandbox/yCO09l3KHGXmbfNbSKz7JT-images_1787059005674_na1fn_L2hvbWUvdWJ1bnR1L3ZvaWNlX2RyYWZ0X3R1dG9yaWFsX3BhY2thZ2UvaW1hZ2VzLzA4X09ic2lkaWFuX-ahjOmdouS4juaJi-acuuWQjOatpQ.png?Expires=1787232694&Signature=MEYCIQDHbsmUZDSCIh96mm8~a6L1SQFBfJkBKdZuUZmouCZKrgIhAM6bC-~WDjbnv3C0UcqboJadb95swEPcrUXDiHuDe8T6&Key-Pair-Id=K1K5N5YNBUUMMN)

### 7.1 最重要的路径原则：三处名字要对齐

这条工作流推荐使用一个独立 Vault，名字叫：

```
Obsidian_n8n

```

对应关系应该是：

```
n8n 上传目录：        /dav/Obsidian_n8n/
桌面 Obsidian Vault：  Obsidian_n8n
手机 Obsidian Vault：  Obsidian_n8n

```

为什么要这么做？因为 Remotely Save 在 WebDAV 模式下默认会把内容同步到以 Vault 名称命名的远端子文件夹。插件文档也建议，多设备同步时使用相同 Vault 名称。[Remotely Save 的说明](https://github.com/remotely-save/remotely-save?ref=qilinora.com)明确列出 WebDAV 与 InfiniCLOUD 支持，并说明桌面端和移动端都可以通过云服务同步。

最稳妥的验证方式不是猜路径，而是：先在桌面 Obsidian 新建一份 `测试同步.md`，手动同步一次，然后去 InfiniCLOUD 文件浏览器看它到底出现在哪个远端目录。让 n8n 最后一个节点上传到**同一层目录**，而不是另建一个相似但不同的文件夹。

### 7.2 电脑端怎么配置

在 Obsidian 桌面端中，进入 **Settings → Community plugins**，关闭 Restricted Mode 后安装 **Remotely Save**。它是第三方社区插件，不是 Obsidian 官方 Sync；使用前请先备份自己的 Vault。插件维护方也特别提醒：同步前务必备份，且插件配置文件中可能包含敏感数据，不能随意分享。

在 Remotely Save 设置中选择 **WebDAV**，然后填写：

| Remotely Save 字段 | 应填写什么                                          |
| ---------------- | ---------------------------------------------- |
| 服务类型             | WebDAV                                         |
| Server Address   | InfiniCLOUD My Page 中显示的 WebDAV Connection URL |
| Username         | InfiniCLOUD User ID                            |
| Password         | Apps Password，不是网页登录密码                         |
| 远端前缀／目录          | 与你在 n8n 中使用的 Vault 目录保持一致                      |

填好后，先点击插件的连接检查或手动同步。第一次同步时不要马上打开手机端，也不要让两个设备同时编辑同一份笔记。先确认电脑端往返同步都没问题。

### 7.3 手机端怎么配置

手机端同样可以使用 Obsidian 加 Remotely Save。插件维护方说明它支持 Obsidian Mobile，并可通过云服务在桌面与移动设备之间同步；但它并不等同于官方 Obsidian Sync。

推荐顺序如下：

1. 在手机 Obsidian 中新建一个空 Vault，名称也设为 `Obsidian_n8n`。
2. 在手机端允许 Community plugins，并安装 Remotely Save。
3. 选择 WebDAV，填写与电脑**完全相同**的 URL、User ID、Apps Password 与远端目录。
4. 先手动同步一次，确认手机端出现电脑上传的测试文件。
5. 再让 n8n 跑一段真实语音，检查新 `.md` 是否先出现在 InfiniCLOUD，随后出现在电脑和手机 Obsidian。

你也可以在 Android 上使用支持 WebDAV 的文件管理／同步工具直接浏览或同步 InfiniCLOUD 文件。InfiniCLOUD 官方 FolderSync 教程演示了 WebDAV 账户、远端目录、本地目录、单向／双向与计划同步的配置方式。但如果目标是“在 Obsidian 里继续编辑 Markdown”，优先让 Obsidian 的同步插件管理 Vault 会更直接。

> **重要边界：** Remotely Save 的自动同步只在 Obsidian 打开时才可能运行；不要期待手机在后台彻底关闭时仍不断同步。多设备同步也有冲突风险，刚开始时请坚持“一个设备编辑完并同步后，再换另一个设备”。

---

### 第 8 步：从录音入口发送一段测试语音

现在工作流已经搭好，但还差最后一个“发件人”——谁来把音频 POST 给 Webhook。

你可以用任何能发送 HTTP multipart 请求的工具。无论你使用 macOS 快捷指令、iOS 快捷指令还是 Android 自动化工具，目标都一样：

```
POST 到你的 Production Webhook URL
表单文件字段名称：data
文件内容：录音文件

```

推荐的测试顺序是：

1. 先用 Test URL，确认 Webhook 能收到 `$binary.data`。
2. 看 ASR 节点是否输出 `$json.text`。
3. 看 Basic LLM Chain 是否输出带 `# 标题` 的 Markdown。
4. 看 Code 节点是否生成 `$binary.data` 和 `$json.fileName`。
5. 看 WebDAV 是否上传成功。
6. 最后在 InfiniCLOUD、桌面 Obsidian 和手机 Obsidian 三处检查同一份 `.md`。

不要一开始就把所有问题混在一起。每一步都能看到中间结果，才是 n8n 最适合小白的调试方式。

---

### 常见问题：按节点产出来排查

| 你看到的现象               | 最可能的问题                                         | 先做什么                                  |
| -------------------- | ---------------------------------------------- | ------------------------------------- |
| Webhook 一直没反应        | 用错 Test／Production URL；测试时没开启监听；手机访问 localhost | 先在 n8n 内复制正确 URL，再判断设备是否在同一台机器或同一网络   |
| Webhook 有执行，但 ASR 报错 | 没收到 data；ASR 地址不可访问；表单参数不对                     | 查看 Webhook 的 $binary，确认字段；再用短音频测试 ASR |
| ASR 有文字，AI 不输出       | {{ $json.text }} 指错字段；模型未连接到 AI 端口；API Key 不可用 | 打开 ASR 输出确认字段名；检查模型虚线连接               |
| AI 输出没有标题            | 提示词没要求 \# 标题                                   | 在 System Message 中明确规定第一行是一级标题        |
| WebDAV 401／403／404   | Apps Password、权限、URL 或目录有误                     | 先用小文件做连接测试；确认是 Apps Password 而非登录密码   |
| 网盘有文件，Obsidian 没出现   | n8n 上传目录与 Vault 远端目录不一致                        | 先从桌面 Obsidian 手动同步一个测试文件，反查真实远端路径     |
| 手机与电脑内容打架            | 两端同时编辑，或者初次同步方向选错                              | 先备份；一次只在一个设备编辑；确认后再开启定时同步             |

---

### 这条工作流还可以扩展成什么

当你把“音频进入 → AI 整理 → Markdown 归档”这条链搭好后，它就不只是一套写文案工具，而是一个通用的个人信息入口。

### 1\. 灵感捕捉器

保留原本的内容文案提示词。适合走路时、开车前、洗澡后突然出现的观点。重点是先把原话留下来，再让 AI 帮你找可写的角度。

### 2\. 会议纪要器

把 System Message 改为“结论、待办、负责人、截止时间、待确认事项”。尤其适合会后用两分钟口述复盘，而不是指望以后回听一小时录音。

### 3\. 访谈与用户研究整理器

把输出改为“用户原话、显性需求、隐性动机、反复出现的词、待追问问题、产品机会”。你会得到一份可以参与产品决策的材料，而不是一段沉在录音文件夹里的访谈录音。

### 4\. 每日复盘与情绪日志

每天晚上说三分钟，AI 输出“今日事件、让我耗能的事、值得保留的发现、明日下一步”。长期积累后，你会得到比零散待办更有价值的个人观察档案。

### 5\. 多平台内容再加工

在 WebDAV 上传后再增加分支：让一份长文案大纲继续生成公众号文章、视频口播稿、X 帖子串、短视频标题和 Newsletter 摘要。记住，最好先全部生成到**草稿**，由你确认后再发布。

### 6\. 个人知识库索引

让 AI 每次额外输出标签、关键词、相关笔记建议和待验证问题。这样每一段语音不是只变成文章，还能成为以后可搜索、可链接、可重新组合的知识素材。

---

### 最后：你需要的不是一台更会写的 AI，而是一条不让观点丢失的路径

真正有价值的内容，往往不是坐在电脑前硬憋出来的。

它来自你刚看到一个现象时的反应，来自一次会后还没有冷却的判断，来自你对生活说出的那句“我好像明白了什么”。

以前，这些东西会死在录音里。

现在，你可以让它们自动成为一份 Markdown：先进入网盘，再进入 Obsidian，然后在你有空时，变成文章、视频、产品判断，或者只是一次更清醒的自我对话。

你负责开口。

剩下的，让自动化替你接住。