AutomationFlowsAI & RAG › Generate Sora V2 Asmr Clips with Gpt-5.1, Stitch via Cloudinary, and Post to…

Generate Sora V2 Asmr Clips with Gpt-5.1, Stitch via Cloudinary, and Post to…

Original n8n title: Generate Sora V2 Asmr Clips with Gpt-5.1, Stitch via Cloudinary, and Post to Twitter/x

BySona Labs @sona on n8n.io

Generate creative ASMR cutting video concepts with GPT-5.1, create high-quality video clips using Sora v2, stitch them together with Cloudinary, and automatically post to Twitter/X—transforming ideas into viral content without manual video editing.

Cron / scheduled trigger★★★★★ complexityAI-powered35 nodesOpenAI ChatHTTP RequestAgentGoogle SheetsOutput Parser StructuredTool Think
AI & RAG Trigger: Cron / scheduled Nodes: 35 Complexity: ★★★★★ AI nodes: yes Added:

This workflow corresponds to n8n.io template #12590 — we link there as the canonical source.

This workflow follows the Agent → Google Sheets recipe pattern — see all workflows that pair these two integrations.

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 →

Download .json
{
  "id": "83RE6WgpOoBn579G",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Generate Sora videos, stitch clips, and post to Twitter",
  "tags": [],
  "nodes": [
    {
      "id": "902b0773-3a03-4c88-a96d-7e7c500f7f59",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        192,
        -496
      ],
      "parameters": {
        "rule": {
          "interval": [
            {}
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "bea43757-3df7-4e7b-8eec-cb3459e1e4ec",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        656,
        -304
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-5.1",
          "cachedResultName": "gpt-5.1"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "fc8f6a3d-82ae-400c-aadb-740d0337a5d1",
      "name": "Check Video Status",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        672,
        240
      ],
      "parameters": {
        "url": "=https://api.openai.com/v1/videos/{{ $json.id }}",
        "options": {
          "response": {
            "response": {}
          }
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE KEY"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "697af730-8922-4c13-ab54-51dc003129fd",
      "name": "Download Completed Video",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueRegularOutput",
      "position": [
        1280,
        400
      ],
      "parameters": {
        "url": "=https://api.openai.com/v1/videos/{{ $json.id }}/content",
        "options": {
          "batching": {
            "batch": {
              "batchSize": 1,
              "batchInterval": 3000
            }
          },
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE KEY"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "1307f27d-c275-439d-a270-0b6606b4bfc0",
      "name": "Create Sora Video Scene - 1",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2128,
        -624
      ],
      "parameters": {
        "url": "https://api.openai.com/v1/videos",
        "method": "POST",
        "options": {
          "batching": {
            "batch": {
              "batchSize": 1,
              "batchInterval": 3000
            }
          }
        },
        "jsonBody": "={\n  \"model\": \"sora-2\",\n  \"prompt\": \"WHAT HAPPENS IN THE VIDEO: {{ $json['Scene 1'].replace(/\\n/g, ' ').replace(/\"/g, '\\\\\"') }} | SOUND: {{ $('ASMR Cutting Ideas').first().json.output.Clip_1.Sound.replace(/\\n/g, ' ').replace(/\"/g, '\\\\\"') }}\",\n  \"size\": \"720x1280\",\n  \"seconds\": \"{{ $('ASMR Cutting Ideas').first().json.output.Clip_1.Duration }}\"\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE KEY"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "5832b5c4-e590-462d-bafb-f3b6d4656d4d",
      "name": "Create Sora Video Scene - 2",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2128,
        -448
      ],
      "parameters": {
        "url": "https://api.openai.com/v1/videos",
        "method": "POST",
        "options": {
          "batching": {
            "batch": {
              "batchSize": 1,
              "batchInterval": 3000
            }
          }
        },
        "jsonBody": "={\n  \"model\": \"sora-2\",\n  \"prompt\": \"WHAT HAPPENS IN THE VIDEO: {{ $json['Scene 2'].replace(/\\n/g, ' ').replace(/\"/g, '\\\\\"') }} | SOUND: {{ $('ASMR Cutting Ideas').first().json.output.Clip_2.Sound.replace(/\\n/g, ' ').replace(/\"/g, '\\\\\"') }}\",\n  \"size\": \"720x1280\",\n  \"seconds\": \"{{ $('ASMR Cutting Ideas').first().json.output.Clip_2.Duration }}\"\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE KEY"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "6d52c7cc-f5fe-43e2-a104-1e9cee2bce87",
      "name": "Create Sora Video Scene - 3",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2128,
        -272
      ],
      "parameters": {
        "url": "https://api.openai.com/v1/videos",
        "method": "POST",
        "options": {
          "batching": {
            "batch": {
              "batchSize": 1,
              "batchInterval": 3000
            }
          }
        },
        "jsonBody": "={\n  \"model\": \"sora-2\",\n  \"prompt\": \"WHAT HAPPENS IN THE VIDEO: {{ $json['Scene 3'].replace(/\\n/g, ' ').replace(/\"/g, '\\\\\"') }} | SOUND: {{ $('ASMR Cutting Ideas').first().json.output.Clip_3.Sound.replace(/\\n/g, ' ').replace(/\"/g, '\\\\\"') }}\",\n  \"size\": \"720x1280\",\n  \"seconds\": \"{{ $('ASMR Cutting Ideas').first().json.output.Clip_3.Duration }}\"\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE KEY"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "875be6c5-2f6a-4986-a2b1-953a0c23a294",
      "name": "Upload to Cloudinary",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1456,
        400
      ],
      "parameters": {
        "url": "https://api.cloudinary.com/v1_1/{Cloud name here}/video/upload",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "contentType": "multipart-form-data",
        "sendHeaders": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "file",
              "parameterType": "formBinaryData",
              "inputDataFieldName": "data"
            },
            {
              "name": "upload_preset",
              "value": "n8n_integration"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "multipart/form-data"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "f4ac4a16-c506-4678-91b2-219b4b9006ef",
      "name": "Wait 30s for Rendering",
      "type": "n8n-nodes-base.wait",
      "position": [
        496,
        240
      ],
      "parameters": {
        "amount": 30
      },
      "typeVersion": 1.1
    },
    {
      "id": "2315522b-7fc1-4337-9520-0b34958f2cca",
      "name": "ASMR Cutting Ideas",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        704,
        -496
      ],
      "parameters": {
        "text": "=Review and adjust the output using the Think tool.",
        "options": {
          "systemMessage": "=You are an ASMR cutting content creator for TikTok/Reels/Shorts specializing in cutting UNUSUAL and UNEXPECTED objects.\n\nGenerate 3 weird/unusual objects to cut with video prompts and a Twitter post caption.\n\n---\n\n## Weird Object Guidelines:\n\nThink of bizarre, unexpected things that can be sliced/cut (even if unconventional):\n- Glass/crystal versions of everyday objects (glass avocado, crystal fruit, glass food replicas)\n- Blocks of unusual materials (lava rock, salt blocks, soap stones, compressed charcoal)\n- Edible items in extreme forms (giant gummy bears, frozen honey, layered soap bars)\n- Synthetic replicas (resin castings, wax sculptures, foam blocks shaped like objects)\n- Natural formations (geodes, pumice, chalk blocks, kinetic sand cakes)\n- Unconventional cuttables (candles shaped like objects, ice sculptures, layered materials)\n\n**Be creative!** The weirder and more satisfying the cut, the better for virality.\n\n---\n\n## Video Structure Rules:\n\n**SINGLE STATIC FRONTAL/SLIGHT-ANGLE VIEW - NO camera movement**\n- Camera positioned directly facing the cutting action at eye level\n- Shows hands from front, holding object steady while knife approaches\n- Object held in hands or resting on cutting board in front view\n- Focus on blade contact point and material response as knife cuts toward camera\n- One continuous shot from start to finish\n\n**Framing (CRITICAL):**\n- **Frontal view or slight angle** (NOT side-profile)\n- Camera facing the object and cutting action directly\n- Shows knife blade cutting TOWARD the camera/viewer\n- Clear view of hands gripping object from front, knife approaching from top or front\n- Object centered in frame with hands visible on sides\n- Similar perspective to the reference image (dragon fruit cutting)\n\n**Action Requirements:**\n- **Knife MUST actually cut through the object**\n- Blade approaches from top/front and cuts downward or toward camera\n- Show blade making contact and slicing through\n- Material must visibly react (split, crack, reveal interior)\n\n**Action Limits:**\n- **8 seconds = 3 actions MAX** (Setup \u2192 Blade contacts \u2192 Material splits)\n- **12 seconds = 4 actions MAX** (Object positioned \u2192 Blade approaches \u2192 Cuts through \u2192 Interior revealed)\n\n---\n\n## Moderation-Safe Language:\n\n**\u2705 SAFE words:**\n- \"cutting,\" \"slicing,\" \"blade,\" \"knife,\" \"splitting\"\n- \"hands holding,\" \"object reacts,\" \"material breaks,\" \"interior reveals\"\n- Focus on object behavior and cutting action\n\n**\u274c AVOID:**\n- Body parts beyond \"hands\"\n- Any suggestive language\n\n---\n\n## JSON Safety Rules:\n\n- Use single quotes (') for emphasis, NOT double quotes (\")\n- Example: \"glass 'avocado'\" not \"glass \"avocado\"\"\n\n---\n\n## Twitter Caption Guidelines:\n\n- Keep it short and engaging (under 280 characters)\n- Include 2-3 relevant hashtags (#ASMR #Satisfying #OddlySatisfying)\n- Mention what's being cut in an intriguing way\n- Create curiosity or excitement\n- No emojis unless they enhance the message\n\n---\n\n## Output:\n```json\n{\n  \"Category\": \"ASMR_Cutting\",\n  \"Twitter_Text\": \"Engaging caption about the cutting video with relevant hashtags\",\n  \"Clip_1\": {\n    \"Prompt\": \"Static frontal shot at eye level showing hands holding [weird object] from the sides. Blade approaches from above and presses down through the center, cutting toward camera. [Material response - how it splits/cracks/reveals interior]. Natural lighting. Front-facing view showing knife, hands, and object splitting.\",\n    \"Sound\": \"Satisfying cutting sound (sharp crack / smooth slice / deep grind / brittle snap)\",\n    \"Duration\": 12\n  },\n  \"Clip_2\": {\n    \"Prompt\": \"Static front view of hands gripping [different weird object] at center frame. Knife blade slices downward through middle toward camera. [Material behavior - texture response, internal structure]. Simple lighting. Frontal angle shows cutting action clearly with hands on sides.\",\n    \"Sound\": \"Different cutting sound from Clip_1\",\n    \"Duration\": 8\n  },\n  \"Clip_3\": {\n    \"Prompt\": \"Static frontal angle showing hands holding [third weird object] steady. Knife blade cuts straight down through center toward viewer. [Object splits revealing unexpected interior/layers]. Natural background. Front-facing camera captures entire cutting motion with object centered.\",\n    \"Sound\": \"Unique cutting sound different from previous\",\n    \"Duration\": 12\n  }\n}\n\n## Example Output:\n```json\n{\n  \"Category\": \"ASMR_Cutting\",\n  \"Twitter_Text\": \"Ever wondered what happens when you cut through a glass avocado, volcanic lava rock, and rainbow soap? The sounds alone are worth it \ud83d\udd2a\u2728 #ASMR #OddlySatisfying #ASMRCutting\",\n  \"Clip_1\": {\n    \"Prompt\": \"Static side-profile shot showing hands holding translucent glass avocado on wooden cutting board. Chef's knife blade presses down from above at slight angle through smooth glass shell. Material cracks cleanly revealing layered green-tinted glass interior with amber glass 'pit' center. Natural lighting from side. Horizontal camera angle shows knife, hands, and splitting glass avocado.\",\n    \"Sound\": \"Sharp glass crack followed by smooth grinding and clean separation snap\",\n    \"Duration\": 12\n  },\n  \"Clip_2\": {\n    \"Prompt\": \"Static horizontal side view of rough black lava stone block on white surface. Hand stabilizes stone while serrated blade saws through from above. Stone crumbles revealing smooth gray interior with particles scattering. Side angle clearly shows blade penetrating volcanic texture and material response.\",\n    \"Sound\": \"Deep grinding with gritty scraping and final crack\",\n    \"Duration\": 8\n  },\n  \"Clip_3\": {\n    \"Prompt\": \"Static side-profile angle of layered rainbow soap block on board with hand holding it steady. Thin blade slices straight down through all colored layers. Soap separates smoothly showing perfect cross-section of pink, orange, yellow, green, blue stripes. Horizontal view captures entire slicing motion from side with natural lighting.\",\n    \"Sound\": \"Soft smooth slicing with slight sticky separation\",\n    \"Duration\": 12\n  }\n}\n```\n\n---\n\n## Rules:\n\n- 3 weird/unusual objects (be creative!)\n- Each prompt = 50-70 words\n- **Frontal / front-facing camera angle** (like reference image, NOT side-profile)\n- **Hands holding object from sides + knife cutting toward camera**\n- **NO camera movement** (static shot only)\n- **NO angle changes** (one frontal angle entire clip)\n- **Cutting action is MANDATORY**\n- **Knife cuts TOWARD camera, not away**\n- **Action limit: 3 for 8s, 4 for 12s**\n- Focus on object's material response\n- Different satisfying sounds\n- Duration: 8 or 12 seconds only\n- Use single quotes (') not double quotes (\")\n- Include engaging Twitter caption under 280 characters"
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 2.1
    },
    {
      "id": "02cc7cad-39df-474e-bedb-fc33bcac9be5",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1680,
        -672
      ],
      "parameters": {
        "color": 7,
        "width": 1152,
        "height": 576,
        "content": "## Generate Clips"
      },
      "typeVersion": 1
    },
    {
      "id": "ffa860c0-3118-4c83-aa00-28f61112b260",
      "name": "Save Category and Clip Scripts",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1360,
        -496
      ],
      "parameters": {
        "columns": {
          "value": {
            "Status": "=In Progress",
            "Scene 1": "={{ $json.output.Clip_1.Prompt }}",
            "Scene 2": "={{ $json.output.Clip_2.Prompt }}",
            "Scene 3": "={{ $json.output.Clip_3.Prompt }}",
            "Category": "={{ $json.output.Category }}"
          },
          "schema": [
            {
              "id": "Category",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Category",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Scene 1",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Scene 1",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Scene 2",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Scene 2",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Scene 3",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Scene 3",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1420239823,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1qUir1c-_ScMnoYVoQ0W41nsv5IpLW6rjK8HUNqvNnAg/edit#gid=1420239823",
          "cachedResultName": "Generate AI viral videos with Seedance and upload to TikTok, YouTube & Instagram"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1qUir1c-_ScMnoYVoQ0W41nsv5IpLW6rjK8HUNqvNnAg",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1qUir1c-_ScMnoYVoQ0W41nsv5IpLW6rjK8HUNqvNnAg/edit?usp=drivesdk",
          "cachedResultName": "example"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "229a8640-6e9a-4c5d-8e45-0d0e3c04ff2e",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        80,
        -80
      ],
      "parameters": {
        "color": 7,
        "width": 1584,
        "height": 720,
        "content": "## Monitor & Download Videos"
      },
      "typeVersion": 1
    },
    {
      "id": "866ee49a-a98d-420b-b3ba-6555dbfc8dab",
      "name": "Collect Video Id",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        512,
        16
      ],
      "parameters": {
        "options": {},
        "fieldsToAggregate": {
          "fieldToAggregate": [
            {
              "fieldToAggregate": "public_id"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "59f21f89-adad-44f5-ba5b-bfc760f7fb24",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -432,
        -672
      ],
      "parameters": {
        "width": 496,
        "height": 1312,
        "content": "# Generate Sora videos, stitch clips, and post to Twitter\n\n## How It Works\n\n1. **Generate Ideas**: GPT-5.1 creates 3 unique ASMR cutting scene prompts with unusual objects and Twitter caption\n2. **Create Videos**: Sora v2 generates 3 separate video clips (8-12 seconds each) in parallel\n3. **Monitor & Download**: Checks Sora rendering status every 30 seconds, downloads completed videos, uploads to Cloudinary\n4. **Stitch Videos**: Merges 3 clips into one video via Cloudinary transformations\n5. **Upload to Twitter**: Uses chunked upload (INIT \u2192 APPEND \u2192 FINALIZE) to post video with AI-generated caption\n\n## Requirements\n\n### API Keys\n- **OpenAI API Key** - For GPT-5.1 and Sora v2 access\n- **Google Sheets OAuth** - To save video ideas and track status\n- **Cloudinary Account** - For video storage and stitching (upload preset: `n8n_integration`)\n- **Twitter OAuth 1.0a** - For automated video upload and posting (required)\n\n### Configuration\n- Update Cloudinary cloud name in \"Build Stitch URL\" and \"Upload to Cloudinary\" nodes\n- Set Google Sheets document ID to your tracking spreadsheet\n- Configure Twitter OAuth 1.0a credentials for upload endpoints\n- Adjust schedule trigger interval as needed (default: every interval)\n\n### Important Notes\n- Failed Sora videos are skipped automatically\n- Twitter video processing can take 10-30 seconds after upload\n- Maximum video size for Twitter: ~512MB\n- Workflow uses Twitter's chunked upload for large files\n- Videos expire from Sora API after ~24 hours"
      },
      "typeVersion": 1
    },
    {
      "id": "19dcc7b1-60f6-46d2-89e7-185a858e1396",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        80,
        -672
      ],
      "parameters": {
        "color": 7,
        "width": 1584,
        "height": 576,
        "content": "## Generate Clip Idea\n"
      },
      "typeVersion": 1
    },
    {
      "id": "117c4275-e670-46e6-9c4c-cb4ecc2e2842",
      "name": "Download Stitched Video",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1168,
        16
      ],
      "parameters": {
        "url": "={{ $json.stitched_video_url }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "5be5c392-f39d-4ca9-aae1-371b3cdeb2a5",
      "name": "Finalize Upload",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2688,
        160
      ],
      "parameters": {
        "url": "https://upload.twitter.com/1.1/media/upload.json",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "contentType": "multipart-form-data",
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "command",
              "value": "FINALIZE"
            },
            {
              "name": "=media_id",
              "value": "={{ $('Combine Media ID + Binary').first().json.media_id_string }}"
            }
          ]
        },
        "genericAuthType": "oAuth1Api"
      },
      "credentials": {
        "oAuth1Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "51caf38e-1f69-4497-a0b2-c96f0c74af4c",
      "name": "Prepare Upload Data",
      "type": "n8n-nodes-base.code",
      "position": [
        1744,
        32
      ],
      "parameters": {
        "jsCode": "const binaryData = items[0].binary.data;\n\n// If data is base64 encoded, decode first\nconst actualBytes = binaryData.data instanceof Buffer \n  ? binaryData.data.length \n  : Buffer.from(binaryData.data, 'base64').length;\n\nreturn [{\n  json: {\n    total_bytes: actualBytes,\n    media_type: binaryData.mimeType || 'video/mp4'\n  },\n  binary: {\n    data: binaryData\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "397c21f0-c94f-41ed-b46a-bb8d5c6b1ec0",
      "name": "Twitter Upload - INIT",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1936,
        32
      ],
      "parameters": {
        "url": "https://upload.twitter.com/1.1/media/upload.json",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "contentType": "multipart-form-data",
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "command",
              "value": "INIT"
            },
            {
              "name": "total_bytes",
              "value": "={{ $json.total_bytes }}"
            },
            {
              "name": "media_type",
              "value": "={{ $json.media_type }}"
            },
            {
              "name": "media_category",
              "value": "tweet_video"
            }
          ]
        },
        "genericAuthType": "oAuth1Api"
      },
      "credentials": {
        "oAuth1Api": {
          "name": "<your credential>"
        },
        "twitterOAuth1Api": {
          "name": "<your credential>"
        },
        "twitterOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "c07d5963-9b37-4e54-9e89-6886e4beafd0",
      "name": "Twitter Upload - APPEND",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2432,
        160
      ],
      "parameters": {
        "url": "https://upload.twitter.com/1.1/media/upload.json",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "contentType": "multipart-form-data",
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "command",
              "value": "APPEND"
            },
            {
              "name": "media_id",
              "value": "={{ $json.media_id_string }}"
            },
            {
              "name": "segment_index",
              "value": "0"
            },
            {
              "name": "media",
              "parameterType": "formBinaryData",
              "inputDataFieldName": "data"
            }
          ]
        },
        "genericAuthType": "oAuth1Api"
      },
      "credentials": {
        "oAuth1Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "7e7d89ba-dc35-4fb1-89e1-ea37eb31f3be",
      "name": "Post a Tweet",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2448,
        384
      ],
      "parameters": {
        "url": "https://api.twitter.com/2/tweets",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"text\": \"{{ $('ASMR Cutting Ideas').first().json.output.Twitter_Text }}\",\n  \"media\": {\n    \"media_ids\": [\"{{ $json.media_id_string }}\"]\n  }\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "oAuth1Api",
        "headerParameters": {
          "parameters": [
            {
              "name": "content-type",
              "value": "application/json"
            }
          ]
        }
      },
      "credentials": {
        "oAuth1Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "763428fe-c1cf-4b4d-80fc-322fc7d4541a",
      "name": "Format JSON Output",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        944,
        -304
      ],
      "parameters": {
        "jsonSchemaExample": "{\n  \"Category\": \"ASMR_Cutting\",\n  \"Twitter_Text\": \"Ever wondered what happens when you cut through a glass avocado, volcanic lava rock, and rainbow soap? The sounds alone are worth it \ud83d\udd2a\u2728 #ASMR #OddlySatisfying #ASMRCutting\",\n  \"Clip_1\": {\n    \"Prompt\": \"Static top-down shot of hands holding translucent glass avocado on wooden cutting board. Sharp chef's knife presses down through the smooth glass shell. Material cracks cleanly revealing layered green-tinted glass interior with amber glass 'pit' center. Bright natural lighting. Hands steady object while blade splits it perfectly in half.\",\n    \"Sound\": \"Sharp glass crack followed by smooth grinding and clean separation snap\",\n    \"Duration\": 12\n  },\n  \"Clip_2\": {\n    \"Prompt\": \"Static side-profile shot showing hands stabilizing rough black lava stone block on white surface. Serrated knife blade saws through porous exterior. Stone crumbles and splits revealing smooth gray interior with scattered particles. Overhead lighting. Focus on blade penetrating volcanic texture.\",\n    \"Sound\": \"Deep grinding with gritty stone-on-metal scraping and final crack\",\n    \"Duration\": 8\n  },\n  \"Clip_3\": {\n    \"Prompt\": \"Static close-up of hands holding layered rainbow soap block. Thin wire cutter slices straight down through all colored layers at once. Soap separates smoothly showing perfect cross-section of pink, orange, yellow, green, blue stripes. Clean white background. Wire glides through creating ribbon-like shavings.\",\n    \"Sound\": \"Soft smooth slicing with slight sticky separation and gentle plop\",\n    \"Duration\": 12\n  }\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "8d4b6723-75ab-4351-9039-f0add4d804d1",
      "name": "AI Reasoning Tool",
      "type": "@n8n/n8n-nodes-langchain.toolThink",
      "position": [
        816,
        -304
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "43ba401e-3666-4f02-884d-0c27a6627a65",
      "name": "Loop Through Videos",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        208,
        80
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "c4c5c870-b373-48a2-a908-01fafb4b2e86",
      "name": "Combine All Scenes",
      "type": "n8n-nodes-base.merge",
      "position": [
        2688,
        -288
      ],
      "parameters": {
        "numberInputs": 3
      },
      "typeVersion": 3.2
    },
    {
      "id": "2a48a68a-4c25-4de6-acb0-2647b59448a2",
      "name": "Check If Still Processing",
      "type": "n8n-nodes-base.if",
      "position": [
        848,
        288
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "8bed937a-ae94-41f8-9fc4-17de36b0ca61",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $json.status }}",
              "rightValue": "failed"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "1f5272c6-04cd-4ef2-b0e5-10c134539223",
      "name": "Check If Render Complete",
      "type": "n8n-nodes-base.if",
      "position": [
        1056,
        352
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "0ebba095-ca57-472b-a48c-c1c34486bf0c",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.status }}",
              "rightValue": "completed"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "cb311e5d-3c13-4869-8a61-85b7cb470db7",
      "name": "Build Stitch URL",
      "type": "n8n-nodes-base.code",
      "position": [
        784,
        16
      ],
      "parameters": {
        "jsCode": "const cloudName = \"{replace with cloud name}\";\n\nconst rawVideos = [\n  $input.first().json.public_id?.[0],\n  $input.first().json.public_id?.[1],\n  $input.first().json.public_id?.[2]\n];\n\nconst videos = rawVideos.filter(v => typeof v === \"string\" && v.trim() !== \"\");\n\nif (videos.length === 0) {\n  return [{ json: { stitched_video_url: null } }];\n}\n\nlet base = `https://res.cloudinary.com/${cloudName}/video/upload/`;\n\n// Add Twitter-compatible transformations\nbase += 'vc_h264:baseline:3.0,ac_aac,ar_44100,q_auto:good,f_mp4/';\n\nvideos.slice(0, -1).forEach(v => {\n  base += `l_video:${v.replace(/\\//g, \":\")},fl_splice/`;\n});\n\nbase += `${videos[videos.length - 1].split(\"/\").pop()}.mp4`;\n\nreturn [{ json: { stitched_video_url: base } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "b037660d-b554-49e2-b472-f833af82b5c6",
      "name": "Combine Media ID + Binary",
      "type": "n8n-nodes-base.merge",
      "position": [
        2144,
        160
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.2
    },
    {
      "id": "34d80a27-c9c6-49ea-8f7d-46a273c4f6db",
      "name": "Check Twitter Processing Status",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2016,
        400
      ],
      "parameters": {
        "url": "https://upload.twitter.com/1.1/media/upload.json",
        "options": {},
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "oAuth1Api",
        "queryParameters": {
          "parameters": [
            {
              "name": "command",
              "value": "STATUS"
            },
            {
              "name": "media_id",
              "value": "={{ $json.media_id_string }}"
            }
          ]
        }
      },
      "credentials": {
        "oAuth1Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "7e87422b-75e7-4387-b663-bc25b0f2c88d",
      "name": "Check If Twitter Ready",
      "type": "n8n-nodes-base.if",
      "position": [
        2240,
        400
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "2c9dd15b-3390-4504-8f56-f834ad158ac2",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.processing_info.state }}",
              "rightValue": "succeeded"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "7b3a9454-af61-4b1c-9496-ac86ceb22a70",
      "name": "Wait for Twitter Processing",
      "type": "n8n-nodes-base.wait",
      "position": [
        1792,
        400
      ],
      "parameters": {},
      "typeVersion": 1.1
    },
    {
      "id": "1656c8ca-7697-45ed-9a0d-b456868caa17",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1680,
        -80
      ],
      "parameters": {
        "color": 7,
        "width": 1152,
        "height": 720,
        "content": "## Upload to Twitter/X"
      },
      "typeVersion": 1
    },
    {
      "id": "2be92900-50e2-4631-a283-8087162ed2f5",
      "name": "Update Status",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2656,
        384
      ],
      "parameters": {
        "columns": {
          "value": {
            "Status": "=Posted"
          },
          "schema": [
            {
              "id": "Category",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Category",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Scene 1",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Scene 1",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Scene 2",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Scene 2",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Scene 3",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Scene 3",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1420239823,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1qUir1c-_ScMnoYVoQ0W41nsv5IpLW6rjK8HUNqvNnAg/edit#gid=1420239823",
          "cachedResultName": "Generate AI viral videos with Seedance and upload to TikTok, YouTube & Instagram"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1qUir1c-_ScMnoYVoQ0W41nsv5IpLW6rjK8HUNqvNnAg",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1qUir1c-_ScMnoYVoQ0W41nsv5IpLW6rjK8HUNqvNnAg/edit?usp=drivesdk",
          "cachedResultName": "example"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.6
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "a8fc005d-8037-4a39-a6bc-86341010e4fa",
  "connections": {
    "Post a Tweet": {
      "main": [
        [
          {
            "node": "Update Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Finalize Upload": {
      "main": [
        [
          {
            "node": "Wait for Twitter Processing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Stitch URL": {
      "main": [
        [
          {
            "node": "Download Stitched Video",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Collect Video Id": {
      "main": [
        [
          {
            "node": "Build Stitch URL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "ASMR Cutting Ideas",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Reasoning Tool": {
      "ai_tool": [
        [
          {
            "node": "ASMR Cutting Ideas",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "ASMR Cutting Ideas",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "ASMR Cutting Ideas": {
      "main": [
        [
          {
            "node": "Save Category and Clip Scripts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Video Status": {
      "main": [
        [
          {
            "node": "Check If Still Processing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Combine All Scenes": {
      "main": [
        [
          {
            "node": "Loop Through Videos",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format JSON Output": {
      "ai_outputParser": [
        [
          {
            "node": "ASMR Cutting Ideas",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Loop Through Videos": {
      "main": [
        [
          {
            "node": "Collect Video Id",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Wait 30s for Rendering",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Upload Data": {
      "main": [
        [
          {
            "node": "Twitter Upload - INIT",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload to Cloudinary": {
      "main": [
        [
          {
            "node": "Loop Through Videos",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Twitter Upload - INIT": {
      "main": [
        [
          {
            "node": "Combine Media ID + Binary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check If Twitter Ready": {
      "main": [
        [
          {
            "node": "Post a Tweet",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Wait for Twitter Processing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait 30s for Rendering": {
      "main": [
        [
          {
            "node": "Check Video Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download Stitched Video": {
      "main": [
        [
          {
            "node": "Prepare Upload Data",
            "type": "main",
            "index": 0
          },
          {
            "node": "Combine Media ID + Binary",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Twitter Upload - APPEND": {
      "main": [
        [
          {
            "node": "Finalize Upload",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check If Render Complete": {
      "main": [
        [
          {
            "node": "Download Completed Video",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Wait 30s for Rendering",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download Completed Video": {
      "main": [
        [
          {
            "node": "Upload to Cloudinary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check If Still Processing": {
      "main": [
        [
          {
            "node": "Check If Render Complete",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Loop Through Videos",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Combine Media ID + Binary": {
      "main": [
        [
          {
            "node": "Twitter Upload - APPEND",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Sora Video Scene - 1": {
      "main": [
        [
          {
            "node": "Combine All Scenes",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Sora Video Scene - 2": {
      "main": [
        [
          {
            "node": "Combine All Scenes",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Create Sora Video Scene - 3": {
      "main": [
        [
          {
            "node": "Combine All Scenes",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "Wait for Twitter Processing": {
      "main": [
        [
          {
            "node": "Check Twitter Processing Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save Category and Clip Scripts": {
      "main": [
        [
          {
            "node": "Create Sora Video Scene - 1",
            "type": "main",
            "index": 0
          },
          {
            "node": "Create Sora Video Scene - 2",
            "type": "main",
            "index": 0
          },
          {
            "node": "Create Sora Video Scene - 3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Twitter Processing Status": {
      "main": [
        [
          {
            "node": "Check If Twitter Ready",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Generate creative ASMR cutting video concepts with GPT-5.1, create high-quality video clips using Sora v2, stitch them together with Cloudinary, and automatically post to Twitter/X—transforming ideas into viral content without manual video editing.

Source: https://n8n.io/workflows/12590/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

ASMR. Uses googleSheets, outputParserStructured, httpRequest, lmChatOpenAi. Scheduled trigger; 35 nodes.

Google Sheets, Output Parser Structured, HTTP Request +5
AI & RAG

//ASMR AI Workflow

HTTP Request, Tool Think, OpenAI Chat +6
AI & RAG

This template is ideal for content creators, social media managers, YouTubers, and digital marketers who want to generate high-quality videos daily using AI and distribute them effortlessly across mul

Google Sheets, HTTP Request, Agent +3
AI & RAG

This workflow is designed for social media managers, content creators, digital marketers, and entrepreneurs who want to automate the entire lifecycle of creating and publishing short-form video conten

Tool Think, Output Parser Structured, Google Sheets +6
AI & RAG

ASMR + Veo3. Uses httpRequest, googleSheets, toolThink, agent. Scheduled trigger; 26 nodes.

HTTP Request, Google Sheets, Tool Think +3