🔄 卡若AI 同步 2026-03-04 17:03 | 更新:卡木、运营中枢工作台 | 排除 >20MB: 11 个

This commit is contained in:
2026-03-04 17:03:12 +08:00
parent 21728da7c4
commit 7b53fa6bc2
8 changed files with 257 additions and 2 deletions

View File

@@ -0,0 +1,102 @@
{
"name": "一键下载抖音视频文案",
"nodes": [
{
"parameters": {},
"id": "a1b2c3d4-0000-4000-8000-000000000001",
"name": "手动输入抖音链接",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [240, 300],
"webhookId": ""
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "url",
"name": "url",
"value": "https://v.douyin.com/请替换为实际链接",
"type": "string"
},
{
"id": "download",
"name": "download",
"value": true,
"type": "boolean"
}
]
},
"options": {}
},
"id": "a1b2c3d4-0000-4000-8000-000000000002",
"name": "设置链接与是否下载",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [460, 300],
"onError": "continue"
},
{
"parameters": {
"method": "POST",
"url": "http://douyin-api:3099/parse",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"bodyContentType": "json",
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify({ url: $json.url, download: $json.download }) }}",
"options": {
"timeout": 60000
}
},
"id": "a1b2c3d4-0000-4000-8000-000000000003",
"name": "调用抖音解析API",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [680, 300],
"onError": "continue"
}
],
"connections": {
"手动输入抖音链接": {
"main": [
[
{
"node": "设置链接与是否下载",
"type": "main",
"index": 0
}
]
]
},
"设置链接与是否下载": {
"main": [
[
{
"node": "调用抖音解析API",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
},
"staticData": null,
"meta": {
"templateCredsSetupCompleted": true
},
"pinData": {},
"versionId": "1"
}

View File

@@ -0,0 +1,47 @@
# n8n 工作流:一键下载抖音视频文案
## 功能
- 在 n8n 中执行一次即可:输入抖音链接 → 自动解析文案并保存到本机,可选下载无水印视频。
- 依赖同编排内的 **抖音解析 API**`website-douyin-api`,端口 3099与 n8n 同属 website 分组。
## 一键完成(全自动)
### 1. 确保服务已启动(一条命令)
```bash
cd /Users/karuo/Documents/开发/2、私域银行/神射手 && docker compose up -d douyin-api n8n
```
### 2. 在 n8n 中导入工作流(唯一需手动的一步)
1. 打开 n8nhttp://localhost:5678
2. 左上角 **菜单****Workflows****Import from File**(或 **Import from URL**
3. 选择本目录下的 **`n8n_一键下载抖音视频文案.json`** 导入
(路径:`卡若AI/03_卡木/木叶_视频内容/抖音视频解析/n8n_一键下载抖音视频文案.json`
4. 保存工作流(可命名如「一键下载抖音视频文案」)
### 3. 使用方式
- **方式一(推荐)**:执行前点击节点「**设置链接与是否下载**」,将 `url` 改为要解析的抖音链接(如 `https://v.douyin.com/xxx``download``true` 则同时下载视频,为 `false` 则仅解析文案。然后点击 **Test workflow****Execute Workflow**
- **方式二**:用「**Execute Workflow**」时在输入数据中传入一条数据:`{"url": "https://v.douyin.com/xxx", "download": true}`
### 4. 结果
- 文案会保存到本机:`/Users/karuo/Documents/卡若Ai的文件夹/视频/{aweme_id}_文案.json``{aweme_id}_文案.txt`
-`download: true`,视频会保存到同目录下
- n8n 最后一个节点会输出 API 返回的 JSONaweme_id、title、desc、hashtags、caption_txt_path、video_path 等)
## 端口与编排
| 服务 | 容器名 | 端口 | 说明 |
|-------------|--------------------|-------|----------------|
| 抖音解析 API | website-douyin-api | 3099 | 供 n8n 调用 |
| n8n | website-n8n | 5678 | 工作流编辑与执行 |
两者均在 **神射手** 同一 docker-compose 下网络互通n8n 内请求地址为 `http://douyin-api:3099/parse`
## 故障排查
- **调用抖音解析API 报错**:确认 `docker ps``website-douyin-api` 在运行,且 n8n 与 douyin-api 在同一 compose 网络(均为 website
- **解析失败**:检查链接是否为抖音短链或完整视频链接;若被风控,可在本机用脚本 `douyin_parse.py` 或 MCP 浏览器兜底。

View File

@@ -0,0 +1,100 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
抖音解析 HTTP API供 n8n 等调用,一键解析抖音链接并返回文案(可选下载视频)。
POST /parse Body: {"url": "https://v.douyin.com/xxx", "download": true|false}
"""
from pathlib import Path
from flask import Flask, request, jsonify
# 同目录下的 douyin_parse
from douyin_parse import fetch_and_parse, download_video, DEFAULT_OUTPUT
app = Flask(__name__)
app.config["JSON_AS_ASCII"] = False
# 输出目录:容器内用 /data/douyin_output需挂载本机用 DEFAULT_OUTPUT
import os as _os
OUTPUT = Path(_os.environ.get("DOUYIN_OUTPUT_DIR", str(DEFAULT_OUTPUT)))
OUTPUT.mkdir(parents=True, exist_ok=True)
@app.route("/health", methods=["GET"])
def health():
return jsonify({"status": "ok"})
@app.route("/parse", methods=["POST", "GET"])
def parse():
"""
POST: JSON body {"url": "https://v.douyin.com/xxx", "download": false}
GET: ?url=https://v.douyin.com/xxx&download=false
"""
if request.method == "GET":
url = request.args.get("url", "").strip()
download = request.args.get("download", "false").lower() in ("1", "true", "yes")
else:
data = request.get_json(silent=True) or {}
url = (data.get("url") or "").strip()
download = data.get("download", False) in (True, "true", "1", "yes")
if not url:
return jsonify({"error": "缺少 url 参数", "usage": "POST /parse body: {\"url\": \"抖音链接\", \"download\": false}"}), 400
info, video_url = fetch_and_parse(url)
aweme_id = info.get("aweme_id")
if info.get("error"):
return jsonify({"error": info["error"], "info": info}), 500
if not aweme_id or aweme_id == "unknown":
return jsonify({"error": "无法解析视频,请检查链接", "info": info}), 400
# 保存文案 JSON 与 TXT
OUTPUT.mkdir(parents=True, exist_ok=True)
import json as _json
import re as _re
caption_json = OUTPUT / f"{aweme_id}_文案.json"
caption_txt = OUTPUT / f"{aweme_id}_文案.txt"
with open(caption_json, "w", encoding="utf-8") as f:
_json.dump(info, f, ensure_ascii=False, indent=2)
txt_lines = [
(info.get("title") or "").strip(),
"",
(info.get("desc") or "").strip(),
"",
"话题: " + " ".join(f"#{t}" for t in (info.get("hashtags") or [])),
"",
f"aweme_id: {aweme_id}",
f"链接: https://www.douyin.com/video/{aweme_id}",
]
with open(caption_txt, "w", encoding="utf-8") as f:
f.write("\n".join(txt_lines))
result = {
"aweme_id": aweme_id,
"title": info.get("title") or "",
"desc": info.get("desc") or "",
"hashtags": info.get("hashtags") or [],
"author": info.get("author") or "",
"caption_txt_path": str(caption_txt),
"caption_json_path": str(caption_json),
"video_url": video_url,
"video_downloaded": False,
"video_path": None,
}
if download and video_url:
safe_title = _re.sub(r"[^\w\s\u4e00-\u9fff]+", "_", (info.get("title") or aweme_id))[:50].strip("_")
out_file = OUTPUT / f"{aweme_id}_{safe_title or 'video'}.mp4"
ok, err = download_video(video_url, out_file)
result["video_downloaded"] = ok
result["video_path"] = str(out_file) if ok else None
if not ok:
result["video_error"] = err
return jsonify(result)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=3099, debug=False)

View File

@@ -0,0 +1,2 @@
flask>=2.0.0
requests>=2.28.0

View File

@@ -219,3 +219,4 @@
| 2026-03-03 14:29:21 | 🔄 卡若AI 同步 2026-03-03 14:29 | 更新:水桥平台对接、卡木、运营中枢工作台 | 排除 >20MB: 14 个 |
| 2026-03-03 17:28:23 | 🔄 卡若AI 同步 2026-03-03 17:28 | 更新Cursor规则、总索引与入口、运营中枢参考资料、运营中枢工作台 | 排除 >20MB: 11 个 |
| 2026-03-03 22:01:54 | 🔄 卡若AI 同步 2026-03-03 22:01 | 更新Cursor规则、金仓、水溪整理归档、卡木、总索引与入口、运营中枢参考资料、运营中枢工作台 | 排除 >20MB: 11 个 |
| 2026-03-04 11:48:54 | 🔄 卡若AI 同步 2026-03-04 11:48 | 更新:水桥平台对接、运营中枢参考资料、运营中枢工作台 | 排除 >20MB: 11 个 |

View File

@@ -20,6 +20,7 @@
| 神射手 | website-shensheshou | **3117** | `开发/2、私域银行/神射手/docker-compose.yml` | 与玩值电竞、OpenClaw、n8n 同文件启动 |
| 玩值电竞 Web | website-wanzhi-web | **3001** | 同上 | 同上 |
| n8n | website-n8n | **5678** | 同上 | 工作流自动化,镜像 docker.n8n.io/n8nio/n8n |
| 抖音解析 API | website-douyin-api | **3099** | 同上 | 供 n8n「一键下载抖音视频文案」工作流调用 |
| OpenClaw 网关 | website-openclaw-gateway | **18789** / **18790** | 同上 | 镜像 openclaw:local 需在 OpenClaw 项目内先 build配置用 `openclaw/.env` |
| 存客宝 Web | cunkebao-web | **3100** | `开发/2、私域银行/cunkebao_v3/docker-compose.yml` | 独立编排(不设 name: website同编排含触客宝+后端+MySQL+Redis |
| 触客宝 Web | touchkebao-web | **3101** | 同上 | 同上 |
@@ -31,9 +32,9 @@
## 统一启动方式
- **神射手 + 玩值电竞 + n8n + OpenClaw 网关**(主站):在神射手目录执行
- **神射手 + 玩值电竞 + n8n + 抖音解析 API + OpenClaw 网关**(主站):在神射手目录执行
`docker compose up -d``docker compose up -d --build`
各服务会出现在 Docker Desktop 的 **website** 分组下。n8n 访问 http://localhost:5678。OpenClaw 镜像需先在 `开发/8、小工具/Docker项目/OpenClaw/openclaw` 内执行 `docker compose build` 生成 `openclaw:local`
各服务会出现在 Docker Desktop 的 **website** 分组下。n8n 访问 http://localhost:5678;抖音解析 API 内网 http://douyin-api:3099/parse供 n8n 工作流调用)。OpenClaw 镜像需先在 `开发/8、小工具/Docker项目/OpenClaw/openclaw` 内执行 `docker compose build` 生成 `openclaw:local`
- **存客宝 + 触客宝**:在存客宝项目目录执行
`cd 开发/2、私域银行/cunkebao_v3 && docker compose up -d`(或 `--build` 拉取最新)
存客宝 http://localhost:3100 、触客宝 http://localhost:3101 ;同编排内含后端 8082、MySQL 3307、Redis 6380。

View File

@@ -222,3 +222,4 @@
| 2026-03-03 14:29:21 | 成功 | 成功 | 🔄 卡若AI 同步 2026-03-03 14:29 | 更新:水桥平台对接、卡木、运营中枢工作台 | 排除 >20MB: 14 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
| 2026-03-03 17:28:23 | 成功 | 成功 | 🔄 卡若AI 同步 2026-03-03 17:28 | 更新Cursor规则、总索引与入口、运营中枢参考资料、运营中枢工作台 | 排除 >20MB: 11 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
| 2026-03-03 22:01:54 | 成功 | 成功 | 🔄 卡若AI 同步 2026-03-03 22:01 | 更新Cursor规则、金仓、水溪整理归档、卡木、总索引与入口、运营中枢参考资料、运营中枢工作台 | 排除 >20MB: 11 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
| 2026-03-04 11:48:54 | 成功 | 成功 | 🔄 卡若AI 同步 2026-03-04 11:48 | 更新:水桥平台对接、运营中枢参考资料、运营中枢工作台 | 排除 >20MB: 11 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |

View File

@@ -47,6 +47,7 @@ description: 本机卡若Docker 与各类服务端口统一登记表。凡
| 3001 | Web | website-wanzhi-web | 万知 web玩值电竞 |
| 3117 | Web | website-shensheshou | 深深手 |
| 5678 | Web | website-n8n | n8n 工作流自动化 |
| 3099 | API | website-douyin-api | 抖音解析 API供 n8n 调用) |
| 8000 | 管理 | portainer | Portainer HTTP |
| 9443 | 管理 | portainer | Portainer HTTPS |
| 27017 | 数据库 | datacenter_mongodb | MongoDB唯一见唯一MongoDB约定 |