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

18 KiB
Raw Blame History

N8N 内容转化流水线工作流设计v4 → v5 升级)

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


📋 核心需求更新v5

输出要求(重要!)

必须同时输出两个版本:

输出文件 路径 格式 用途
Markdown 源文件 content-output/{原文件名}.md 中文 Markdown Obsidian 留存、溯源
公众号 HTML content-output/{原文件名}.html 带样式的 HTML 直接复制到公众号编辑器

Obsidian 目录结构

~/Workspace/nexus/openclaw/
├── content-queue/                              # 原始英文文章(输入)
│   └── 2026-03-29-ai-solopreneur.md
│
└── content-output/                            # 成品(输出)
    ├── 2026-03-29-ai-solopreneur.md           # 翻译后 Markdown
    └── 2026-03-29-ai-solopreneur.html         # 公众号 HTML新增

📋 工作流概述

OpenClaw (发现文章)
       ↓ (保存文件到 n8n-files 目录)
       ↓ (触发 Webhook)

┌─────────────────────────────────────────────────────────────┐
│  N8N 工作流 (v5): content-translation-pipeline-v5          │
│                                                              │
│  [Webhook] → [Read File] → [Extract Text] → [AI Agent]     │
│       ↓                              ↑ (DeepSeek)            │
│  [Build Markdown] → [Write .md] → [Build HTML] → [Write .html] │
│       ↓                                                          │
│  [Send Telegram]                                               │
└─────────────────────────────────────────────────────────────┘

🔌 节点详细设计v5

节点 1Webhook Trigger

类型: Webhook 名称: Webhook Trigger Path /content-translation-v5(新建 path Method POST

接收数据格式:

{
  "note_name": "2026-03-29-ai-solopreneur.md",
  "source_path": "/Users/weishen/Workspace/nexus/openclaw/content-queue/2026-03-29-ai-solopreneur.md",
  "callback_url": "http://192.168.3.189:18789/webhook/yunce"
}

节点 2Read Obsidian Note

类型: Read Binary File 名称: Read Obsidian Note

配置:

  • File Path: =/home/node/.n8n-files/{{ $json.body.note_name }}

节点 3Extract from File

类型: Extract from File 名称: Extract from File Operation text

输出:

{
  "original_content": "...",
  "note_name": "2026-03-29-ai-solopreneur.md",
  "source_path": "/Users/weishen/Workspace/nexus/openclaw/content-queue/..."
}

节点 4AI Agent翻译+改写)

类型: LangChain Agent 名称: AI Agent Version 3.1 Model DeepSeek Chat Model

Prompt 模板:

你是一个专业的中文内容编辑,擅长将英文文章转化为适合中国读者的高质量内容。

## 你的任务

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

## 内容要求

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

## 文章主题方向(供校准时参考)
- AI Agent 落地实践与工具推荐
- AI 赋能商业的最佳实践
- AI 时代的网络安全与运维

## 输出格式(严格按此 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 }}

节点 5Build Markdown新增

类型: Code 名称: Build Markdown

功能: 将 AI 输出组装成 Markdown 文件

const aiResult = $input.first().json.message;
const data = typeof aiResult === 'string' ? JSON.parse(aiResult) : aiResult;

const noteName = $('Webhook Trigger').first().json.body.note_name;
// 去掉 .md 后缀,输出到 content-output
const outputName = noteName.replace('.md', '.md');
const outputPath = '/Users/weishen/Workspace/nexus/openclaw/content-output/' + outputName;

const markdown = `# ${data.wechat_title}

${data.wechat_content}

---

## X/Twitter 文案

${data.twitter_copy}

---

## 视频信息

**标题:** ${data.video_title}

**口播脚本:**

${data.video_script}

---

*封面图关键词:${data.cover_keywords?.join(', ')}*
`;

return {
  json: {
    output_path: outputPath,
    output_content: markdown,
    source_path: $('Webhook Trigger').first().json.body.source_path
  }
};

