使用Claude AI、竞品分析和Supabase RAG的SEO内容生成器
高级
这是一个Content Creation, Multimodal AI领域的自动化工作流,包含 40 个节点。主要使用 If, Code, Filter, HttpRequest, GoogleSheets 等节点。 使用Claude AI、竞品分析和Supabase RAG生成SEO内容
前置要求
- •可能需要目标 API 的认证凭证
- •Google Sheets API 凭证
- •Anthropic API Key
- •OpenAI API Key
- •Supabase URL 和 API Key
使用的节点 (40)
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
"meta": {
"instanceId": "393ca9e36a1f81b0f643c72792946a5fe5e49eb4864181ba4032e5a408278263"
},
"nodes": [
{
"id": "032fa5cd-ddba-4004-9c16-395ca9f8509b",
"name": "过滤器1",
"type": "n8n-nodes-base.filter",
"position": [
-1280,
448
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "d0a801f4-942f-4f2b-b71f-f31f23066f28",
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{ $json['Keyword'] }}",
"rightValue": ""
},
{
"id": "6e0d041d-30cd-413d-913d-3c1775840277",
"operator": {
"type": "string",
"operation": "empty",
"singleValue": true
},
"leftValue": "={{ $json['<h1>'] }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "6d0d3e23-ce99-4151-acb7-9d78dca10961",
"name": "条件判断1",
"type": "n8n-nodes-base.if",
"position": [
-1088,
448
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "b5344169-b18b-482d-9d03-b02c170668b9",
"operator": {
"type": "string",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $json['Keyword'] }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "4f7306be-5788-451b-9974-b3e509b7bfc9",
"name": "Anthropic 聊天模型2",
"type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
"position": [
896,
640
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "claude-sonnet-4-20250514",
"cachedResultName": "Claude Sonnet 4"
},
"options": {}
},
"credentials": {
"anthropicApi": {
"id": "WXQf5QsxCs3AyxlW",
"name": "Anthropic account"
}
},
"typeVersion": 1.3
},
{
"id": "6ac8f3a1-1eb9-448f-b962-9260fdfe6fc6",
"name": "Supabase 向量存储2",
"type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
"position": [
1056,
640
],
"parameters": {
"mode": "retrieve-as-tool",
"topK": 5,
"options": {
"queryName": "=match_{{ $('Client Information').item.json['Supabase database'] }}_documents"
},
"toolName": "BaseDeDonnees",
"tableName": {
"__rl": true,
"mode": "id",
"value": "={{ $('Client Information').item.json['Supabase database'] }}_documents"
},
"toolDescription": "=Here's a database with information about {{ $('Client Information').item.json['Client name'] }}, you can use it to improve the relevance in your writing."
},
"credentials": {
"supabaseApi": {
"id": "WXo0zqqBO5HTdEW5",
"name": "Clients"
}
},
"typeVersion": 1.1
},
{
"id": "430268c9-f9dc-41ff-b7aa-a51794efe0fc",
"name": "OpenAI 嵌入2",
"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
"position": [
1152,
768
],
"parameters": {
"options": {}
},
"credentials": {
"openAiApi": {
"id": "Wk5dyBYFy6HDwml2",
"name": "OpenAi account"
}
},
"typeVersion": 1.2
},
{
"id": "ebc3843c-55a9-426e-877a-a34b56b30e01",
"name": "结构化输出解析器2",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
1392,
640
],
"parameters": {
"jsonSchemaExample": "{\n\t\"meta_title\": \"Courtage Assurance : Services & Avantages d'un Courtier en 2023\",\n\t\"meta_description\": \"Découvrez comment optimiser votre compte de libre passage avec Revolution. Conseils d'experts pour maximiser votre capital retraite et faire les meilleurs choix. Consultez-nous !\",\n \"h1\": \"Compte de libre passage : Guide complet pour gérer votre 2e pilier\"\n}"
},
"typeVersion": 1.2
},
{
"id": "0b01c8ed-fb64-4793-9ad5-23e8f2cbb042",
"name": "Anthropic 聊天模型",
"type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
"position": [
1760,
640
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "claude-sonnet-4-20250514",
"cachedResultName": "Claude Sonnet 4"
},
"options": {}
},
"credentials": {
"anthropicApi": {
"id": "WXQf5QsxCs3AyxlW",
"name": "Anthropic account"
}
},
"typeVersion": 1.3
},
{
"id": "3a3bff06-54d9-4e63-9b48-bcd35714a6ce",
"name": "Supabase 向量存储",
"type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
"position": [
1920,
640
],
"parameters": {
"mode": "retrieve-as-tool",
"topK": 5,
"options": {
"queryName": "=match_{{ $('Client Information').item.json['Supabase database'] }}_documents"
},
"toolName": "BaseDeDonnees",
"tableName": {
"__rl": true,
"mode": "id",
"value": "={{ $('Client Information').item.json['Supabase database'] }}_documents"
},
"toolDescription": "=Here's a database with information about {{ $('Client Information').item.json['Client name'] }}, you can use it to improve the relevance in your writing."
},
"credentials": {
"supabaseApi": {
"id": "WXo0zqqBO5HTdEW5",
"name": "Clients"
}
},
"typeVersion": 1.1
},
{
"id": "6956f1b1-a7f5-4350-b2f0-d4a65e7f2423",
"name": "OpenAI 嵌入",
"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
"position": [
2016,
768
],
"parameters": {
"options": {}
},
"credentials": {
"openAiApi": {
"id": "Wk5dyBYFy6HDwml2",
"name": "OpenAi account"
}
},
"typeVersion": 1.2
},
{
"id": "7670a1db-3d6e-4d42-842f-49de3d307bef",
"name": "标题1",
"type": "n8n-nodes-base.code",
"position": [
336,
-64
],
"parameters": {
"jsCode": "// Fonction pour extraire et regrouper les titres par niveau\nfunction extractAndGroupTitles(markdownText) {\n // Expression régulière pour capturer les titres h1-h6\n const headingRegex = /^(#{1,6})\\s+(.+)$/gm;\n \n // Initialiser tous les niveaux avec \"pas de h{n}\"\n const titlesByLevel = {\n h1: [],\n h2: [],\n h3: [],\n h4: [],\n h5: [],\n h6: []\n };\n \n let match;\n \n // Parcourir toutes les correspondances\n while ((match = headingRegex.exec(markdownText)) !== null) {\n const level = match[1].length; // Nombre de #\n let text = match[2].trim();\n \n // Retirer les liens markdown : [texte](url) -> texte\n text = text.replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1');\n \n const levelTag = `h${level}`;\n \n titlesByLevel[levelTag].push(text);\n }\n \n // Créer l'objet de résultat\n const result = {};\n \n Object.keys(titlesByLevel).forEach(level => {\n if (titlesByLevel[level].length === 0) {\n result[level] = `${level} : pas de ${level}`;\n } else {\n result[level] = `${level} :\\n${titlesByLevel[level].join('\\n')}`;\n }\n });\n \n return result;\n}\n\n// Récupérer les données d'entrée\nconst inputData = $input.first();\n\n// Vérifier la structure et récupérer le markdown\nlet markdown = '';\nif (inputData && inputData.json && inputData.json.data && inputData.json.data.markdown) {\n markdown = inputData.json.data.markdown;\n} else {\n console.log(\"Structure non reconnue:\", JSON.stringify(inputData).substring(0, 300));\n return {\n json: {\n h1: \"h1 : pas de h1\",\n h2: \"h2 : pas de h2\",\n h3: \"h3 : pas de h3\",\n h4: \"h4 : pas de h4\",\n h5: \"h5 : pas de h5\",\n h6: \"h6 : pas de h6\"\n }\n };\n}\n\n// Extraire et regrouper les titres\nconst titres = extractAndGroupTitles(markdown);\n\n// Retourner le résultat dans le format demandé\nreturn {\n json: titres\n};"
},
"typeVersion": 2
},
{
"id": "27649231-5440-4099-82c0-ad2d96092b85",
"name": "标题2",
"type": "n8n-nodes-base.code",
"position": [
336,
160
],
"parameters": {
"jsCode": "// Fonction pour extraire et regrouper les titres par niveau\nfunction extractAndGroupTitles(markdownText) {\n // Expression régulière pour capturer les titres h1-h6\n const headingRegex = /^(#{1,6})\\s+(.+)$/gm;\n \n // Initialiser tous les niveaux avec \"pas de h{n}\"\n const titlesByLevel = {\n h1: [],\n h2: [],\n h3: [],\n h4: [],\n h5: [],\n h6: []\n };\n \n let match;\n \n // Parcourir toutes les correspondances\n while ((match = headingRegex.exec(markdownText)) !== null) {\n const level = match[1].length; // Nombre de #\n let text = match[2].trim();\n \n // Retirer les liens markdown : [texte](url) -> texte\n text = text.replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1');\n \n const levelTag = `h${level}`;\n \n titlesByLevel[levelTag].push(text);\n }\n \n // Créer l'objet de résultat\n const result = {};\n \n Object.keys(titlesByLevel).forEach(level => {\n if (titlesByLevel[level].length === 0) {\n result[level] = `${level} : pas de ${level}`;\n } else {\n result[level] = `${level} :\\n${titlesByLevel[level].join('\\n')}`;\n }\n });\n \n return result;\n}\n\n// Récupérer les données d'entrée\nconst inputData = $input.first();\n\n// Vérifier la structure et récupérer le markdown\nlet markdown = '';\nif (inputData && inputData.json && inputData.json.data && inputData.json.data.markdown) {\n markdown = inputData.json.data.markdown;\n} else {\n console.log(\"Structure non reconnue:\", JSON.stringify(inputData).substring(0, 300));\n return {\n json: {\n h1: \"h1 : pas de h1\",\n h2: \"h2 : pas de h2\",\n h3: \"h3 : pas de h3\",\n h4: \"h4 : pas de h4\",\n h5: \"h5 : pas de h5\",\n h6: \"h6 : pas de h6\"\n }\n };\n}\n\n// Extraire et regrouper les titres\nconst titres = extractAndGroupTitles(markdown);\n\n// Retourner le résultat dans le format demandé\nreturn {\n json: titres\n};"
},
"typeVersion": 2
},
{
"id": "ce4ed824-ce7c-4d18-b1e7-c473e257e514",
"name": "标题3",
"type": "n8n-nodes-base.code",
"position": [
336,
384
],
"parameters": {
"jsCode": "// Fonction pour extraire et regrouper les titres par niveau\nfunction extractAndGroupTitles(markdownText) {\n // Expression régulière pour capturer les titres h1-h6\n const headingRegex = /^(#{1,6})\\s+(.+)$/gm;\n \n // Initialiser tous les niveaux avec \"pas de h{n}\"\n const titlesByLevel = {\n h1: [],\n h2: [],\n h3: [],\n h4: [],\n h5: [],\n h6: []\n };\n \n let match;\n \n // Parcourir toutes les correspondances\n while ((match = headingRegex.exec(markdownText)) !== null) {\n const level = match[1].length; // Nombre de #\n let text = match[2].trim();\n \n // Retirer les liens markdown : [texte](url) -> texte\n text = text.replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1');\n \n const levelTag = `h${level}`;\n \n titlesByLevel[levelTag].push(text);\n }\n \n // Créer l'objet de résultat\n const result = {};\n \n Object.keys(titlesByLevel).forEach(level => {\n if (titlesByLevel[level].length === 0) {\n result[level] = `${level} : pas de ${level}`;\n } else {\n result[level] = `${level} :\\n${titlesByLevel[level].join('\\n')}`;\n }\n });\n \n return result;\n}\n\n// Récupérer les données d'entrée\nconst inputData = $input.first();\n\n// Vérifier la structure et récupérer le markdown\nlet markdown = '';\nif (inputData && inputData.json && inputData.json.data && inputData.json.data.markdown) {\n markdown = inputData.json.data.markdown;\n} else {\n console.log(\"Structure non reconnue:\", JSON.stringify(inputData).substring(0, 300));\n return {\n json: {\n h1: \"h1 : pas de h1\",\n h2: \"h2 : pas de h2\",\n h3: \"h3 : pas de h3\",\n h4: \"h4 : pas de h4\",\n h5: \"h5 : pas de h5\",\n h6: \"h6 : pas de h6\"\n }\n };\n}\n\n// Extraire et regrouper les titres\nconst titres = extractAndGroupTitles(markdown);\n\n// Retourner le résultat dans le format demandé\nreturn {\n json: titres\n};"
},
"typeVersion": 2
},
{
"id": "743ed1ac-a884-43cb-ab5b-c461c901a70c",
"name": "标题4",
"type": "n8n-nodes-base.code",
"position": [
336,
592
],
"parameters": {
"jsCode": "// Fonction pour extraire et regrouper les titres par niveau\nfunction extractAndGroupTitles(markdownText) {\n // Expression régulière pour capturer les titres h1-h6\n const headingRegex = /^(#{1,6})\\s+(.+)$/gm;\n \n // Initialiser tous les niveaux avec \"pas de h{n}\"\n const titlesByLevel = {\n h1: [],\n h2: [],\n h3: [],\n h4: [],\n h5: [],\n h6: []\n };\n \n let match;\n \n // Parcourir toutes les correspondances\n while ((match = headingRegex.exec(markdownText)) !== null) {\n const level = match[1].length; // Nombre de #\n let text = match[2].trim();\n \n // Retirer les liens markdown : [texte](url) -> texte\n text = text.replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1');\n \n const levelTag = `h${level}`;\n \n titlesByLevel[levelTag].push(text);\n }\n \n // Créer l'objet de résultat\n const result = {};\n \n Object.keys(titlesByLevel).forEach(level => {\n if (titlesByLevel[level].length === 0) {\n result[level] = `${level} : pas de ${level}`;\n } else {\n result[level] = `${level} :\\n${titlesByLevel[level].join('\\n')}`;\n }\n });\n \n return result;\n}\n\n// Récupérer les données d'entrée\nconst inputData = $input.first();\n\n// Vérifier la structure et récupérer le markdown\nlet markdown = '';\nif (inputData && inputData.json && inputData.json.data && inputData.json.data.markdown) {\n markdown = inputData.json.data.markdown;\n} else {\n console.log(\"Structure non reconnue:\", JSON.stringify(inputData).substring(0, 300));\n return {\n json: {\n h1: \"h1 : pas de h1\",\n h2: \"h2 : pas de h2\",\n h3: \"h3 : pas de h3\",\n h4: \"h4 : pas de h4\",\n h5: \"h5 : pas de h5\",\n h6: \"h6 : pas de h6\"\n }\n };\n}\n\n// Extraire et regrouper les titres\nconst titres = extractAndGroupTitles(markdown);\n\n// Retourner le résultat dans le format demandé\nreturn {\n json: titres\n};"
},
"typeVersion": 2
},
{
"id": "0ad858fb-78d9-400e-8f08-4d46e1716000",
"name": "标题5",
"type": "n8n-nodes-base.code",
"position": [
336,
784
],
"parameters": {
"jsCode": "// Fonction pour extraire et regrouper les titres par niveau\nfunction extractAndGroupTitles(markdownText) {\n // Expression régulière pour capturer les titres h1-h6\n const headingRegex = /^(#{1,6})\\s+(.+)$/gm;\n \n // Initialiser tous les niveaux avec \"pas de h{n}\"\n const titlesByLevel = {\n h1: [],\n h2: [],\n h3: [],\n h4: [],\n h5: [],\n h6: []\n };\n \n let match;\n \n // Parcourir toutes les correspondances\n while ((match = headingRegex.exec(markdownText)) !== null) {\n const level = match[1].length; // Nombre de #\n let text = match[2].trim();\n \n // Retirer les liens markdown : [texte](url) -> texte\n text = text.replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1');\n \n const levelTag = `h${level}`;\n \n titlesByLevel[levelTag].push(text);\n }\n \n // Créer l'objet de résultat\n const result = {};\n \n Object.keys(titlesByLevel).forEach(level => {\n if (titlesByLevel[level].length === 0) {\n result[level] = `${level} : pas de ${level}`;\n } else {\n result[level] = `${level} :\\n${titlesByLevel[level].join('\\n')}`;\n }\n });\n \n return result;\n}\n\n// Récupérer les données d'entrée\nconst inputData = $input.first();\n\n// Vérifier la structure et récupérer le markdown\nlet markdown = '';\nif (inputData && inputData.json && inputData.json.data && inputData.json.data.markdown) {\n markdown = inputData.json.data.markdown;\n} else {\n console.log(\"Structure non reconnue:\", JSON.stringify(inputData).substring(0, 300));\n return {\n json: {\n h1: \"h1 : pas de h1\",\n h2: \"h2 : pas de h2\",\n h3: \"h3 : pas de h3\",\n h4: \"h4 : pas de h4\",\n h5: \"h5 : pas de h5\",\n h6: \"h6 : pas de h6\"\n }\n };\n}\n\n// Extraire et regrouper les titres\nconst titres = extractAndGroupTitles(markdown);\n\n// Retourner le résultat dans le format demandé\nreturn {\n json: titres\n};"
},
"typeVersion": 2
},
{
"id": "f7948f6b-a650-41c2-8c7d-2603e393cb73",
"name": "代码",
"type": "n8n-nodes-base.code",
"position": [
2464,
432
],
"parameters": {
"jsCode": "// Code avec conservation de toutes les colonnes existantes\nconst items = [];\n\n// Récupérer les données de vos différents nodes\nconst loopItem = $('Loop Over Items').item.json;\nconst metaTagsOutput = $('Meta tag + h1').item.json.output;\nconst briefOutput = $json.output;\n\n// Créer l'objet avec toutes les colonnes et le mapping des nouvelles valeurs\nconst transformedItem = {\n // Copier toutes les propriétés existantes\n ...loopItem,\n \n // Écraser/ajouter les nouvelles valeurs\n '<title>': metaTagsOutput.meta_title,\n '<meta-desc>': metaTagsOutput.meta_description,\n '<h1>': metaTagsOutput.h1,\n 'brief': briefOutput\n};\n\n// Retourner l'item transformé\nitems.push(transformedItem);\n\nreturn items;"
},
"typeVersion": 2
},
{
"id": "a4485f65-cb46-4282-b0f4-1cdb95277592",
"name": "Apify",
"type": "n8n-nodes-base.httpRequest",
"position": [
-432,
448
],
"parameters": {
"url": "https://api.apify.com/v2/acts/nFJndFXA5zjCTuudP/run-sync-get-dataset-items",
"method": "POST",
"options": {
"timeout": 300000,
"response": {
"response": {
"responseFormat": "json"
}
}
},
"jsonBody": "={\n \"countryCode\": \"fr\",\n \"forceExactMatch\": false,\n \"includeIcons\": false,\n \"includeUnfilteredResults\": false,\n \"languageCode\": \"fr\",\n \"maxPagesPerQuery\": 1,\n \"mobileResults\": false,\n \"queries\": \"{{ $json['Keyword'] }}\",\n \"resultsPerPage\": 10,\n \"saveHtml\": false,\n \"saveHtmlToKeyValueStore\": false\n}",
"sendBody": true,
"sendQuery": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"queryParameters": {
"parameters": [
{
"name": "timeout",
"value": "240"
},
{
"name": "memory",
"value": "512"
},
{
"name": "maxItems",
"value": "10"
},
{
"name": "format",
"value": "json"
},
{
"name": "maxTotalChargeUsd",
"value": "0.50"
}
]
},
"nodeCredentialType": "httpHeaderAuth"
},
"credentials": {
"httpHeaderAuth": {
"id": "jAy18eDHHP2ZoGrH",
"name": "Apify"
}
},
"executeOnce": true,
"typeVersion": 4.2
},
{
"id": "a5ef41de-4718-4902-adb9-cff82e1b3885",
"name": "在表格中更新行",
"type": "n8n-nodes-base.googleSheets",
"position": [
2816,
432
],
"parameters": {
"columns": {
"value": {},
"schema": [
{
"id": "Niv 0",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Niv 0",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Niv 1",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Niv 1",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Niv 2",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Niv 2",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Niv 3",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Niv 3",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "mots clés",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "mots clés",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "vol",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "vol",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "KD%",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "KD%",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Type de page",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Type de page",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "URL",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "URL",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "<title>",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "<title>",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "<meta-desc>",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "<meta-desc>",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "<h1>",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "<h1>",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "brief",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "brief",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "mots clés secondaires",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "mots clés secondaires",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "intentions de recherche",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "intentions de recherche",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "nombre de mots",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "nombre de mots",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Premiere version",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Premiere version",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Thot",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Thot",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "col_11",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "col_11",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "col_13",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "col_13",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "col_15",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "col_15",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "row_number",
"type": "string",
"display": true,
"removed": false,
"readOnly": true,
"required": false,
"displayName": "row_number",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "autoMapInputData",
"matchingColumns": [
"mots clés"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "name",
"value": "FR"
},
"documentId": {
"__rl": true,
"mode": "url",
"value": "={{ $('When chat message received').item.json.chatInput }}"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "wBRLUCktxqXE6DVJ",
"name": "Google Sheets account"
}
},
"typeVersion": 4.5
},
{
"id": "d953e577-f521-4162-8f41-28f6962e593f",
"name": "爬取1",
"type": "@mendable/n8n-nodes-firecrawl.firecrawl",
"onError": "continueRegularOutput",
"position": [
64,
-64
],
"parameters": {
"url": "={{ $('Apify').item.json.organicResults[0].url }}",
"operation": "scrape",
"scrapeOptions": {
"options": {
"headers": {},
"includeTags": {
"items": [
{
"tag": "h1, h2, h3, h4"
}
]
}
}
},
"requestOptions": {}
},
"credentials": {
"firecrawlApi": {
"id": "E34WDB80ik5VHjiI",
"name": "Firecrawl account"
}
},
"typeVersion": 1,
"alwaysOutputData": false
},
{
"id": "4fb36ed5-04fd-415f-b288-b1f6c6681b67",
"name": "爬取2",
"type": "@mendable/n8n-nodes-firecrawl.firecrawl",
"onError": "continueRegularOutput",
"position": [
64,
160
],
"parameters": {
"url": "={{ $('Apify').item.json.organicResults[1].url }}",
"operation": "scrape",
"scrapeOptions": {
"options": {
"headers": {},
"includeTags": {
"items": [
{
"tag": "h1, h2, h3, h4"
}
]
}
}
},
"requestOptions": {}
},
"credentials": {
"firecrawlApi": {
"id": "E34WDB80ik5VHjiI",
"name": "Firecrawl account"
}
},
"typeVersion": 1,
"alwaysOutputData": false
},
{
"id": "9fe7da48-4ce4-4dd9-b8db-719c91a4bd8e",
"name": "爬取5",
"type": "@mendable/n8n-nodes-firecrawl.firecrawl",
"onError": "continueRegularOutput",
"position": [
64,
784
],
"parameters": {
"url": "={{ $('Apify').item.json.organicResults[4].url }}",
"operation": "scrape",
"scrapeOptions": {
"options": {
"headers": {},
"includeTags": {
"items": [
{
"tag": "h1, h2, h3, h4"
}
]
}
}
},
"requestOptions": {}
},
"credentials": {
"firecrawlApi": {
"id": "E34WDB80ik5VHjiI",
"name": "Firecrawl account"
}
},
"typeVersion": 1,
"alwaysOutputData": false
},
{
"id": "a5a1bbe4-8e4a-43c3-a79d-17ccaf4a62f8",
"name": "爬取4",
"type": "@mendable/n8n-nodes-firecrawl.firecrawl",
"onError": "continueRegularOutput",
"position": [
64,
592
],
"parameters": {
"url": "={{ $('Apify').item.json.organicResults[3].url }}",
"operation": "scrape",
"scrapeOptions": {
"options": {
"headers": {},
"includeTags": {
"items": [
{
"tag": "h1, h2, h3, h4"
}
]
}
}
},
"requestOptions": {}
},
"credentials": {
"firecrawlApi": {
"id": "E34WDB80ik5VHjiI",
"name": "Firecrawl account"
}
},
"typeVersion": 1,
"alwaysOutputData": false
},
{
"id": "0212ab73-03c1-4469-a577-7929052ed3f4",
"name": "爬取3",
"type": "@mendable/n8n-nodes-firecrawl.firecrawl",
"onError": "continueRegularOutput",
"position": [
64,
384
],
"parameters": {
"url": "={{ $('Apify').item.json.organicResults[2].url }}",
"operation": "scrape",
"scrapeOptions": {
"options": {
"headers": {},
"includeTags": {
"items": [
{
"tag": "h1, h2, h3, h4"
}
]
}
}
},
"requestOptions": {}
},
"credentials": {
"firecrawlApi": {
"id": "E34WDB80ik5VHjiI",
"name": "Firecrawl account"
}
},
"typeVersion": 1,
"alwaysOutputData": false
},
{
"id": "a428387e-f48a-4441-85ab-5633df895e02",
"name": "客户信息",
"type": "n8n-nodes-base.googleSheets",
"position": [
-1728,
448
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "name",
"value": "Client information"
},
"documentId": {
"__rl": true,
"mode": "url",
"value": "={{ $('When chat message received').item.json.chatInput }}"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "wBRLUCktxqXE6DVJ",
"name": "Google Sheets account"
}
},
"typeVersion": 4.5
},
{
"id": "6980bc20-deff-4b86-aff9-aa6532e5af96",
"name": "SEO 信息",
"type": "n8n-nodes-base.googleSheets",
"position": [
-1504,
448
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "name",
"value": "SEO"
},
"documentId": {
"__rl": true,
"mode": "url",
"value": "={{ $('When chat message received').item.json.chatInput }}"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "wBRLUCktxqXE6DVJ",
"name": "Google Sheets account"
}
},
"typeVersion": 4.5
},
{
"id": "56cd7226-72cf-4a1f-9175-646c2d701851",
"name": "当收到聊天消息时",
"type": "@n8n/n8n-nodes-langchain.chatTrigger",
"position": [
-2000,
448
],
"webhookId": "88a8efaa-7712-49bd-ba94-4bb130719dbe",
"parameters": {
"mode": "webhook",
"public": true,
"options": {
"responseMode": "responseNode"
}
},
"typeVersion": 1.1
},
{
"id": "81fdb3c4-5fe0-42aa-8ec8-f74438331ef8",
"name": "遍历项目",
"type": "n8n-nodes-base.splitInBatches",
"position": [
-848,
432
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "26c815ed-adc8-4ecd-80ff-ff51d92fdda1",
"name": "元标签 + h1",
"type": "@n8n/n8n-nodes-langchain.agent",
"maxTries": 5,
"position": [
1024,
432
],
"parameters": {
"text": "=[Main keyword]: {{ $('Loop Over Items').item.json['Keyword'] }}\n\n[Page]: {{ $('SEO information').item.json.Page }}\n\n[Site]: {{ $('Client Information').item.json['Client name'] }} ({{ $('Client Information').item.json['Client information'] }})\n\n[Description]:{{ $('Loop Over Items').item.json.Description }}\n\n[Competitor info]:\n\nCompetitor 1:\n{{ $('Apify').item?.json?.organicResults?.[0]?.url || '' }}\n\nMeta title: {{ $('Apify').item?.json?.organicResults?.[0]?.title || '' }}\nMeta description: {{ $('Apify').item?.json?.organicResults?.[0]?.description || '' }}\n{{ $('Titre 1').item.json.h1 }}\n\nCompetitor 2:\n{{ $('Apify').item?.json?.organicResults?.[1]?.url || '' }}\nMeta title: {{ $('Apify').item?.json?.organicResults?.[1]?.title || '' }}\nMeta description: {{ $('Apify').item?.json?.organicResults?.[1]?.description || '' }}\n{{ $('Titre 2').item.json.h1 }}\n\nCompetitor 3:\n{{ $('Apify').item?.json?.organicResults?.[2]?.url || '' }}\nMeta title: {{ $('Apify').item?.json?.organicResults?.[2]?.title || '' }}\nMeta description: {{ $('Apify').item?.json?.organicResults?.[2]?.description || '' }}\n{{ $('Titre 3').item.json.h1 }}\n\nCompetitor 4:\n{{ $('Apify').item?.json?.organicResults?.[3]?.url || '' }}\nMeta title: {{ $('Apify').item?.json?.organicResults?.[3]?.title || '' }}\nMeta description: {{ $('Apify').item?.json?.organicResults?.[3]?.description || '' }}\n{{ $('Titre 4').item.json.h1 }}\n\nCompetitor 5:\n{{ $('Apify').item?.json?.organicResults?.[4]?.url || '' }}\nMeta title: {{ $('Apify').item?.json?.organicResults?.[4]?.title || '' }}\nMeta description: {{ $('Apify').item?.json?.organicResults?.[4]?.description || '' }}\n{{ $('Titre 5').item.json.h1 }}\n\n[Client name]: {{ $('Client Information').item.json['Client name'] }}",
"options": {
"systemMessage": "# Rules\n\nAs an SEO expert, I need you to analyze the [Main keyword] for the page [Page], for the site [Site]. You also have a short description [Description] of what the page is about. You must also analyze the competitor info [Competitor info] (url, meta title, meta description, h1)\n\n# Deliverables\n\nto provide the following elements:\n\nMETA TITLE (65 characters maximum):\nCreate a catchy and optimized meta title that includes the main keyword at the beginning of the title if possible, while remaining natural and click-inducing. The format should be in sentence case. Expected structure for the title: Main keyword, cta (do not include the [Client name] in the title)\n\nMETA DESCRIPTION (165 characters maximum):\nWrite a persuasive meta description that clearly summarizes the page's added value, includes the main keyword and features an effective call-to-action.\n\nH1 (70 characters maximum):\nPropose an impactful H1 that integrates the main keyword while being attractive to the user. The format should be in sentence case.\n\nDo not write an introduction or conclusion to your response.\n\n# Tools\n\nYou have access to a RAG database with information about the client [Client name] to help you write the requested information as effectively as possible."
},
"promptType": "define",
"hasOutputParser": true
},
"retryOnFail": true,
"typeVersion": 1.9,
"waitBetweenTries": 5000
},
{
"id": "08ed03ff-61de-474e-bfc5-23d0b65adb08",
"name": "便签",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2048,
352
],
"parameters": {
"color": 2,
"width": 1360,
"height": 256,
"content": "# 阶段1:数据输入与配置"
},
"typeVersion": 1
},
{
"id": "4bc76db0-11e9-415b-b43e-d8e7cf8d9bf1",
"name": "便签1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-576,
-128
],
"parameters": {
"color": 3,
"width": 1248,
"height": 1072,
"content": "# 阶段2:竞争对手研究与分析"
},
"typeVersion": 1
},
{
"id": "1effb4a8-4543-46b3-9792-7d496c749015",
"name": "便签2",
"type": "n8n-nodes-base.stickyNote",
"position": [
848,
352
],
"parameters": {
"color": 5,
"width": 656,
"height": 560,
"content": "# 阶段3:元标签和 H1 生成"
},
"typeVersion": 1
},
{
"id": "feada2a4-5e65-482a-aacc-4cd5b1361c80",
"name": "便签4",
"type": "n8n-nodes-base.stickyNote",
"position": [
2416,
352
],
"parameters": {
"color": 7,
"width": 560,
"height": 256,
"content": "# 阶段5:数据集成与表格更新"
},
"typeVersion": 1
},
{
"id": "89e6932d-e4a1-494c-8fac-c763ce46513a",
"name": "便签5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2704,
128
],
"parameters": {
"color": 4,
"width": 544,
"height": 944,
"content": "# 阶段0:设置与配置"
},
"typeVersion": 1
},
{
"id": "f24fbe21-4f20-4349-837f-fda54fc844fb",
"name": "便签6",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2048,
656
],
"parameters": {
"color": 2,
"width": 1360,
"height": 464,
"content": "### 您需要做的:"
},
"typeVersion": 1
},
{
"id": "9a08f7ac-681f-40a2-9216-0f31628b98e4",
"name": "便签7",
"type": "n8n-nodes-base.stickyNote",
"position": [
-576,
992
],
"parameters": {
"color": 3,
"width": 1248,
"height": 368,
"content": "### 系统功能:"
},
"typeVersion": 1
},
{
"id": "e2c12fe5-a19f-461b-8293-e9947de3a487",
"name": "便签8",
"type": "n8n-nodes-base.stickyNote",
"position": [
848,
960
],
"parameters": {
"color": 5,
"width": 656,
"height": 384,
"content": "### 系统功能:"
},
"typeVersion": 1
},
{
"id": "07dbbd72-4d44-44e0-ad8e-8f3e0ef5b033",
"name": "便签3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1648,
352
],
"parameters": {
"color": 6,
"width": 656,
"height": 560,
"content": "# 阶段4:内容简报创建"
},
"typeVersion": 1
},
{
"id": "b0ed1638-8acd-4c70-aea2-0a0c4b1ea8ee",
"name": "内容简报",
"type": "@n8n/n8n-nodes-langchain.agent",
"maxTries": 5,
"position": [
1872,
432
],
"parameters": {
"text": "=[Site]: {{ $('Client Information').item.json['Client name'] }}({{ $('Client Information').item.json['Client information'] }})\n[Main keyword]: {{ $('Loop Over Items').item.json.Keyword }}\n[h1]: {{ $('Meta tag + h1').item.json.output.h1 }}\n[Description]: {{ $('Loop Over Items').item.json.Description }}\n[Awareness]: {{ $('Loop Over Items').item.json['Awareness level'] }}\n[Competitor info]:\nCompetitor 1:\n{{ $('Apify').item.json.organicResults[0].url }}\n{{ $('Titre 1').item.json.h1 }}\n{{ $('Titre 1').item.json.h2 }}\n{{ $('Titre 1').item.json.h3 }}\n{{ $('Titre 1').item.json.h4 }}\n{{ $('Titre 1').item.json.h5 }}\n{{ $('Titre 1').item.json.h6 }}\nCompetitor 2:\n{{ $('Apify').item.json.organicResults[1].url }}\n{{ $('Titre 2').item.json.h1 }}\n{{ $('Titre 2').item.json.h2 }}\n{{ $('Titre 2').item.json.h3 }}\n{{ $('Titre 2').item.json.h4 }}\n{{ $('Titre 2').item.json.h5 }}\n{{ $('Titre 2').item.json.h6 }}\nCompetitor 3:\n{{ $('Apify').item.json.organicResults[2].url }}\n{{ $('Titre 3').item.json.h1 }}\n{{ $('Titre 3').item.json.h2 }}\n{{ $('Titre 3').item.json.h3 }}\n{{ $('Titre 3').item.json.h4 }}\n{{ $('Titre 3').item.json.h5 }}\n{{ $('Titre 3').item.json.h6 }}\nCompetitor 4:\n{{ $('Apify').item.json.organicResults[3].url }}\n{{ $('Titre 4').item.json.h1 }}\n{{ $('Titre 4').item.json.h2 }}\n{{ $('Titre 4').item.json.h3 }}\n{{ $('Titre 4').item.json.h4 }}\n{{ $('Titre 4').item.json.h5 }}\n{{ $('Titre 4').item.json.h6 }}\nCompetitor 5:\n{{ $('Apify').item.json.organicResults[4].url }}\n{{ $('Titre 5').item.json.h1 }}\n{{ $('Titre 5').item.json.h2 }}\n{{ $('Titre 5').item.json.h3 }}\n{{ $('Titre 5').item.json.h4 }}\n{{ $('Titre 5').item.json.h5 }}\n{{ $('Titre 5').item.json.h6 }}\n[Page type]: {{ $('Loop Over Items').item.json['Type de page'] ? $('Loop Over Items').item.json['Type de page'] : '' }}\n[Client name]: {{ $('Client Information').item.json['Client name'] }}",
"options": {
"systemMessage": "# Rules\n\nI want to create an SEO content brief for a web page for the site [Site]. The main keyword I'm targeting is [Main keyword] and the h1 is the following [h1]. Here's a short description of the page [Description] And here's the awareness level that corresponds to the page [Awareness] Here's additional information about competitors positioning on this keyword, use this as inspiration to respond to the request [Competitor info]\n\n# Deliverables\n\nCan you provide a complete content brief including:\n\nPage type: [Page type]\nDetailed analysis of the search intent behind the main keyword (informational, transactional, navigational as percentages for each intent)\nStrategy to highlight the company in this content based on the main keyword\nRich media suggestions to integrate (images, videos, infographics, tables, etc.)\nDetailed MECE (Mutually Exclusive, Collectively Exhaustive) page structure with:\n\nthe h1 [h1]\nIntroduction\nH2 sections with key points for each section\nH3 subsections if necessary\n\n\nRecommended level of detail for writing on a scale of 1 to 10\n\nPlease ensure that the proposed structure is coherent, exhaustive, without redundancies, and optimized for SEO while remaining relevant for users.\nDo not write an introduction or conclusion to your response.\n\n# Tools\n\nYou have access to a RAG database with information about [Client name] to help you write the requested information as effectively as possible."
},
"promptType": "define"
},
"retryOnFail": true,
"typeVersion": 1.9,
"waitBetweenTries": 5000
},
{
"id": "a9554edf-3b91-4a27-a9b8-bdad45920583",
"name": "便签9",
"type": "n8n-nodes-base.stickyNote",
"position": [
1648,
960
],
"parameters": {
"color": 6,
"width": 656,
"height": 400,
"content": "### 系统功能:"
},
"typeVersion": 1
},
{
"id": "7141cb57-f915-47bf-83fb-1c6283bddcac",
"name": "便签10",
"type": "n8n-nodes-base.stickyNote",
"position": [
2416,
656
],
"parameters": {
"color": 7,
"width": 560,
"height": 416,
"content": "### 系统功能:"
},
"typeVersion": 1
},
{
"id": "4af149e0-c216-4075-9aab-9f6e27f6ddf5",
"name": "便签13",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1744,
-176
],
"parameters": {
"width": 816,
"height": 336,
"content": "## 需要更高级的自动化解决方案?联系我们获取定制企业工作流!"
},
"typeVersion": 1
}
],
"pinData": {
"When chat message received": [
{
"action": "sendMessage",
"chatInput": "t",
"sessionId": "bae7e54a70ab4df5a59a2f8841897496"
}
]
},
"connections": {
"If1": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
],
[]
]
},
"Code": {
"main": [
[
{
"node": "Update row in sheet",
"type": "main",
"index": 0
}
]
]
},
"Apify": {
"main": [
[
{
"node": "Scrape 1",
"type": "main",
"index": 0
}
]
]
},
"Filter1": {
"main": [
[
{
"node": "If1",
"type": "main",
"index": 0
}
]
]
},
"Titre 1": {
"main": [
[
{
"node": "Scrape 2",
"type": "main",
"index": 0
}
]
]
},
"Titre 2": {
"main": [
[
{
"node": "Scrape 3",
"type": "main",
"index": 0
}
]
]
},
"Titre 3": {
"main": [
[
{
"node": "Scrape 4",
"type": "main",
"index": 0
}
]
]
},
"Titre 4": {
"main": [
[
{
"node": "Scrape 5",
"type": "main",
"index": 0
}
]
]
},
"Titre 5": {
"main": [
[
{
"node": "Meta tag + h1",
"type": "main",
"index": 0
}
]
]
},
"Scrape 1": {
"main": [
[
{
"node": "Titre 1",
"type": "main",
"index": 0
}
]
]
},
"Scrape 2": {
"main": [
[
{
"node": "Titre 2",
"type": "main",
"index": 0
}
]
]
},
"Scrape 3": {
"main": [
[
{
"node": "Titre 3",
"type": "main",
"index": 0
}
]
]
},
"Scrape 4": {
"main": [
[
{
"node": "Titre 4",
"type": "main",
"index": 0
}
]
]
},
"Scrape 5": {
"main": [
[
{
"node": "Titre 5",
"type": "main",
"index": 0
}
]
]
},
"Content brief": {
"main": [
[
{
"node": "Code",
"type": "main",
"index": 0
}
]
]
},
"Meta tag + h1": {
"main": [
[
{
"node": "Content brief",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Items": {
"main": [
[],
[
{
"node": "Apify",
"type": "main",
"index": 0
}
]
]
},
"SEO information": {
"main": [
[
{
"node": "Filter1",
"type": "main",
"index": 0
}
]
]
},
"Embeddings OpenAI": {
"ai_embedding": [
[
{
"node": "Supabase Vector Store",
"type": "ai_embedding",
"index": 0
}
]
]
},
"Client Information": {
"main": [
[
{
"node": "SEO information",
"type": "main",
"index": 0
}
]
]
},
"Embeddings OpenAI2": {
"ai_embedding": [
[
{
"node": "Supabase Vector Store2",
"type": "ai_embedding",
"index": 0
}
]
]
},
"Update row in sheet": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Anthropic Chat Model": {
"ai_languageModel": [
[
{
"node": "Content brief",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Anthropic Chat Model2": {
"ai_languageModel": [
[
{
"node": "Meta tag + h1",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Supabase Vector Store": {
"ai_tool": [
[
{
"node": "Content brief",
"type": "ai_tool",
"index": 0
}
]
]
},
"Supabase Vector Store2": {
"ai_tool": [
[
{
"node": "Meta tag + h1",
"type": "ai_tool",
"index": 0
}
]
]
},
"Structured Output Parser2": {
"ai_outputParser": [
[
{
"node": "Meta tag + h1",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"When chat message received": {
"main": [
[
{
"node": "Client Information",
"type": "main",
"index": 0
}
]
]
}
}
}常见问题
如何使用这个工作流?
复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。
这个工作流适合什么场景?
高级 - 内容创作, 多模态 AI
需要付费吗?
本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。
相关工作流推荐
使用Claude AI和竞品分析的SEO内容生成器
使用Claude AI和Apify竞品分析生成SEO内容
If
Code
Filter
+9
36 节点Growth AI
内容创作
从Google Sheets生成SEO锚文本
使用Claude 4 Sonnet从Google Sheets生成SEO锚文本
Code
Filter
Google Sheets
+5
19 节点Growth AI
内容创作
在可视化参考库中探索n8n节点
在可视化参考库中探索n8n节点
If
Ftp
Set
+93
113 节点I versus AI
其他
使用Claude AI从Google Sheets到WordPress生成无障碍替代文本
使用Claude AI从Google Sheets到WordPress生成无障碍替代文本
If
Code
Http Request
+5
10 节点Growth AI
内容创作
使用 BOAMP API 和 Google Sheets 监控并筛选法国采购招标
使用 BOAMP API 和 Google Sheets 监控并筛选法国采购招标
If
Code
Wait
+7
55 节点Growth AI
内容创作
内容生成器 v3
AI驱动博客自动化:使用GPT-4生成并发布SEO文章至WordPress和Twitter
If
Set
Code
+25
144 节点Jay Emp0
内容创作