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": "DEV_RIO_702_X_Post_Prepare",
"nodes": [
{
"parameters": {},
"id": "b1a10702-0000-4000-8000-000000000001",
"name": "Manual Trigger",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [
-848,
0
]
},
{
"parameters": {
"jsCode": "// DEV_RIO_702 X(Twitter)\u6295\u7a3f\u3010\u4e0b\u66f8\u304d\u6e96\u5099\u306e\u307f\u30fbdry-run\u3011\u3002\n// DEV_RIO_103 \u306e\u51fa\u529b\u3092\u53d7\u3051\u53d6\u308b\u3002103\u306b\u306f title \u30d5\u30a3\u30fc\u30eb\u30c9\u304c\u7121\u3044\u305f\u3081 theme \u3092\u8a71\u984c\u30d2\u30f3\u30c8\u306b\u4f7f\u3046\u3002\n// qa_status \u304c\u7121\u3044\u624b\u52d5\u30c6\u30b9\u30c8\u6642\u306f 'PASS' \u6271\u3044\uff08\u5b9f\u30c1\u30a7\u30a4\u30f3\u3067\u306f103\u304c\u5fc5\u305a\u8a2d\u5b9a\u3059\u308b\uff09\u3002\nconst i = $input.first().json;\nreturn [{ json: {\n content_id: i.content_id ?? 'ca-x-001',\n theme: i.theme ?? '\uff08\u30c6\u30fc\u30de\u672a\u8a2d\u5b9a\uff09',\n note_body: i.note_body ?? i.note_draft_body ?? '',\n threads_post: i.threads_post ?? '',\n qa_status: i.qa_status ?? 'PASS',\n platform: 'x',\n action_type: 'prepare_x_drafts'\n} }];"
},
"id": "b1a10702-0000-4000-8000-000000000002",
"name": "Collect Inputs",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-624,
0
]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "loose"
},
"conditions": [
{
"id": "gate-qa-pass",
"leftValue": "={{ $json.qa_status }}",
"rightValue": "PASS",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"id": "b1a10702-0000-4000-8000-000000000003",
"name": "QA Gate (PASS only)",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
-400,
0
]
},
{
"parameters": {
"jsCode": "// X\u6295\u7a3f\u306e\u4e0b\u66f8\u304d\u751f\u6210\u30d7\u30ed\u30f3\u30d7\u30c8\u3092 Anthropic body \u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3068\u3057\u3066\u7d44\u307f\u7acb\u3066\u308b\u3002\n// \u30c6\u30ad\u30b9\u30c8\u306fJS\u6587\u5b57\u5217\u306b\u5b89\u5168\u306b\u57cb\u3081\u8fbc\u3080\uff08jsonBody\u3078\u306e\u76f4\u63a5\u6587\u5b57\u5217\u88dc\u9593\u306f\u58ca\u308c\u3084\u3059\u3044\u305f\u3081\u56de\u907f\uff09\u3002\nconst i = $input.first().json;\nconst excerpt = String(i.note_body || '').slice(0, 500);\nconst prompt = `\u4ee5\u4e0b\u306e\u8a18\u4e8b\u304b\u3089\u3001X(Twitter)\u6295\u7a3f\u306e\u4e0b\u66f8\u304d\u30923\u30d1\u30bf\u30fc\u30f3\u4f5c\u6210\u3057\u3066\u304f\u3060\u3055\u3044\u3002\\n\\n\u30c6\u30fc\u30de: ${i.theme}\\n\u672c\u6587\u629c\u7c8b: ${excerpt}\\n\\n\u6761\u4ef6:\\n- \u5404140\u5b57\u4ee5\u5185\u3001\u65e5\u672c\u8a9e\u3002\\n- \u30cf\u30c3\u30b7\u30e5\u30bf\u30b02\u301c3\u500b\u3002\\n- \u8a87\u5f35\u30fb\u865a\u507d\u306e\u6570\u5024\u30fb\u65ad\u5b9a\u7684\u306a\u6210\u679c\u4fdd\u8a3c\u306f\u7981\u6b62\u3002\\n- \u51fa\u529b\u306f\u6b21\u306eJSON\u914d\u5217\u306e\u307f\uff08\u524d\u5f8c\u306b\u8aac\u660e\u30fb\u30b3\u30fc\u30c9\u30d6\u30ed\u30c3\u30af\u8a18\u53f7\u3092\u4ed8\u3051\u306a\u3044\uff09:\\n[{\"angle\":\"string\",\"text\":\"string\"}]`;\nconst anthropic_body = {\n model: 'claude-haiku-4-5',\n max_tokens: 1024,\n messages: [ { role: 'user', content: prompt } ]\n};\nreturn [{ json: { ...i, anthropic_body } }];"
},
"id": "b1a10702-0000-4000-8000-000000000004",
"name": "Build X Prompt",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-176,
-112
]
},
{
"parameters": {
"method": "POST",
"url": "https://api.anthropic.com/v1/messages",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "anthropicApi",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "anthropic-version",
"value": "2023-06-01"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ $json.anthropic_body }}",
"options": {
"timeout": 30000
}
},
"id": "b1a10702-0000-4000-8000-000000000005",
"name": "Generate X Drafts (Claude)",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
48,
-112
],
"credentials": {
"anthropicApi": {
"name": "<your credential>"
}
},
"continueOnFail": true
},
{
"parameters": {
"jsCode": "// Claude\u5fdc\u7b54\u3092\u30d1\u30fc\u30b9\u3002\u5931\u6557\u6642\u306f\u634f\u9020\u305b\u305a parse_error \u3092\u660e\u793a\u3002\u51aa\u7b49\u6027\u30ad\u30fc\u4ed8\u4e0e\u3002\u516c\u958b\u76f4\u524d\u3067\u505c\u6b62\u3002\nconst input = $input.first().json;\nconst ctx = $('Collect Inputs').first().json;\nlet drafts = [];\nlet parse_error = null;\nif (input.error) {\n parse_error = 'anthropic_api_error: ' + JSON.stringify(input.error).slice(0, 300);\n} else {\n try {\n const text = input.content && input.content[0] && input.content[0].text;\n if (!text) throw new Error('no text in response');\n const cleaned = text.trim().replace(/^```json\\s*/i, '').replace(/```\\s*$/, '');\n const match = cleaned.match(/\\[[\\s\\S]*\\]/);\n drafts = JSON.parse(match ? match[0] : cleaned);\n if (!Array.isArray(drafts) || drafts.length === 0) throw new Error('drafts missing/empty');\n drafts = drafts.map(d => ({ angle: d.angle ?? '', text: d.text ?? '' }));\n } catch (e) {\n parse_error = 'parse_failed: ' + e.message;\n }\n}\nif (parse_error) drafts = [{ angle: 'manual', text: '\uff08AI\u5fdc\u7b54\u306e\u53d6\u5f97/\u89e3\u6790\u306b\u5931\u6557\u3002\u624b\u52d5\u3067\u4e0b\u66f8\u304d\u3092\u4f5c\u6210\u3057\u3066\u304f\u3060\u3055\u3044\uff09' }];\nconst idempotency_key = [ctx.platform, ctx.content_id, ctx.action_type].join('|');\nreturn [{ json: {\n content_id: ctx.content_id,\n platform: 'x',\n drafts,\n draft_count: drafts.length,\n idempotency_key,\n state: 'WAITING_APPROVAL',\n published: false,\n draft_error: parse_error,\n note: 'dry-run\u3002X\u6295\u7a3f\u306e\u4e0b\u66f8\u304d\u5019\u88dc\u306e\u307f\u751f\u6210\u3002\u2605\u81ea\u52d5\u6295\u7a3f\u306f\u3057\u306a\u3044\u3002\u4eba\u9593\u304c\u5185\u5bb9\u3092\u78ba\u8a8d\u3057\u3001\u554f\u984c\u306a\u3051\u308c\u3070\u624b\u52d5\u3067X\u306b\u6295\u7a3f\u3059\u308b\uff08CLAUDE.md \u6e96\u62e0\uff09\u3002'\n} }];"
},
"id": "b1a10702-0000-4000-8000-000000000006",
"name": "Stop Before Publish",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
272,
-112
]
},
{
"parameters": {},
"id": "b1a10702-0000-4000-8000-000000000007",
"name": "Result (drafts only, no publish)",
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [
496,
-112
]
},
{
"parameters": {
"jsCode": "// QA\u30b2\u30fc\u30c8\u4e0d\u901a\u904e\uff08qa_status != PASS\uff09\u3002\u4e0b\u66f8\u304d\u751f\u6210\u3092\u30b9\u30ad\u30c3\u30d7\u3002\nconst i = $input.first().json;\nreturn [{ json: {\n content_id: i.content_id,\n platform: 'x',\n skipped: true,\n qa_status: i.qa_status,\n state: 'SKIPPED_NOT_PASS',\n published: false,\n note: 'qa_status \u304c PASS \u3067\u306f\u306a\u3044\u305f\u3081 X\u4e0b\u66f8\u304d\u751f\u6210\u3092\u30b9\u30ad\u30c3\u30d7\uff08\u54c1\u8cea\u672a\u9054\u30b3\u30f3\u30c6\u30f3\u30c4\u306f\u914d\u5e03\u6e96\u5099\u3057\u306a\u3044\uff09\u3002'\n} }];"
},
"id": "b1a10702-0000-4000-8000-000000000008",
"name": "Skip (not PASS)",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-176,
176
]
}
],
"connections": {
"Manual Trigger": {
"main": [
[
{
"node": "Collect Inputs",
"type": "main",
"index": 0
}
]
]
},
"Collect Inputs": {
"main": [
[
{
"node": "QA Gate (PASS only)",
"type": "main",
"index": 0
}
]
]
},
"QA Gate (PASS only)": {
"main": [
[
{
"node": "Build X Prompt",
"type": "main",
"index": 0
}
],
[
{
"node": "Skip (not PASS)",
"type": "main",
"index": 0
}
]
]
},
"Build X Prompt": {
"main": [
[
{
"node": "Generate X Drafts (Claude)",
"type": "main",
"index": 0
}
]
]
},
"Generate X Drafts (Claude)": {
"main": [
[
{
"node": "Stop Before Publish",
"type": "main",
"index": 0
}
]
]
},
"Stop Before Publish": {
"main": [
[
{
"node": "Result (drafts only, no publish)",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
},
"active": false,
"meta": {
"description": "DEV_RIO_702 X Post Prepare. dry-run. qa_status=PASS \u306e\u3068\u304d\u306e\u307f Claude \u3067 X\u6295\u7a3f\u4e0b\u66f8\u304d3\u6848\u3092\u751f\u6210\u3057\u516c\u958b\u76f4\u524d\u3067\u505c\u6b62\u3002NEVER publish/activate. \u81ea\u52d5\u6295\u7a3f\u306f\u3057\u306a\u3044\uff08CLAUDE.md \u6e96\u62e0\uff09\u3002\u4eba\u9593\u304c\u78ba\u8a8d\u5f8c\u3001\u624b\u52d5\u6295\u7a3f\u3002"
},
"tags": [
{
"name": "DEV"
},
{
"name": "RIO"
},
{
"name": "X"
}
]
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
anthropicApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
DEV_RIO_702_X_Post_Prepare. Uses httpRequest. Event-driven trigger; 8 nodes.
Source: https://gist.github.com/YuuTKD/3339e39eae796b476df4bff79809e5db — 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.
This n8n workflow automatically shares content from a Telegram Channel to multiple platforms like WordPress, Facebook, X/Twitter, and LinkedIn. It uses a Switch node to detect the type of content—text
Hacker News to Video Template - AlexK1919. Uses hackerNews, s3, httpRequest, dropbox. Event-driven trigger; 48 nodes.
Disclaimer: this workflow only works on self-hosted instances due to the file system usage.
More workflow: https://aitool.wiki/
> ⚠️ Disclaimer: This workflow uses Community Nodes and requires a self-hosted n8n instance.