节点 6Write .md File新增

类型: Write Binary File / ReadWriteFile 名称: Write Markdown Note

配置:

  • Operation: write
  • File Path: =/home/node/.n8n-files/{{ $json.body.output_name }}_output.md
  • Content: ={{ $json.output_content }}

注意: 输出到 n8n-files/ 目录,由 OpenClaw 负责复制回 Obsidian。


节点 7Build HTML新增核心

类型: Code 名称: Build WeChat HTML

功能: 将 Markdown 转为带样式的公众号 HTML

const aiResult = $input.first().json.message;
const data = typeof aiResult === 'string' ? JSON.parse(aiResult) : aiResult;

const outputName = $('Webhook Trigger').first().json.body.output_name;
const htmlPath = '/home/node/.n8n-files/' + outputName + '_output.html';

// 公众号 HTML 模板
const html = `<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <style>
    body {
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif;
      font-size: 16px;
      line-height: 1.8;
      color: #333;
      max-width: 100%;
      padding: 20px;
    }
    h1 {
      font-size: 24px;
      text-align: center;
      color: #1a1a1a;
      margin-bottom: 30px;
      font-weight: 600;
    }
    h2 {
      font-size: 20px;
      color: #1a1a1a;
      margin-top: 30px;
      margin-bottom: 15px;
      font-weight: 600;
      border-left: 4px solid #007aff;
      padding-left: 12px;
    }
    p {
      text-align: justify;
      margin-bottom: 16px;
      text-indent: 2em;
    }
    .twitter-copy {
      background: #f5f5f5;
      padding: 15px;
      border-radius: 8px;
      margin: 20px 0;
      font-size: 15px;
    }
    .video-info {
      background: #f0f7ff;
      padding: 15px;
      border-radius: 8px;
      margin: 20px 0;
    }
    .video-title {
      font-size: 18px;
      font-weight: 600;
      color: #007aff;
      margin-bottom: 10px;
    }
    .script {
      font-size: 14px;
      line-height: 1.6;
      color: #555;
    }
    .cover-keywords {
      color: #999;
      font-size: 12px;
      text-align: center;
      margin-top: 30px;
      padding-top: 20px;
      border-top: 1px solid #eee;
    }
  </style>
</head>
<body>

<h1>${data.wechat_title}</h1>

${data.wechat_content.split('\n').map(line => {
  if (line.startsWith('# ')) return `<h1 style="text-align:center;font-size:24px;margin:30px 0;">${line.slice(2)}</h1>`;
  if (line.startsWith('## ')) return `<h2>${line.slice(3)}</h2>`;
  if (line.startsWith('### ')) return `<h3 style="font-size:17px;color:#333;margin:20px 0 10px;">${line.slice(4)}</h3>`;
  if (line.trim() === '---') return '<hr style="border:none;border-top:1px solid #eee;margin:30px 0;">';
  if (line.startsWith('- ') || line.startsWith('* ')) return `<li style="margin:8px 0;">${line.slice(2)}</li>`;
  if (line.trim() === '') return '';
  return `<p>${line}</p>`;
}).join('\n')}

<div class="twitter-copy">
  <strong>📱 X/Twitter 文案:</strong><br>
  ${data.twitter_copy.replace(/\n/g, '<br>')}
</div>

<div class="video-info">
  <div class="video-title">🎬 视频标题:${data.video_title}</div>
  <div class="script">
    <strong>口播脚本:</strong><br>
    ${data.video_script.replace(/\n/g, '<br>')}
  </div>
</div>

<div class="cover-keywords">
  封面图关键词:${data.cover_keywords?.join(' | ')}<br>
  原文路径:${$('Webhook Trigger').first().json.body.source_path}
</div>

</body>
</html>`;

return {
  json: {
    html_path: htmlPath,
    html_content: html
  }
};

