---
title: N8N 内容转化流水线工作流设计（v6 — 与实际部署对齐）
source:
author: shenwei
published:
created:
description:
tags: []
---

# N8N 内容转化流水线工作流设计（v6 — 与实际部署对齐）

> 用于：AI 英文文章 → 中文公众号/X/视频 内容转化
> 工作流 ID：`SjGKBtSnQ0u87mlK`
> 触发方式：OpenClaw 通过 Webhook 调用
> 管理平台：Mac mini 上的 n8n (`https://n8n.ishenwei.online`)

---

## ⚠️ 路径映射说明（重要！）

n8n 容器通过 Docker volume mount 访问宿主机文件系统：

| 容器内路径 | 宿主机路径（OpenClaw 用这个） |
|-----------|--------------------------|
| `/home/node/.n8n-files/` | `/Users/weishen/docker/n8n/n8n_data/files/` |

> **所有 `scp` / `ssh cp` / `ssh rm` 命令都必须使用宿主机路径。**
> n8n 节点内部配置的是容器路径，两者是同一个目录。

---

## 核心需求

### 输出要求

**单一输出：中文 Markdown 文件**

| 输出文件 | 宿主机路径 | 格式 |
|---------|-----------|------|
| **Markdown 成品** | `content-output/{output_name}_out.md` | 中文 Markdown，可在 Obsidian 中编辑后发布公众号 |

### Obsidian 目录结构

```
~/Workspace/nexus/openclaw/
├── content-queue/                              # 原始英文文章（输入）
│   └── 3 Essential Tools for OpenClaw.md
│
└── content-output/                            # 成品（输出）
    └── 3 Essential Tools for OpenClaw_out.md  # 中文 Markdown ✅
```

---

## 节点详细设计（v6 实际版本）

### 节点 1️⃣：Webhook Trigger

**类型：** Webhook
**名称：** `Webhook Trigger`
**Path：** `/content-translation-v6`
**Method：** POST

**接收数据格式（重要更新）：**

```json
{
  "note_name": "3 Essential Tools for OpenClaw.md",
  "output_name": "3 Essential Tools for OpenClaw"
}
```

> ⚠️ `source_path` 字段可选（v6 实际 webhook body 不依赖此字段）。

---

### 节点 2️⃣：Read Binary File

**类型：** Read Binary File
**名称：** `Read Obsidian Note`

**配置（容器内路径）：**
- File Path: `=/home/node/.n8n-files/{{ $json.body.note_name }}`

---

### 节点 3️⃣：Extract from File

**类型：** Extract from File
**名称：** `Extract from File`
**Operation：** `text`

---

### 节点 4️⃣：Structured Output Parser

**类型：** Structured Output Parser
**名称：** `Structured Output Parser`
**说明：** n8n 内置的结构化输出解析器，负责将 AI 输出的文本解析为 JSON 供后续节点使用。

**JSON Schema：**
```json
{
  "wechat_title": "中文标题",
  "wechat_excerpt": "公众号摘要（100字内）",
  "wechat_content": "完整公众号文章（Markdown格式）",
  "twitter_copy": "X/Twitter文案（280字内，带emoji）",
  "video_title": "视频标题",
  "video_script": "口播脚本（含时间戳和字幕）",
  "cover_keywords": ["关键词1", "关键词2", "关键词3"]
}
```

---

### 节点 5️⃣：AI Agent

**类型：** LangChain Agent
**名称：** `AI Agent`
**Version：** 3.1
**Model：** DeepSeek Chat Model
**Output Parser：** `Structured Output Parser`（已连接）

**Prompt 模板（与 v6 文档一致，但 JSON 字段名注意小写）：**
```
你是专业的中文内容编辑，擅长将英文文章转化为适合中国读者的高质量内容。

## 你的任务

将以下英文原文转化为：
1. 公众号风格的深度文章（2000-3000字）
2. X/Twitter 风格的短文案（280字内，带emoji钩子）
3. 视频口播脚本（3-5分钟，适合抖音/YouTube）

## 内容要求

- 语言：地道中文，无翻译腔
- 风格：专业、有干货、适合中国读者
- 调性：公众号大V风格，有观点有案例
- 商业化：可自然植入 AI Agent / 知识管理相关内容（软性，不硬广）

## 输出格式（严格按此 JSON 返回）

{
  "wechat_title": "中文标题",
  "wechat_excerpt": "公众号摘要（100字内）",
  "wechat_content": "完整公众号文章（Markdown格式）",
  "twitter_copy": "X/Twitter文案（280字内，带emoji）",
  "video_title": "视频标题",
  "video_script": "口播脚本（含时间戳和字幕）",
  "cover_keywords": ["关键词1", "关键词2", "关键词3"]
}

## 原文内容
{{ $json.data }}
```

