8
n8n 中文网amn8n.com

MetaAds创意洞察研究员v1.4

高级

这是一个Market Research, Multimodal AI领域的自动化工作流,包含 32 个节点。主要使用 If, Set, Code, Wait, SplitOut 等节点。 使用Google Vision和Video Intelligence API分析Meta广告创意

前置要求
  • 可能需要目标 API 的认证凭证
  • Google Sheets API 凭证
  • Facebook Graph API 凭证
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "id": "YoV79TLDcH5vXJBQ",
  "meta": {
    "instanceId": "d5e1aee00419f7d76c99b6815681c983a5e0b4d87bfcf461d2e125e2786ef532"
  },
  "name": "MetaAds 创意洞察研究员 by videointelligence v_1.4",
  "tags": [
    {
      "id": "8ZOxg8cY0fPL8g0s",
      "name": "ReadyToUse",
      "createdAt": "2025-07-10T04:08:19.089Z",
      "updatedAt": "2025-07-10T04:08:19.089Z"
    },
    {
      "id": "tITAFvUSOpVVIBvI",
      "name": "MetaAds",
      "createdAt": "2025-07-05T02:24:26.705Z",
      "updatedAt": "2025-07-05T02:24:26.705Z"
    },
    {
      "id": "3Kr9akgvGQXhCtQJ",
      "name": "ForPublishing",
      "createdAt": "2025-08-13T13:36:55.022Z",
      "updatedAt": "2025-08-13T13:36:55.022Z"
    }
  ],
  "nodes": [
    {
      "id": "2e978712-7f3c-41f9-98ef-5485108d6115",
      "name": "每天上午 9 点运行",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -3232,
        80
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 9
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "68355d2e-dca3-4fd8-822c-62f0448e4a92",
      "name": "获取活跃广告",
      "type": "n8n-nodes-base.facebookGraphApi",
      "position": [
        -2784,
        80
      ],
      "parameters": {
        "edge": "ads",
        "node": "={{ $json.campaign_id }}",
        "options": {
          "queryParameters": {
            "parameter": [
              {
                "name": "fields",
                "value": "=id,name,creative{id,object_type,thumbnail_url,image_url,object_story_spec{video_data{video_id,image_url}}}"
              }
            ]
          }
        },
        "graphApiVersion": "v22.0"
      },
      "credentials": {
        "facebookGraphApi": {
          "id": "jF7Lc9HyK76Jr9Xm",
          "name": "KH | Facebook Graph"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "854d454f-a888-4935-9f27-ea58802553c2",
      "name": "是视频吗?",
      "type": "n8n-nodes-base.if",
      "position": [
        -2336,
        80
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "4168e3d6-4171-460d-83b5-446736c04f32",
              "operator": {
                "type": "string",
                "operation": "exists",
                "singleValue": true
              },
              "leftValue": "={{ $json.data.creative.object_story_spec.video_data.video_id }}",
              "rightValue": "VIDEO"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "23fbf5c4-827a-41f4-8b0b-d2316022ea22",
      "name": "获取视频源 URL",
      "type": "n8n-nodes-base.facebookGraphApi",
      "position": [
        -2112,
        -112
      ],
      "parameters": {
        "node": "={{ $json.data.creative.object_story_spec.video_data.video_id }}",
        "options": {
          "queryParameters": {
            "parameter": [
              {
                "name": "fields",
                "value": "permalink_url,created_time,id,source"
              }
            ]
          }
        },
        "graphApiVersion": "v23.0"
      },
      "credentials": {
        "facebookGraphApi": {
          "id": "jF7Lc9HyK76Jr9Xm",
          "name": "KH | Facebook Graph"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "0042d4c3-8230-4a6e-ad3d-58737470e225",
      "name": "下载视频文件",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1888,
        -112
      ],
      "parameters": {
        "url": "={{ $json.source }}",
        "options": {
          "response": {
            "response": {}
          }
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "b747cea5-3573-429b-8f60-8a4753014ffc",
      "name": "设置广告系列 ID",
      "type": "n8n-nodes-base.set",
      "position": [
        -3008,
        80
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "da4b6ef7-7c06-40f7-8e3c-f69871311c7a",
              "name": "campaign_id",
              "type": "string",
              "value": "campaign_id"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "a07e2fba-dbdc-45e5-a8f1-e98583b4c66f",
      "name": "拆分输出",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        -2560,
        80
      ],
      "parameters": {
        "include": "allOtherFields",
        "options": {},
        "fieldToSplitOut": "data"
      },
      "typeVersion": 1
    },
    {
      "id": "a522ff6d-b853-4508-81d2-6b077deeb4e9",
      "name": "开始视频标注",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueErrorOutput",
      "position": [
        -1216,
        -176
      ],
      "parameters": {
        "url": "https://videointelligence.googleapis.com/v1/videos:annotate",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"inputContent\": \"{{ $json.data }}\",\n  \"features\": [\n    \"LABEL_DETECTION\",\n    \"SPEECH_TRANSCRIPTION\",\n    \"TEXT_DETECTION\"\n  ],\n  \"locationId\": \"us-east1\"\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "googleApi"
      },
      "credentials": {
        "googleApi": {
          "id": "Nmr8IbL8OVyAxSZO",
          "name": "GCP Video Intelligence SA"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "01e9920b-101c-4363-a733-3f49a406f215",
      "name": "如果就绪",
      "type": "n8n-nodes-base.if",
      "position": [
        -544,
        -272
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "0b5230bd-b5d3-4421-9a9e-e97943c81ab2",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.done }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "ae707d17-a632-4895-9263-6e9263280332",
      "name": "解析数据",
      "type": "n8n-nodes-base.code",
      "position": [
        -96,
        -320
      ],
      "parameters": {
        "jsCode": "// n8n Code node (JavaScript)\n// Mode: Run once for all items\n\nconst inputItems = $input.all();\n\nconst toSeconds = (v) => {\n  if (v == null) return null;\n  if (typeof v === 'number') return v;\n  if (typeof v === 'string' && v.endsWith('s')) return parseFloat(v.slice(0, -1));\n  const n = Number(v);\n  return Number.isFinite(n) ? n : null;\n};\n\nconst nowUtc = () => new Date().toISOString();\n\nconst rows = [];\n\nfor (const item of inputItems) {\n  const j = item.json || {};\n\n  // Metadata from the Set node — keeping the names exactly as specified\n  const meta = {\n    source: j.source ?? null, // important: do not rename, as this field is needed by the next node\n    campaign_id: j.campaign_id ?? null,\n    ad_id: j.ad_id ?? null,\n    creative_id: j.creative_id ?? null,\n    video_id: j.video_id ?? null,\n    file_name: j.file_name ?? null,\n    image_url: j.image_url ?? null,\n  };\n\n  // If file_name was not set in the Set node — try to extract it from the VI response\n  const resolvedFileName =\n    meta.file_name ??\n    (j.response?.annotationResults?.[0]?.inputUri\n      ? j.response.annotationResults[0].inputUri.split('/').pop()\n      : null) ??\n    j.name ??\n    'unknown_file';\n\n  const results = j.response?.annotationResults ?? [];\n  for (const r of results) {\n    // 1) Segment Labels\n    for (const ann of (r.segmentLabelAnnotations ?? [])) {\n      const cat = (ann.categoryEntities ?? [])\n        .map(c => c?.description)\n        .filter(Boolean)\n        .join('|') || null;\n\n      for (const s of (ann.segments ?? [])) {\n        rows.push({\n          ...meta,\n          file_name: resolvedFileName,\n          annotation_type: 'SegmentLabel',\n          label_or_text: ann.entity?.description ?? null,\n          full_transcript: null,\n          category: cat,\n          confidence: s.confidence ?? null,\n          start_time_s: toSeconds(s.segment?.startTimeOffset),\n          end_time_s: toSeconds(s.segment?.endTimeOffset),\n          language_code: null,\n          processed_at_utc: nowUtc(),\n        });\n      }\n    }\n\n    // 2) Shot Labels\n    for (const ann of (r.shotLabelAnnotations ?? [])) {\n      const cat = (ann.categoryEntities ?? [])\n        .map(c => c?.description)\n        .filter(Boolean)\n        .join('|') || null;\n\n      for (const s of (ann.segments ?? [])) {\n        rows.push({\n          ...meta,\n          file_name: resolvedFileName,\n          annotation_type: 'ShotLabel',\n          label_or_text: ann.entity?.description ?? null,\n          full_transcript: null,\n          category: cat,\n          confidence: s.confidence ?? null,\n          start_time_s: toSeconds(s.segment?.startTimeOffset),\n          end_time_s: toSeconds(s.segment?.endTimeOffset),\n          language_code: null,\n          processed_at_utc: nowUtc(),\n        });\n      }\n    }\n\n    // 3) Text Detection\n    for (const t of (r.textAnnotations ?? [])) {\n      for (const s of (t.segments ?? [])) {\n        rows.push({\n          ...meta,\n          file_name: resolvedFileName,\n          annotation_type: 'TextDetection',\n          label_or_text: t.text ?? null,\n          full_transcript: null,\n          category: null,\n          confidence: s.confidence ?? null,\n          start_time_s: toSeconds(s.segment?.startTimeOffset),\n          end_time_s: toSeconds(s.segment?.endTimeOffset),\n          language_code: null,\n          processed_at_utc: nowUtc(),\n        });\n      }\n    }\n\n    // 4) Speech Transcription (if enabled in VI)\n    for (const st of (r.speechTranscriptions ?? [])) {\n      for (const alt of (st.alternatives ?? [])) {\n        const words = alt.words ?? [];\n        const start = words[0]?.startTime ?? null;\n        const end = words.length ? words[words.length - 1]?.endTime : null;\n\n        rows.push({\n          ...meta,\n          file_name: resolvedFileName,\n          annotation_type: 'SpeechTranscription',\n          label_or_text: alt.transcript ?? null,\n          full_transcript: alt.transcript ?? null,\n          category: null,\n          confidence: alt.confidence ?? null,\n          start_time_s: toSeconds(start),\n          end_time_s: toSeconds(end),\n          language_code: st.languageCode ?? null,\n          processed_at_utc: nowUtc(),\n        });\n      }\n    }\n  }\n}\n\n// Return a batch of items\nreturn rows.map(r => ({ json: r }));"
      },
      "typeVersion": 2
    },
    {
      "id": "1f26ad56-9337-42c8-aab5-094e33022f74",
      "name": "下载图像文件",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -928,
        576
      ],
      "parameters": {
        "url": "={{ $json.data.creative.image_url }}",
        "options": {
          "response": {
            "response": {}
          }
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "9d0c3096-2f81-4bf9-a37b-af604d3b4b6e",
      "name": "视频转 Base64 字符串",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        -1664,
        -112
      ],
      "parameters": {
        "options": {},
        "operation": "binaryToPropery"
      },
      "typeVersion": 1
    },
    {
      "id": "0ad3c2a7-269f-4f5b-83f5-0fd39aee5bba",
      "name": "图像转 Base64 字符串",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        -704,
        576
      ],
      "parameters": {
        "options": {},
        "operation": "binaryToPropery"
      },
      "typeVersion": 1
    },
    {
      "id": "c2d1bb24-2a65-4a80-af67-4e7c1e63716b",
      "name": "开始图像标注",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -480,
        576
      ],
      "parameters": {
        "url": "https://vision.googleapis.com/v1/images:annotate",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"requests\": [\n    {\n      \"image\": { \"content\": \"{{ $json.data }}\" },\n      \"features\": [\n        { \"type\": \"LABEL_DETECTION\", \"maxResults\": 50 },\n        { \"type\": \"TEXT_DETECTION\", \"maxResults\": 50 },\n        { \"type\": \"LOGO_DETECTION\", \"maxResults\": 50 },\n        { \"type\": \"LANDMARK_DETECTION\", \"maxResults\": 50 },\n        { \"type\": \"OBJECT_LOCALIZATION\", \"maxResults\": 50 },\n        { \"type\": \"WEB_DETECTION\", \"maxResults\": 50 },\n        { \"type\": \"SAFE_SEARCH_DETECTION\" }\n      ]\n    }\n  ]\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "googleApi"
      },
      "credentials": {
        "googleApi": {
          "id": "Nmr8IbL8OVyAxSZO",
          "name": "GCP Video Intelligence SA"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "6ea1b33d-412f-4a0e-80ad-0c269717b167",
      "name": "为静态创意设置 ID 数据",
      "type": "n8n-nodes-base.set",
      "position": [
        -256,
        576
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "919bc87d-275d-4cbd-bc1e-f16138f7c2f1",
              "name": "campaign_id",
              "type": "string",
              "value": "={{ $('Set Campaign ID').item.json.campaign_id }}"
            },
            {
              "id": "7a59b304-de21-4d19-93b7-086b30033884",
              "name": "ad_id",
              "type": "string",
              "value": "={{ $('Is it a Video?').item.json.data.id }}"
            },
            {
              "id": "9c755ff3-579e-469c-ba4e-77ce81243a41",
              "name": "creative_id",
              "type": "string",
              "value": "={{ $('Is it a Video?').item.json.data.creative.id }}"
            },
            {
              "id": "c5b65d23-521d-48d7-bf9b-b5d4f1387dce",
              "name": "file_name",
              "type": "string",
              "value": "={{ $('Is it a Video?').item.json.data.name }}"
            },
            {
              "id": "60954a83-3c70-40d5-afb5-d79f6948d4a2",
              "name": "image_url",
              "type": "string",
              "value": "={{ $('Download Image File').item.json.data.creative.image_url }}"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "a72dbc3d-2b86-4380-9ae6-56055412e08e",
      "name": "为视频设置 ID 数据",
      "type": "n8n-nodes-base.set",
      "position": [
        -320,
        -320
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "919bc87d-275d-4cbd-bc1e-f16138f7c2f1",
              "name": "campaign_id",
              "type": "string",
              "value": "={{ $('Set Campaign ID').item.json.campaign_id }}"
            },
            {
              "id": "7a59b304-de21-4d19-93b7-086b30033884",
              "name": "ad_id",
              "type": "string",
              "value": "={{ $('Is it a Video?').item.json.data.id }}"
            },
            {
              "id": "9c755ff3-579e-469c-ba4e-77ce81243a41",
              "name": "creative_id",
              "type": "string",
              "value": "={{ $('Is it a Video?').item.json.data.creative.id }}"
            },
            {
              "id": "b68c42ea-dd28-46ca-8d83-a19fd4633c63",
              "name": "video_id",
              "type": "string",
              "value": "={{ $('Is it a Video?').item.json.data.creative.object_story_spec.video_data.video_id }}"
            },
            {
              "id": "c5b65d23-521d-48d7-bf9b-b5d4f1387dce",
              "name": "file_name",
              "type": "string",
              "value": "={{ $('Is it a Video?').item.json.data.name }}"
            },
            {
              "id": "60954a83-3c70-40d5-afb5-d79f6948d4a2",
              "name": "image_url",
              "type": "string",
              "value": "={{ $('Is it a Video?').item.json.data.creative.object_story_spec.video_data.image_url }}"
            },
            {
              "id": "5706a979-2b07-4546-9a07-deddbee6e343",
              "name": "source",
              "type": "string",
              "value": "={{ $('Get Video Source URL').item.json.source }}"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "77438f20-64ed-46d2-a467-2a7a9a209fc5",
      "name": "从图像解析数据",
      "type": "n8n-nodes-base.code",
      "position": [
        -32,
        576
      ],
      "parameters": {
        "jsCode": "// n8n Code node (JavaScript)\n// Mode: Run once for all items\n\nconst items = $input.all();\nconst nowUtc = () => new Date().toISOString();\n\nconst serializeBBox = (verts=[]) =>\n  verts.map(v => `${(v.x ?? 0).toFixed(4)},${(v.y ?? 0).toFixed(4)}`).join('|');\n\nconst rows = [];\n\nfor (const it of items) {\n  const j = it.json || {};\n\n  // Metadata from the 'Set id data' node (trying to get image_url from several places)\n  const resolvedImageUrl =\n    j.image_url\n    ?? j.data?.creative?.image_url\n    ?? j.data?.creative?.thumbnail_url\n    ?? null;\n\n  const meta = {\n    source: j.source ?? null,\n    campaign_id: j.campaign_id ?? null,\n    ad_id: j.ad_id ?? null,\n    creative_id: j.creative_id ?? null,\n    video_id: j.video_id ?? null,\n    file_name: j.file_name ?? null,\n    image_url: resolvedImageUrl,\n  };\n\n  // Cloud Vision response (supporting different wrappers)\n  const resp = j.responses?.[0] || j.response?.responses?.[0] || j.response || {};\n\n  // 1) LABELS\n  for (const a of (resp.labelAnnotations ?? [])) {\n    rows.push({\n      ...meta,\n      annotation_type: 'Label',\n      label_or_text: a.description ?? null,\n      full_transcript: null,\n      category: null,\n      confidence: a.score ?? null,\n      start_time_s: null,\n      end_time_s: null,\n      language_code: null,\n      processed_at_utc: nowUtc(),\n    });\n  }\n\n  // 2) LOGOS\n  for (const a of (resp.logoAnnotations ?? [])) {\n    rows.push({\n      ...meta,\n      annotation_type: 'Logo',\n      label_or_text: a.description ?? null,\n      full_transcript: null,\n      category: 'logo',\n      confidence: a.score ?? null,\n      start_time_s: null,\n      end_time_s: null,\n      language_code: null,\n      processed_at_utc: nowUtc(),\n    });\n  }\n\n  // 3) LANDMARKS\n  for (const a of (resp.landmarkAnnotations ?? [])) {\n    rows.push({\n      ...meta,\n      annotation_type: 'Landmark',\n      label_or_text: a.description ?? null,\n      full_transcript: null,\n      category: null,\n      confidence: a.score ?? null,\n      start_time_s: null,\n      end_time_s: null,\n      language_code: null,\n      processed_at_utc: nowUtc(),\n    });\n  }\n\n  // 4) OBJECTS (bbox)\n  for (const a of (resp.localizedObjectAnnotations ?? [])) {\n    const bbox = serializeBBox(a.boundingPoly?.normalizedVertices ?? []);\n    rows.push({\n      ...meta,\n      annotation_type: 'Object',\n      label_or_text: a.name ?? null,\n      full_transcript: null,\n      category: bbox ? `bbox:${bbox}` : null,\n      confidence: a.score ?? null,\n      start_time_s: null,\n      end_time_s: null,\n      language_code: null,\n      processed_at_utc: nowUtc(),\n    });\n  }\n\n  // 5) WEB DETECTION\n  const web = resp.webDetection || {};\n  for (const e of (web.webEntities ?? [])) {\n    if (!e.description) continue;\n    rows.push({\n      ...meta,\n      annotation_type: 'WebEntity',\n      label_or_text: e.description,\n      full_transcript: null,\n      category: null,\n      confidence: e.score ?? null,\n      start_time_s: null,\n      end_time_s: null,\n      language_code: null,\n      processed_at_utc: nowUtc(),\n    });\n  }\n  for (const b of (web.bestGuessLabels ?? [])) {\n    rows.push({\n      ...meta,\n      annotation_type: 'BestGuess',\n      label_or_text: b.label ?? null,\n      full_transcript: null,\n      category: null,\n      confidence: null,\n      start_time_s: null,\n      end_time_s: null,\n      language_code: null,\n      processed_at_utc: nowUtc(),\n    });\n  }\n\n  // 6) SAFE SEARCH\n  if (resp.safeSearchAnnotation) {\n    const s = resp.safeSearchAnnotation;\n    for (const k of ['adult','medical','violence','spoof','racy']) {\n      rows.push({\n        ...meta,\n        annotation_type: 'SafeSearch',\n        label_or_text: `${k}:${s[k] ?? 'UNKNOWN'}`,\n        full_transcript: null,\n        category: null,\n        confidence: null,\n        start_time_s: null,\n        end_time_s: null,\n        language_code: null,\n        processed_at_utc: nowUtc(),\n      });\n    }\n  }\n\n  // 7) TEXT\n  const fta = resp.fullTextAnnotation;\n  if (fta?.text) {\n    rows.push({\n      ...meta,\n      annotation_type: 'Text',\n      label_or_text: fta.text.slice(0, 1000),\n      full_transcript: fta.text,\n      category: 'fullText',\n      confidence: null,\n      start_time_s: null,\n      end_time_s: null,\n      language_code: null,\n      processed_at_utc: nowUtc(),\n    });\n  } else {\n    for (const t of (resp.textAnnotations ?? []).slice(0, 50)) {\n      if (!t.description) continue;\n      rows.push({\n        ...meta,\n        annotation_type: 'Text',\n        label_or_text: t.description,\n        full_transcript: null,\n        category: 'snippet',\n        confidence: null,\n        start_time_s: null,\n        end_time_s: null,\n        language_code: null,\n        processed_at_utc: nowUtc(),\n      });\n    }\n  }\n}\n\nreturn rows.map(r => ({ json: r }));"
      },
      "typeVersion": 2
    },
    {
      "id": "48761c30-7d32-40ad-855a-5362f12edbf1",
      "name": "有 image_url 吗?",
      "type": "n8n-nodes-base.if",
      "position": [
        -1216,
        368
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "12beb5b0-5438-4dd3-8161-7c8da1ba31c4",
              "operator": {
                "type": "string",
                "operation": "exists",
                "singleValue": true
              },
              "leftValue": "={{ $json.data.creative.image_url }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "dac450fb-80d6-4d07-b929-5bc132a8dea2",
      "name": "视频循环",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        -1440,
        -112
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "6dd566d0-2f05-495f-b1e6-8d9e58a116a6",
      "name": "添加错误",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -768,
        -32
      ],
      "parameters": {
        "columns": {
          "value": {
            "error_type": "={{ $json.error_type }}"
          },
          "schema": [
            {
              "id": "error_type",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "error_type",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "error_message",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "error_message",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "campaign_id",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "campaign_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "ad_id",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "ad_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "creative_id",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "creative_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "video_id",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "video_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "file_name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "file_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "image_url",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "image_url",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "thumbnail_url",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "thumbnail_url",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "source",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "source",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "processed_at_utc",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "processed_at_utc",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1828512644,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1XgMMxrnthHhy1jIaxCWNGHLZ50Z5mv4Be1RlwSpGcuA/edit#gid=1828512644",
          "cachedResultName": "errors"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1XgMMxrnthHhy1jIaxCWNGHLZ50Z5mv4Be1RlwSpGcuA",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1XgMMxrnthHhy1jIaxCWNGHLZ50Z5mv4Be1RlwSpGcuA/edit?usp=drivesdk",
          "cachedResultName": "MetaAds Creative Insights researcher by videointelligence v_1.1"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "0drwHzGo1eKmiTc6",
          "name": "KH | Google Sheets "
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "6ed766ae-73a3-4f69-91f2-ca07d2c70e90",
      "name": "检查操作状态",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -768,
        -352
      ],
      "parameters": {
        "url": "=https://videointelligence.googleapis.com/v1/{{ $('Start Video Annotation').item.json.name }}",
        "options": {},
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "googleApi"
      },
      "credentials": {
        "googleApi": {
          "id": "Nmr8IbL8OVyAxSZO",
          "name": "GCP Video Intelligence SA"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "f7be8b28-9f68-4d36-bfd6-9d45ba55fd80",
      "name": "添加分段数据",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        128,
        -16
      ],
      "parameters": {
        "columns": {
          "value": {
            "ad_id": "={{ $('Set id data for Video').item.json.ad_id }}",
            "source": "={{ $('Set id data for Video').item.json.source }}",
            "category": "={{ $json.category }}",
            "video_id": "={{ $('Set id data for Video').item.json.video_id }}",
            "file_name": "={{ $('Set id data for Video').item.json.file_name }}",
            "image_url": "={{ $('Set id data for Video').item.json.image_url }}",
            "confidence": "={{ $json.confidence }}",
            "end_time_s": "={{ $json.end_time_s }}",
            "campaign_id": "={{ $('Set id data for Video').item.json.campaign_id }}",
            "creative_id": "={{ $('Set id data for Video').item.json.creative_id }}",
            "start_time_s": "={{ $json.start_time_s }}",
            "label_or_text": "={{ $json.label_or_text }}",
            "language_code": "={{ $json.language_code }}",
            "annotation_type": "={{ $json.annotation_type }}",
            "full_transcript": "={{ $json.full_transcript }}",
            "processed_at_utc": "={{ $json.processed_at_utc }}"
          },
          "schema": [
            {
              "id": "source",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "source",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "campaign_id",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "campaign_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "ad_id",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "ad_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "creative_id",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "creative_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "video_id",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "video_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "file_name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "file_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "image_url",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "image_url",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "annotation_type",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "annotation_type",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "label_or_text",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "label_or_text",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "full_transcript",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "full_transcript",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "category",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "category",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "confidence",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "confidence",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "start_time_s",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "start_time_s",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "end_time_s",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "end_time_s",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "language_code",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "language_code",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "processed_at_utc",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "processed_at_utc",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1XgMMxrnthHhy1jIaxCWNGHLZ50Z5mv4Be1RlwSpGcuA/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1XgMMxrnthHhy1jIaxCWNGHLZ50Z5mv4Be1RlwSpGcuA",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1XgMMxrnthHhy1jIaxCWNGHLZ50Z5mv4Be1RlwSpGcuA/edit?usp=drivesdk",
          "cachedResultName": "MetaAds Creative Insights researcher by videointelligence v_1.1"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "0drwHzGo1eKmiTc6",
          "name": "KH | Google Sheets "
        }
      },
      "typeVersion": 4.6,
      "alwaysOutputData": false
    },
    {
      "id": "c6ff4f8e-1a7f-4c23-839a-ec0b640393f0",
      "name": "设置(视频错误行)",
      "type": "n8n-nodes-base.set",
      "position": [
        -992,
        -32
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "cc622574-ba7c-4899-922f-1ea566b9d051",
              "name": "error_type",
              "type": "string",
              "value": "VIDEO_ANNOTATION_FAILED"
            },
            {
              "id": "215a5640-66ed-434d-8b71-708dc1171954",
              "name": "error_message",
              "type": "string",
              "value": "{{ $json.error.message }}"
            },
            {
              "id": "e303f282-9880-450f-b9a1-de04a79697ca",
              "name": "campaign_id",
              "type": "string",
              "value": "={{ $('Set Campaign ID').item.json.campaign_id }}"
            },
            {
              "id": "fd549b0b-67ba-4d81-a76a-c9766dfca013",
              "name": "ad_id",
              "type": "string",
              "value": "={{ $json.data.id }}"
            },
            {
              "id": "8a471e1d-bd4a-4a0c-b2de-6f92073b4545",
              "name": "creative_id",
              "type": "string",
              "value": "={{ $json.data.creative.id }}"
            },
            {
              "id": "1bc0c568-015a-4b7b-990b-42ef5613ca7c",
              "name": "video_id",
              "type": "string",
              "value": ""
            },
            {
              "id": "8d28b972-e82a-49c7-ad1a-fe488f30d842",
              "name": "file_name",
              "type": "string",
              "value": "={{ $json.data.name }}"
            },
            {
              "id": "0dd70485-3a48-4713-a132-3af888d56bc7",
              "name": "image_url",
              "type": "string",
              "value": ""
            },
            {
              "id": "7b508e9c-d605-4bb9-924a-8fe97e971818",
              "name": "thumbnail_url",
              "type": "string",
              "value": "={{ $json.data.creative.thumbnail_url }}"
            },
            {
              "id": "ce62f39e-941f-47ab-ab46-ffa162db561a",
              "name": "source",
              "type": "string",
              "value": ""
            },
            {
              "id": "56b517e5-abd3-4870-b6c1-4cbc318eb1bf",
              "name": "processed_at_utc",
              "type": "string",
              "value": "={{ (new Date()).toISOString() }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "83446d6c-4e47-4953-a1d7-fd23086c0979",
      "name": "便签配置",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3040,
        -192
      ],
      "parameters": {
        "color": 6,
        "width": 450,
        "height": 280,
        "content": "**⚙️ 1. 配置:广告系列 ID**"
      },
      "typeVersion": 1
    },
    {
      "id": "12d3042f-5661-40ba-9ab9-e9cbfea54167",
      "name": "便签分支",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2464,
        224
      ],
      "parameters": {
        "color": 5,
        "width": 450,
        "height": 250,
        "content": "**🔀 2. 分支逻辑:是视频还是图像?**"
      },
      "typeVersion": 1
    },
    {
      "id": "65252e3f-04ba-42d9-8e0f-041448744ae8",
      "name": "便签视频",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1488,
        -496
      ],
      "parameters": {
        "color": 4,
        "width": 1570,
        "height": 380,
        "content": "**🎞️ 3. 视频分析**"
      },
      "typeVersion": 1
    },
    {
      "id": "0e327863-2c8a-4f14-9bc4-cf203746d6a2",
      "name": "便签图像",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -960,
        736
      ],
      "parameters": {
        "color": 6,
        "width": 1042,
        "height": 328,
        "content": "**🖼️ 4. 图像分析**"
      },
      "typeVersion": 1
    },
    {
      "id": "dfc557ed-974f-450d-ba29-b5a76097f8aa",
      "name": "便签错误",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1328,
        0
      ],
      "parameters": {
        "color": 8,
        "width": 770,
        "height": 330,
        "content": "**⚠️ 5. 错误处理**"
      },
      "typeVersion": 1
    },
    {
      "id": "5b3846c2-8a1b-4aeb-96d5-047bc932a3d4",
      "name": "便签 Google Sheets",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        112,
        -240
      ],
      "parameters": {
        "color": 7,
        "width": 402,
        "height": 394,
        "content": "**💾 6. 写入 Google Sheets**"
      },
      "typeVersion": 1
    },
    {
      "id": "a1e7723f-7812-433c-bd3f-cf88cc65852d",
      "name": "等待 3 秒",
      "type": "n8n-nodes-base.wait",
      "position": [
        -320,
        64
      ],
      "webhookId": "f2d0ba40-8c02-45b4-a8ee-2407fd510ae9",
      "parameters": {
        "amount": 3
      },
      "typeVersion": 1.1
    },
    {
      "id": "e50f1d57-0fc5-413a-8f4c-88f5f5360834",
      "name": "等待 30 秒",
      "type": "n8n-nodes-base.wait",
      "position": [
        -992,
        -272
      ],
      "webhookId": "f8cdc1ed-e3c1-4961-b974-ccc59dfa93ff",
      "parameters": {
        "unit": "seconds",
        "amount": 30
      },
      "typeVersion": 1
    },
    {
      "id": "ce8b70bf-e911-4401-abd4-e1a9d97c3c4f",
      "name": "设置(错误行)",
      "type": "n8n-nodes-base.set",
      "position": [
        -944,
        256
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "cc622574-ba7c-4899-922f-1ea566b9d051",
              "name": "error_type",
              "type": "string",
              "value": "NO_IMAGE_URL"
            },
            {
              "id": "215a5640-66ed-434d-8b71-708dc1171954",
              "name": "error_message",
              "type": "string",
              "value": "Image URL or video_id not found "
            },
            {
              "id": "e303f282-9880-450f-b9a1-de04a79697ca",
              "name": "campaign_id",
              "type": "string",
              "value": "={{ $('Set Campaign ID').item.json.campaign_id }}"
            },
            {
              "id": "fd549b0b-67ba-4d81-a76a-c9766dfca013",
              "name": "ad_id",
              "type": "string",
              "value": "={{ $json.data.id }}"
            },
            {
              "id": "8a471e1d-bd4a-4a0c-b2de-6f92073b4545",
              "name": "creative_id",
              "type": "string",
              "value": "={{ $json.data.creative.id }}"
            },
            {
              "id": "1bc0c568-015a-4b7b-990b-42ef5613ca7c",
              "name": "video_id",
              "type": "string",
              "value": ""
            },
            {
              "id": "8d28b972-e82a-49c7-ad1a-fe488f30d842",
              "name": "file_name",
              "type": "string",
              "value": "={{ $json.data.name }}"
            },
            {
              "id": "0dd70485-3a48-4713-a132-3af888d56bc7",
              "name": "image_url",
              "type": "string",
              "value": ""
            },
            {
              "id": "7b508e9c-d605-4bb9-924a-8fe97e971818",
              "name": "thumbnail_url",
              "type": "string",
              "value": "={{ $json.data.creative.thumbnail_url }}"
            },
            {
              "id": "ce62f39e-941f-47ab-ab46-ffa162db561a",
              "name": "source",
              "type": "string",
              "value": ""
            },
            {
              "id": "56b517e5-abd3-4870-b6c1-4cbc318eb1bf",
              "name": "processed_at_utc",
              "type": "string",
              "value": "={{ (new Date()).toISOString() }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "46c643b2-3e26-4881-99bb-d4d2491d313d",
  "connections": {
    "Wait 3s": {
      "main": [
        [
          {
            "node": "Loop for videos",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If Ready": {
      "main": [
        [
          {
            "node": "Wait 3s",
            "type": "main",
            "index": 0
          },
          {
            "node": "Set id data for Video",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Wait 30s",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait 30s": {
      "main": [
        [
          {
            "node": "Check Operation Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out": {
      "main": [
        [
          {
            "node": "Is it a Video?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse data": {
      "main": [
        [
          {
            "node": "Add Segments data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Active Ads": {
      "main": [
        [
          {
            "node": "Split Out",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Has image_url?": {
      "main": [
        [
          {
            "node": "Download Image File",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Set (Error Row)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is it a Video?": {
      "main": [
        [
          {
            "node": "Get Video Source URL",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Has image_url?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop for videos": {
      "main": [
        [],
        [
          {
            "node": "Start Video Annotation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set (Error Row)": {
      "main": [
        [
          {
            "node": "Add errors",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Campaign ID": {
      "main": [
        [
          {
            "node": "Get Active Ads",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Run Daily at 9 AM": {
      "main": [
        [
          {
            "node": "Set Campaign ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download Image File": {
      "main": [
        [
          {
            "node": "Image to Base64 String",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download Video File": {
      "main": [
        [
          {
            "node": "Video to Base64 String",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Video Source URL": {
      "main": [
        [
          {
            "node": "Download Video File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set (Video Error Row)": {
      "main": [
        [
          {
            "node": "Add errors",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set id data for Video": {
      "main": [
        [
          {
            "node": "Parse data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Operation Status": {
      "main": [
        [
          {
            "node": "If Ready",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Image to Base64 String": {
      "main": [
        [
          {
            "node": "Start Image Annotation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse data from images": {
      "main": [
        [
          {
            "node": "Add Segments data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set id data for Static": {
      "main": [
        [
          {
            "node": "Parse data from images",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Start Image Annotation": {
      "main": [
        [
          {
            "node": "Set id data for Static",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Start Video Annotation": {
      "main": [
        [
          {
            "node": "Wait 30s",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Set (Video Error Row)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Video to Base64 String": {
      "main": [
        [
          {
            "node": "Loop for videos",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。

这个工作流适合什么场景?

高级 - 市场调研, 多模态 AI

需要付费吗?

本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。

工作流信息
难度等级
高级
节点数量32
分类2
节点类型12
难度说明

适合高级用户,包含 16+ 个节点的复杂工作流

外部链接
在 n8n.io 查看

分享此工作流