节点 8Write .html File新增

类型: Write Binary File / ReadWriteFile 名称: Write WeChat HTML

配置:

  • Operation: write
  • File Path: =/home/node/.n8n-files/{{ $json.body.output_name }}_output.html
  • Content: ={{ $json.html_content }}

注意: 输出到 n8n-files/ 目录,由 OpenClaw 负责复制回 Obsidian。


节点 9Send Telegram Message

类型: Telegram 名称: Send Telegram Message

配置:

  • Chat ID: 5038825565
  • Text:
✅ 文章转换完成!

📝 标题:{{ $json.wechat_title }}
📁 Markdown/home/node/.n8n-files/{{ $json.body.output_name }}_output.md
🌐 HTML/home/node/.n8n-files/{{ $json.body.output_name }}_output.html
🐦 Twitter 文案:{{ $json.twitter_copy }}
  • Credentials: Telegram XingJiang Bot

注意: Telegram 只通知完成OpenClaw 收到通知后负责将文件复制回 Obsidian。


🔗 完整节点连接图v5

┌─────────────────────────────────┐
│  Webhook Trigger                │
│  POST /content-translation-v5  │
└──────────────┬──────────────────┘
               │
               ▼
┌─────────────────────────────────┐
│  Read Obsidian Note             │
│  (Read Binary File)            │
└──────────────┬──────────────────┘
               │
               ▼
┌─────────────────────────────────┐
│  Extract from File              │
│  (text operation)               │
└──────────────┬──────────────────┘
               │
    ┌──────────┴──────────┐
    │                      │
    │              ┌───────┴────────┐
    │              │ DeepSeek       │
    │              │ Chat Model     │
    │              └───────┬────────┘
    │                      │
    ▼                      ▼
┌─────────────────────────────────┐
│  AI Agent (LangChain)           │
│  - system prompt               │
│  - original content            │
└──────────────┬──────────────────┘
               │
               ▼
┌─────────────────────────────────┐
│  Build Markdown (NEW)           │
│  组装中文 Markdown 文件         │
└──────────────┬──────────────────┘
               │
               ▼