> ⚠️ 注意：Build Markdown 节点访问 AI 结果用的是 `$input.first().json.output`，不是 `message`。

---

### 节点 6️⃣：Build Markdown

**类型：** Code
**名称：** `Build Markdown`

**功能：** 将 AI 输出的 JSON 组装成 Markdown 文件

```javascript
const aiResponse = $input.first().json.output;
const aiResult = typeof aiResponse === 'string' ? JSON.parse(aiResponse) : aiResponse;

const noteName = $('Webhook Trigger').first().json.body.note_name;
const outputName = $('Webhook Trigger').first().json.body.output_name;
const sourcePath = $('Webhook Trigger').first().json.body.source_path || '';

const markdown = '# ' + aiResult.wechat_title + '\n\n'
  + aiResult.wechat_excerpt + '\n\n'
  + aiResult.wechat_content + '\n\n'
  + '---\n\n'
  + '## X/Twitter 文案\n\n'
  + aiResult.twitter_copy + '\n\n'
  + '---\n\n'
  + '## 视频信息\n\n'
  + '**标题：** ' + aiResult.video_title + '\n\n'
  + '**口播脚本：\n\n'
  + aiResult.video_script + '\n\n'
  + '---\n\n'
  + '*封面图关键词：' + (aiResult.cover_keywords ? aiResult.cover_keywords.join(' | ') : '') + '*\n\n'
  + '*原文路径：' + sourcePath + '*/';

return {
  json: {
    output_name: outputName,
    markdown_content: markdown,
    ai_result: aiResult
  }
};
```

---

### 节点 7️⃣：Convert to File

**类型：** Convert to File
**名称：** `Convert to File`
**Operation：** `toText`
**Source Property：** `markdown_content`

> 将 Build Markdown 输出的文本（`markdown_content` 字段）转换为二进制文件，供 Write 节点写入。

---

### 节点 8️⃣：Write Markdown File

**类型：** Read/Write File
**名称：** `Write Markdown File`
**Operation：** `write`

**配置：**
- File Name: `=/home/node/.n8n-files/{{ $('Build Markdown').item.json.output_name }}_out.md`
- Data Property Name: `=data`

> ⚠️ 输出文件名格式：`{output_name}_out.md`（不是 `_output.md`！）

---

### 节点 9️⃣：Send Telegram Message

**类型：** Telegram
**名称：** `Send Telegram Message`

**配置：**
- Chat ID: `5038825565`
- Text:
```
=✅ 文章转换完成！

📝 标题：{{ $('Build Markdown').item.json.ai_result.wechat_title }}
```
- Parse Mode: `Markdown`

> ⚠️ v6 实际通知只含标题，不含文件路径。OpenClaw 根据约定的文件命名规则自行定位输出文件。

---

## 节点连接图

```
Webhook Trigger
       │
       ▼
Read Binary File
       │
       ▼
Extract from File
       │
       ▼
┌──────────────────────────────────────┐
│  Structured Output Parser  ←────────┤（AI Output Parser 连接）
│  AI Agent  ─────────────────────────→│（prompt + outputSchema）
│  DeepSeek Chat Model                 │
└──────────────────────────────────────┘
       │
       ▼
Build Markdown
       │
       ▼
Convert to File
       │
       ▼
Write Markdown File
       │
       ▼
Send Telegram Message
```

---

## 调用方式（OpenClaw 侧 — 实际测试命令）

### 宿主机 n8n-files 目录
```
/Users/weishen/docker/n8n/n8n_data/files/
```

### 完整流程（实际测试版）

