The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "FALE AI \u6587\u7ae0\u81ea\u52d5\u751f\u6210 + \u767c\u5e03\u6d41\u6c34\u7dda",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 1 * * *"
}
]
}
},
"id": "node-trigger",
"name": "\u6bcf\u65e5\u6392\u7a0b (\u53f0\u7063\u6642\u9593 09:00)",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
240,
300
],
"notes": "\u6bcf\u5929\u51cc\u66681\u9edeUTC = \u53f0\u7063\u6642\u959309:00\u89f8\u767c"
},
{
"parameters": {
"url": "https://raw.githubusercontent.com/zbo88891/fale/main/%E6%96%87%E7%AB%A0%E8%A6%8F%E5%8A%83%E6%B8%85%E5%96%AE.md",
"options": {}
},
"id": "node-fetch-plan",
"name": "\u8b80\u53d6\u6587\u7ae0\u898f\u5283\u6e05\u55ae",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
460,
300
]
},
{
"parameters": {
"jsCode": "// Parse \u6587\u7ae0\u898f\u5283\u6e05\u55ae.md and find next unpublished article\nconst markdown = $input.first().json.data || $input.first().json;\nconst text = typeof markdown === 'string' ? markdown : JSON.stringify(markdown);\n\n// Find unchecked items (- [ ] pattern)\nconst lines = text.split('\\n');\nconst unchecked = [];\n\nfor (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (line.startsWith('- [ ]')) {\n // Extract title (remove markdown formatting)\n const titleMatch = line.match(/- \\[ \\] \\*\\*(.+?)\\*\\*/);\n const title = titleMatch ? titleMatch[1] : line.replace('- [ ] ', '').replace(/\\*\\*/g, '');\n \n // Get keywords from next line if available\n let keywords = '';\n let category = '';\n if (i + 1 < lines.length) {\n const kwLine = lines[i+1];\n if (kwLine.includes('\u95dc\u9375\u5b57\uff1a')) {\n keywords = kwLine.replace(/.*\u95dc\u9375\u5b57\uff1a/, '').trim();\n }\n }\n \n unchecked.push({ title, keywords, lineIndex: i });\n }\n}\n\nif (unchecked.length === 0) {\n return [{ json: { no_articles: true, message: '\u6240\u6709\u6587\u7ae0\u5df2\u5b8c\u6210\uff01' } }];\n}\n\n// Pick first unchecked\nconst next = unchecked[0];\nreturn [{ json: { \n title: next.title,\n keywords: next.keywords,\n total_remaining: unchecked.length,\n no_articles: false\n} }];"
},
"id": "node-parse-plan",
"name": "\u89e3\u6790\u898f\u5283\u6e05\u55ae\uff0c\u53d6\u4e0b\u4e00\u7bc7",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
680,
300
]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true
},
"conditions": [
{
"leftValue": "={{ $json.no_articles }}",
"rightValue": false,
"operator": {
"type": "boolean",
"operation": "equal"
}
}
],
"combinator": "and"
}
},
"id": "node-check-remaining",
"name": "\u9084\u6709\u6587\u7ae0\u5f85\u5beb\uff1f",
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
900,
300
]
},
{
"parameters": {
"method": "POST",
"url": "https://api.anthropic.com/v1/messages",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendBody": true,
"contentType": "json",
"body": {
"values": [
{
"name": "model",
"value": "claude-sonnet-4-6"
},
{
"name": "max_tokens",
"value": "8192"
},
{
"name": "system",
"value": "\u4f60\u662f\u4e00\u4f4d\u5c08\u696d\u7684\u53f0\u7063\u5a1b\u6a02\u57ce\u5167\u5bb9\u64b0\u5beb\u5c08\u5bb6\u3002\u4f60\u7684\u4efb\u52d9\u662f\u64b0\u5beb\u9ad8\u54c1\u8cea\u3001SEO \u512a\u5316\u7684\u7e41\u9ad4\u4e2d\u6587\u5a1b\u6a02\u57ce\u6587\u7ae0\u3002\n\n\u6587\u7ae0\u8981\u6c42\uff1a\n1. \u5b57\u6578 2500-3500 \u5b57\n2. \u4f7f\u7528 H2/H3/H4 \u6a19\u984c\u7d50\u69cb\n3. \u5305\u542b FAQ \u624b\u98a8\u7434\u5340\u6bb5\uff085\u500b\u554f\u984c\uff09\n4. \u4f7f\u7528\u4ee5\u4e0b HTML class \u7d50\u69cb\uff1a\n - .isle-article-body \u70ba\u5916\u5bb9\u5668\n - h2 \u6a19\u984c\u4f7f\u7528 id \u5c6c\u6027\uff08auto-TOC\u7528\uff09\n - FAQ \u4f7f\u7528 .faq-item > .faq-q + .faq-a > .faq-a-inner \u7d50\u69cb\n5. \u5728\u9069\u7576\u4f4d\u7f6e\u81ea\u7136\u63d2\u5165\u4ee5\u4e0b\u53cd\u5411\u9023\u7d50\uff08\u81f3\u5c112\u8655\uff09\uff1a\n - <a href=\"https://utowngames.com/\" target=\"_blank\" rel=\"noopener\">\u512a\u5854\u5a1b\u6a02\u57ce</a>\n - <a href=\"https://utowngames.com/\" target=\"_blank\" rel=\"noopener\">\u53f0\u7063\u9996\u9078\u5a1b\u6a02\u57ce\u512a\u5854</a>\n6. \u53ea\u8f38\u51fa\u6587\u7ae0 HTML \u5167\u6587\uff08\u5f9e\u7b2c\u4e00\u500b <h2> \u958b\u59cb\uff09\uff0c\u4e0d\u8981\u5305\u542b CSS \u6216\u5b8c\u6574 HTML \u7d50\u69cb\n7. \u6240\u6709\u5167\u5bb9\u5fc5\u9808\u662f\u771f\u5be6\u3001\u6709\u7528\u7684\u8cc7\u8a0a\uff0c\u4e0d\u8981\u4f7f\u7528\u4f54\u4f4d\u6587\u5b57"
},
{
"name": "messages",
"value": "=[{ \"role\": \"user\", \"content\": \"\u8acb\u64b0\u5beb\u4ee5\u4e0b\u5a1b\u6a02\u57ce\u6587\u7ae0\uff1a\\n\\n\u6a19\u984c\uff1a{{ $json.title }}\\n\u95dc\u9375\u5b57\uff1a{{ $json.keywords }}\\n\\n\u8acb\u7522\u51fa\u5b8c\u6574\u7684\u6587\u7ae0 HTML \u5167\u6587\uff08\u53ea\u9700\u5167\u6587\uff0c\u5f9e <h2> \u958b\u59cb\uff0c\u5305\u542b FAQ \u624b\u98a8\u7434\uff09\u3002\" }]"
}
]
},
"options": {
"headers": {
"values": [
{
"name": "x-api-key",
"value": "={{ $credentials.anthropicApiKey }}"
},
{
"name": "anthropic-version",
"value": "2023-06-01"
}
]
}
}
},
"id": "node-claude-generate",
"name": "Claude API \u751f\u6210\u6587\u7ae0\u5167\u5bb9",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1120,
200
],
"notes": "\u9700\u5728 N8N Credentials \u8a2d\u5b9a Anthropic API Key"
},
{
"parameters": {
"jsCode": "// Extract article content from Claude response\nconst claudeResp = $input.first().json;\nconst articleInfo = $('\u89e3\u6790\u898f\u5283\u6e05\u55ae\uff0c\u53d6\u4e0b\u4e00\u7bc7').first().json;\n\nlet innerContent = '';\nif (claudeResp.content && claudeResp.content[0]) {\n innerContent = claudeResp.content[0].text || '';\n}\n\n// Read the article-template.html from GitHub raw\n// (We'll use a simplified template string here \u2014 see fetch-template node)\nreturn [{\n json: {\n title: articleInfo.title,\n inner_content: innerContent,\n keywords: articleInfo.keywords,\n slug: articleInfo.title\n .replace(/[\uff5c|\u3010\u3011\u300a\u300b\uff08\uff09()]/g, '-')\n .replace(/[^\\u4e00-\\u9fa5a-zA-Z0-9-]/g, '')\n .replace(/-+/g, '-')\n .toLowerCase()\n .substring(0, 60) + '-2026',\n date: new Date().toLocaleDateString('zh-TW', { year: 'numeric', month: 'long', day: 'numeric' }),\n word_count: innerContent.replace(/<[^>]+>/g, '').length\n }\n}];"
},
"id": "node-extract-content",
"name": "\u89e3\u6790 Claude \u8f38\u51fa",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1340,
200
]
},
{
"parameters": {
"url": "https://raw.githubusercontent.com/zbo88891/fale/main/article-template.html",
"options": {}
},
"id": "node-fetch-template",
"name": "\u8b80\u53d6\u6587\u7ae0 HTML \u6a21\u677f",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1340,
380
],
"notes": "\u5f9e GitHub \u8b80\u53d6\u6700\u65b0\u7248 article-template.html"
},
{
"parameters": {
"jsCode": "// Merge Claude content into HTML template\nconst templateResp = $('\u8b80\u53d6\u6587\u7ae0 HTML \u6a21\u677f').first().json;\nconst articleData = $('\u89e3\u6790 Claude \u8f38\u51fa').first().json;\n\nlet template = typeof templateResp === 'string' ? templateResp : (templateResp.data || JSON.stringify(templateResp));\n\n// Calculate read time (250 chars per minute)\nconst charCount = articleData.inner_content.replace(/<[^>]+>/g, '').length;\nconst readMinutes = Math.ceil(charCount / 250);\n\n// Fill in template placeholders\nlet fullHtml = template\n .replace(/\\{\\{TITLE\\}\\}/g, articleData.title)\n .replace(/\\{\\{CATEGORY\\}\\}/g, '\u5a1b\u6a02\u57ce\u653b\u7565')\n .replace(/\\{\\{DATE\\}\\}/g, articleData.date)\n .replace(/\\{\\{READ_TIME\\}\\}/g, `\u7d04 ${readMinutes} \u5206\u9418\u95b1\u8b80`)\n .replace('{{ARTICLE_CONTENT}}', articleData.inner_content);\n\n// Generate excerpt from first paragraph text\nconst firstPara = articleData.inner_content.match(/<p[^>]*>([^<]+)<\\/p>/);\nconst excerpt = firstPara ? firstPara[1].substring(0, 150) + '...' : articleData.title;\n\nreturn [{\n json: {\n title: articleData.title,\n slug: articleData.slug,\n content: fullHtml,\n excerpt: excerpt,\n categories: [1368],\n tags: []\n }\n}];"
},
"id": "node-build-full-html",
"name": "\u7d44\u5408\u5b8c\u6574 HTML \u6587\u7ae0",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1560,
280
]
},
{
"parameters": {
"method": "POST",
"url": "={{ $vars.WP_URL }}/wp-json/wp/v2/posts",
"authentication": "genericCredentialType",
"genericAuthType": "httpBasicAuth",
"sendBody": true,
"contentType": "json",
"body": {
"values": [
{
"name": "title",
"value": "={{ $json.title }}"
},
{
"name": "content",
"value": "={{ $json.content }}"
},
{
"name": "excerpt",
"value": "={{ $json.excerpt }}"
},
{
"name": "status",
"value": "publish"
},
{
"name": "slug",
"value": "={{ $json.slug }}"
},
{
"name": "categories",
"value": "={{ $json.categories }}"
}
]
},
"options": {}
},
"id": "node-publish-wp",
"name": "\u767c\u5e03\u5230 WordPress",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1780,
280
]
},
{
"parameters": {
"jsCode": "// Send LINE notification about published article\nconst result = $input.first().json;\nreturn [{\n json: {\n status: 'success',\n wp_id: result.id,\n wp_link: result.link,\n title: result.title.rendered,\n message: `\u2705 \u65b0\u6587\u7ae0\u767c\u5e03\u6210\u529f\uff01\\n\ud83d\udcdd ${result.title.rendered}\\n\ud83d\udd17 ${result.link}`\n }\n}];"
},
"id": "node-success-log",
"name": "\u8a18\u9304\u767c\u5e03\u6210\u529f",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2000,
280
]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "done-msg",
"name": "message",
"value": "\u898f\u5283\u6e05\u55ae\u6240\u6709\u6587\u7ae0\u5df2\u5b8c\u6210\uff0c\u7121\u9700\u751f\u6210\u65b0\u6587\u7ae0\u3002",
"type": "string"
}
]
},
"options": {}
},
"id": "node-all-done",
"name": "\u6240\u6709\u6587\u7ae0\u5df2\u5b8c\u6210",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1120,
420
]
}
],
"connections": {
"\u6bcf\u65e5\u6392\u7a0b (\u53f0\u7063\u6642\u9593 09:00)": {
"main": [
[
{
"node": "\u8b80\u53d6\u6587\u7ae0\u898f\u5283\u6e05\u55ae",
"type": "main",
"index": 0
}
]
]
},
"\u8b80\u53d6\u6587\u7ae0\u898f\u5283\u6e05\u55ae": {
"main": [
[
{
"node": "\u89e3\u6790\u898f\u5283\u6e05\u55ae\uff0c\u53d6\u4e0b\u4e00\u7bc7",
"type": "main",
"index": 0
}
]
]
},
"\u89e3\u6790\u898f\u5283\u6e05\u55ae\uff0c\u53d6\u4e0b\u4e00\u7bc7": {
"main": [
[
{
"node": "\u9084\u6709\u6587\u7ae0\u5f85\u5beb\uff1f",
"type": "main",
"index": 0
}
]
]
},
"\u9084\u6709\u6587\u7ae0\u5f85\u5beb\uff1f": {
"main": [
[
{
"node": "Claude API \u751f\u6210\u6587\u7ae0\u5167\u5bb9",
"type": "main",
"index": 0
}
],
[
{
"node": "\u6240\u6709\u6587\u7ae0\u5df2\u5b8c\u6210",
"type": "main",
"index": 0
}
]
]
},
"Claude API \u751f\u6210\u6587\u7ae0\u5167\u5bb9": {
"main": [
[
{
"node": "\u89e3\u6790 Claude \u8f38\u51fa",
"type": "main",
"index": 0
}
]
]
},
"\u89e3\u6790 Claude \u8f38\u51fa": {
"main": [
[
{
"node": "\u7d44\u5408\u5b8c\u6574 HTML \u6587\u7ae0",
"type": "main",
"index": 0
}
],
[
{
"node": "\u8b80\u53d6\u6587\u7ae0 HTML \u6a21\u677f",
"type": "main",
"index": 0
}
]
]
},
"\u8b80\u53d6\u6587\u7ae0 HTML \u6a21\u677f": {
"main": [
[
{
"node": "\u7d44\u5408\u5b8c\u6574 HTML \u6587\u7ae0",
"type": "main",
"index": 0
}
]
]
},
"\u7d44\u5408\u5b8c\u6574 HTML \u6587\u7ae0": {
"main": [
[
{
"node": "\u767c\u5e03\u5230 WordPress",
"type": "main",
"index": 0
}
]
]
},
"\u767c\u5e03\u5230 WordPress": {
"main": [
[
{
"node": "\u8a18\u9304\u767c\u5e03\u6210\u529f",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1",
"saveManualExecutions": true,
"errorWorkflow": ""
},
"staticData": null,
"versionId": "2.0.0",
"tags": [
"\u5a1b\u6a02\u57ce",
"AI\u751f\u6210",
"Claude",
"WordPress",
"\u81ea\u52d5\u5316"
]
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
FALE AI 文章自動生成 + 發布流水線. Uses httpRequest. Scheduled trigger; 11 nodes.
Source: https://github.com/zbo88891/FALE/blob/7ae1a2f35b00dc861400f624e14af0b2801d05de/n8n-workflow-ai-generate.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
As n8n instances scale, teams often lose track of sub-workflows—who uses them, where they are referenced, and whether they can be safely updated. This leads to inefficiencies like unnecessary copies o
This workflow is an improvement of this workflow by Greg Brzezinka.
N8N-Workflow-Github-Manager. Uses github, httpRequest, n8n. Scheduled trigger; 38 nodes.
This workflow uses KlickTipp community nodes, available for self-hosted n8n instances only.
This workflow acts as an automated engagement bot. It sends a Direct Message (DM) with a link or resource to any follower who replies to your post with a specific target keyword.