┌─────────────────────────────────┐
│  Write Markdown Note (NEW)     │
│  → content-output/*.md         │
└──────────────┬──────────────────┘
               │
               ▼
┌─────────────────────────────────┐
│  Build WeChat HTML (NEW)        │
│  Markdown → 带样式 HTML         │
└──────────────┬──────────────────┘
               │
               ▼
┌─────────────────────────────────┐
│  Write WeChat HTML (NEW)        │
│  → content-output/*.html        │
└──────────────┬──────────────────┘
               │
               ▼
┌─────────────────────────────────┐
│  Send Telegram Message          │
│  文章转换完成通知               │
└─────────────────────────────────┘

🔄 调用方式OpenClaw 侧)

重要说明n8n 只能读写 /home/node/.n8n-files/ 目录,无法直接访问 Obsidian 目录。因此 OpenClaw 负责文件搬运n8n 专注处理。

OpenClaw 完整流程:

# =============================================
# 步骤 1OpenClaw 复制原文到 n8n-files 目录
# =============================================
# SSH 到 MacMini将源文件复制到 n8n 容器可访问的目录
scp /Users/weishen/Workspace/nexus/openclaw/content-queue/article-2026-03-29.md \
    macmini:/home/node/.n8n-files/article-2026-03-29.md

# =============================================
# 步骤 2OpenClaw 触发 n8n Webhook
# =============================================
curl -X POST "https://n8n.ishenwei.online/webhook/content-translation-v5" \
  -H "Content-Type: application/json" \
  -d '{
    "note_name": "article-2026-03-29.md",
    "source_path": "/Users/weishen/Workspace/nexus/openclaw/content-queue/article-2026-03-29.md",
    "output_name": "article-2026-03-29",
    "callback_url": "http://192.168.3.189:18789/webhook/yunce"
  }'

# =============================================
# 步骤 3n8n 流程执行中...
# =============================================
# n8n 读取 /home/node/.n8n-files/article-2026-03-29.md
# 处理(翻译、改写)
# 输出到 /home/node/.n8n-files/article-2026-03-29_output.md
# 输出到 /home/node/.n8n-files/article-2026-03-29_output.html
# 发送 Telegram 通知

# =============================================
# 步骤 4OpenClaw 复制输出文件回 Obsidian工作流完成后
# =============================================
# 复制 Markdown 成品
scp macmini:/home/node/.n8n-files/article-2026-03-29_output.md \
    /Users/weishen/Workspace/nexus/openclaw/content-output/article-2026-03-29.md

# 复制 HTML 成品
scp macmini:/home/node/.n8n-files/article-2026-03-29_output.html \
    /Users/weishen/Workspace/nexus/openclaw/content-output/article-2026-03-29.html

# =============================================
# 步骤 5清理 n8n-files 临时文件(可选)
# =============================================
ssh macmini "rm /home/node/.n8n-files/article-2026-03-29.md \
                  /home/node/.n8n-files/article-2026-03-29_output.md \
                  /home/node/.n8n-files/article-2026-03-29_output.html"

简化版 OpenClaw 代码流程:

import subprocess

note_name = "article-2026-03-29.md"
source_path = "/Users/weishen/Workspace/nexus/openclaw/content-queue/" + note_name
output_name = note_name.replace('.md', '')
n8n_files = "/home/node/.n8n-files"

# 1. 复制原文到 n8n-files
subprocess.run(['scp', source_path, f'macmini:{n8n_files}/{note_name}'])

# 2. 触发 Webhook
subprocess.run(['curl', '-X', 'POST',
    'https://n8n.ishenwei.online/webhook/content-translation-v5',
    '-H', 'Content-Type: application/json',
    '-d', f'{{"note_name": "{note_name}", "output_name": "{output_name}", ...}}'
])

# 3. 等待 Telegram 通知(工作流完成)

# 4. 复制输出回 Obsidian
subprocess.run(['scp',
    f'macmini:{n8n_files}/{output_name}_output.md',
    f'/Users/weishen/Workspace/nexus/openclaw/content-output/{output_name}.md'])
subprocess.run(['scp',
    f'macmini:{n8n_files}/{output_name}_output.html',
    f'/Users/weishen/Workspace/nexus/openclaw/content-output/{output_name}.html'])

📁 最终 Obsidian 目录结构

~/Workspace/nexus/openclaw/
├── content-queue/                                      # 原始英文输入OpenClaw 放置)
│   └── article-2026-03-29.md
│
└── content-output/                                    # 成品OpenClaw 从 n8n-files/ 复制回来)
    ├── article-2026-03-29.md                          # 中文 Markdown ✅
    └── article-2026-03-29.html                        # 公众号 HTML ✅

文件来源说明:

  • n8n 工作流只读写 /home/node/.n8n-files/ 目录
  • OpenClaw 在工作流完成后负责将输出文件复制到 Obsidian 目录

验收标准

  1. 触发后自动完成整个流程,无需人工干预
  2. content-output/ 目录同时生成 .md.html 两个文件
  3. HTML 文件可直接复制粘贴到微信公众号编辑器,格式基本正确
  4. Telegram 收到完成通知(含标题和文件路径)
  5. 错误时 n8n 记录错误节点并停止流程

📝 备注

  • Markdown 源文件:保留中文原文,方便后续修改和溯源
  • HTML 文件:带内联样式,兼容微信公众号编辑器,复制后格式不走形
  • 文件路径:写入 Obsidian vault 的 content-output/ 子目录,需确保 n8n 容器有对应目录的写权限
  • API KeyDeepSeek API 通过 n8n credential 配置,无需在代码中硬编码