```bash
# =============================================
# 步骤 1：复制原文到 n8n 容器可访问的目录
# =============================================
scp "/Users/weishen/Workspace/nexus/openclaw/content-queue/3 Essential Tools for OpenClaw.md" \
    "macmini:/Users/weishen/docker/n8n/n8n_data/files/3 Essential Tools for OpenClaw.md"

# =============================================
# 步骤 2：触发 Webhook
# =============================================
curl -X POST "https://n8n.ishenwei.online/webhook/content-translation-v6" \
  -H "Content-Type: application/json" \
  -d '{
    "note_name": "3 Essential Tools for OpenClaw.md",
    "output_name": "3 Essential Tools for OpenClaw"
  }' \
  -m 180 \
  -w "\nHTTP_CODE:%{http_code}\n"

# =============================================
# 步骤 3-4：复制输出文件回 Obsidian
# =============================================
# ⚠️ 注意：输出文件名是 {output_name}_out.md，不是 _output.md
ssh macmini "cp \"/Users/weishen/docker/n8n/n8n_data/files/3 Essential Tools for OpenClaw_out.md\" \
\"/Users/weishen/Workspace/nexus/openclaw/content-output/3 Essential Tools for OpenClaw_out.md\""

# =============================================
# 步骤 5：清理临时文件
# =============================================
ssh macmini "rm '/Users/weishen/docker/n8n/n8n_data/files/3 Essential Tools for OpenClaw.md'"
ssh macmini "rm '/Users/weishen/docker/n8n/n8n_data/files/3 Essential Tools for OpenClaw_out.md'"
```

---

## Python 自动化脚本模板（v6a — 勘误版）

```python
import subprocess
import sys

# ========== 配置区 ==========
N8N_BASE_URL = "https://n8n.ishenwei.online"
WEBHOOK_PATH = "content-translation-v6"
SOURCE_FILE = "/path/to/source/file.md"   # <-- 修改为实际源文件路径
N8N_FILES_HOST = "/Users/weishen/docker/n8n/n8n_data/files"
NOTE_NAME = "source-file.md"              # <-- 实际文件名
OUTPUT_NAME = "source-file"              # <-- output_name（无扩展名）
OUTPUT_DIR = "/Users/weishen/Workspace/nexus/openclaw/content-output"
# ============================

n8n_input = f"{N8N_FILES_HOST}/{NOTE_NAME}"
n8n_output = f"{N8N_FILES_HOST}/{OUTPUT_NAME}_out.md"  # <-- 命名规则：_out.md

print(f"[Step 1/5] 复制输入文件到 N8N 容器: {NOTE_NAME}")
result = subprocess.run(
    ['scp', SOURCE_FILE, f'macmini:{n8n_input}'],
    capture_output=True, text=True
)
if result.returncode != 0:
    print(f"X 文件复制失败: {result.stderr}")
    sys.exit(1)
print(f"V 已复制到 {n8n_input}")

print(f"[Step 2/5] 触发 N8N Webhook: {WEBHOOK_PATH}")
webhook_url = f"{N8N_BASE_URL}/webhook/{WEBHOOK_PATH}"
payload = ("{"
           "\"note_name\": \"" + NOTE_NAME + "\", "
           "\"output_name\": \"" + OUTPUT_NAME + "\""
           "}")
result = subprocess.run(
    ['curl', '-X', 'POST', webhook_url,
     '-H', 'Content-Type: application/json',
     '-d', payload,
     '-m', '180'],
    capture_output=True, text=True
)
print(f"Webhook 触发响应: {result.stdout[:200]}")

print("[Step 3/5] 等待 N8N 执行完成（Telegram 通知将发送到本会话）...")
print("请等待 Telegram 通知，收到后继续执行步骤 4。")
sys.exit(0)

# ---- 以下为步骤 4 和 5，需在收到 Telegram 通知后执行 ----

print(f"[Step 4/5] 复制输出文件回 Obsidian...")
src = f"macmini:{n8n_output}"
dst = f"{OUTPUT_DIR}/{OUTPUT_NAME}_out.md"
result = subprocess.run(['scp', src, dst], capture_output=True, text=True)
if result.returncode == 0:
    print(f"  V {OUTPUT_NAME}_out.md")
else:
    print(f"  X {result.stderr}")

print("[Step 5/5] 清理 N8N 容器临时文件...")
for f in [NOTE_NAME, f"{OUTPUT_NAME}_out.md"]:
    r = subprocess.run(['ssh', 'macmini', 'rm', f"{N8N_FILES_HOST}/{f}"],
                        capture_output=True, text=True)
    status = "V" if r.returncode == 0 else f"X ({r.stderr})"
    print(f"  {status} {f}")

print("🎉 工作流执行完毕！")
```

---

## 验收标准

1. Webhook 触发后 n8n 自动执行完整流程，无需人工干预
2. `content-output/` 目录生成 `{output_name}_out.md` 文件
3. Markdown 文件包含：标题 + 摘要 + 公众号正文 + Twitter 文案 + 视频脚本 + 封面关键词
4. Telegram 收到含标题的完成通知
5. 错误时 n8n 记录错误节点并停止流程

---

## 与 v6 文档的差异汇总（本文档为正确版本）

