Files
nexus/openclaw/yunce/n8n-content-pipeline-workflow.md

503 lines
16 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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 成功后再清理,失败时保留现场