| 项目 | v6 文档（错） | v6a 实际版本（对） |
|------|-------------|-----------------|
| n8n-files 宿主机路径 | `/home/node/.n8n-files/` | `/Users/weishen/docker/n8n/n8n_data/files/` |
| 输出文件名 | `{output_name}_output.md` | `{output_name}_out.md` |
| 节点数 | 7 个 | 9 个（含 Convert to File + Structured Output Parser） |
| Build Markdown JSON 路径 | `$input.first().json.message` | `$input.first().json.output` |
| Telegram 通知内容 | 含文件路径 | 仅含标题 |
| webhook body | 包含 source_path | source_path 可选 |
| Write Markdown File FileName | `...output_name}_output.md` | `...output_name}_out.md` |

---

---

# 📖 附录：OpenClaw ↔ N8N 通用工作流调用规范（v1.1）

> 本规范旨在为 OpenClaw 与 N8N 之间的每次交互建立统一标准，使星辉（XingHui）或其他 Agent 能够通过标准化步骤执行任意 N8N 工作流。
>
> **适用范围**：任何由 OpenClaw 触发、N8N 执行的工作流
>
> **核心约束**：必须确认 n8n 容器的 volume mount 宿主机路径，所有 OpenClaw 侧文件操作使用宿主机路径。

---

## 路径映射规则

n8n Docker 部署的 volume mount 映射关系：
- 容器内 `/home/node/.n8n-files/` → 宿主机 `{docker-root}/n8n_data/files/`
- 当前部署：`/Users/weishen/docker/n8n/n8n_data/files/`

> 新增工作流时，先确认 docker-compose.yml 中的 volume 配置，用宿主机路径执行所有 `scp` / `ssh cp` / `ssh rm` 命令。

---

## 标准化执行步骤

### 步骤 ①：准备输入文件

**通用格式**：`scp <源路径> macmini:{N8N_FILES_HOST}/<文件名>`

### 步骤 ②：触发 Webhook

**通用格式**：
```bash
curl -X POST "<N8N_BASE_URL>/webhook/<webhook-path>" \
  -H "Content-Type: application/json" \
  -d '{"note_name": "<文件名>", "output_name": "<输出名>"}' \
  -m 180 -w "\nHTTP_CODE:%{http_code}\n"
```

### 步骤 ③：等待执行完成

**通知方式**：Telegram Bot（推荐）> Callback URL > 轮询 n8n API

### 步骤 ④：复制输出文件

**⚠️ 输出文件名规则因工作流而异，必须对照具体工作流确认（常见规则：`_out.md` / `_output.md` / `{name}_result.md`）**

**通用格式**：`ssh macmini "cp {N8N_FILES_HOST}/<输出文件名> <目标路径>"`

### 步骤 ⑤：清理临时文件

**通用格式**：`ssh macmini "rm {N8N_FILES_HOST}/<输入文件> {N8N_FILES_HOST}/<输出文件>"`

---

## 速查表

| 工作流 | Webhook Path | 输入文件规则 | 输出文件规则 | 通知方式 |
|--------|-------------|-------------|-------------|---------|
| 内容转化 v6 | `content-translation-v6` | `content-queue/*.md` | `content-output/*_out.md` | Telegram（仅标题） |
| （待补充） | | | | |

---

## 异常处理规范

| 异常情况 | 处理方式 |
|---------|---------|
| `scp` 文件复制失败 | 检查源文件是否存在、检查 docker volume 路径是否正确 |
| `curl` Webhook 超时 | 增加 `-m` 超时时间（如 180 秒），重试 1 次 |
| Telegram 未收到通知 | 登录 n8n 管理界面 → 查看工作流执行记录 |
| 输出文件复制失败 | 确认实际输出文件名（对照工作流的 Write 节点配置） |
| N8N 工作流报错 | 登录 n8n 管理界面 → 查看错误节点日志 |

---

## 关键约束汇总

1. **n8n volume 宿主机路径**：`/Users/weishen/docker/n8n/n8n_data/files/`
2. **文件传输**：OpenClaw 侧统一用宿主机路径（`scp` / `ssh cp` / `ssh rm`）
3. **输出文件名**：必须对照具体工作流的 Write 节点确认，不得假设
4. **Webhook 触发**：`curl -X POST`，`-m 180` 超时，响应含 `HTTP_CODE`
5. **通知等待**：必须等待 Telegram/callback 再复制输出文件
6. **清理时机**：步骤 4 成功后再清理，失败时保留现场
