AutomationFlowsData & Sheets › Convert Edited Notion Pages Into Explainer Videos with Ozor AI

Convert Edited Notion Pages Into Explainer Videos with Ozor AI

ByOzorAI @ozorai on n8n.io

Got a Notion doc? Turn it into a polished explainer video without lifting a finger. This workflow watches your Notion database for recently edited pages and uses Ozor AI to automatically generate a professional video from the content — then drops the finished video right back…

Cron / scheduled trigger★★★★☆ complexity17 nodesNotionN8N Nodes Ozor
Data & Sheets Trigger: Cron / scheduled Nodes: 17 Complexity: ★★★★☆ Added:

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

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": "MPDBjJPvjHbekdkb",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Ozor 03 \u2014 Notion SOP Edited \u2192 LMS Training Video Refresh",
  "tags": [
    {
      "id": "SuifuWS54jd4UEEP",
      "name": "ozor",
      "createdAt": "2026-05-11T16:06:19.688Z",
      "updatedAt": "2026-05-11T16:06:19.688Z"
    }
  ],
  "nodes": [
    {
      "id": "a90a6fab-5278-42f0-b3df-eec2770ada76",
      "name": "Every 15 Minutes",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -16,
        -144
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "minutes",
              "minutesInterval": 15
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "b8a219e4-15db-4a72-a368-8b486e1ea998",
      "name": "Notion \u2014 Recently Edited SOPs",
      "type": "n8n-nodes-base.notion",
      "position": [
        256,
        -144
      ],
      "parameters": {
        "limit": 1,
        "options": {},
        "resource": "databasePage",
        "operation": "getAll",
        "databaseId": {
          "__rl": true,
          "mode": "list",
          "value": "35d2b1fb-9cde-8088-8645-fc907ca6b3c3",
          "cachedResultUrl": "https://www.notion.so/35d2b1fb9cde80888645fc907ca6b3c3",
          "cachedResultName": "Document Hub"
        }
      },
      "credentials": {
        "notionApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "85d61727-4223-4404-816f-3dcc31f76c48",
      "name": "Ozor \u2014 Analyze Notion Page",
      "type": "n8n-nodes-ozor.ozor",
      "position": [
        0,
        80
      ],
      "parameters": {
        "resource": "document",
        "sourceUrl": "https://www.ozor.ai/",
        "analyzePrompt": "={{ $json.text }}"
      },
      "credentials": {
        "ozorApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "bdb001d1-9ba2-4062-9602-54bb3ab94094",
      "name": "Ozor \u2014 Generate From Plan",
      "type": "n8n-nodes-ozor.ozor",
      "position": [
        256,
        80
      ],
      "parameters": {
        "planId": "={{ $json.plan.planId }}",
        "resource": "document",
        "operation": "generatePlan"
      },
      "credentials": {
        "ozorApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "6b283b85-fdb5-4ae3-90c6-5af6cb69167b",
      "name": "Get many child blocks",
      "type": "n8n-nodes-base.notion",
      "position": [
        512,
        -144
      ],
      "parameters": {
        "blockId": {
          "__rl": true,
          "mode": "url",
          "value": "={{ $json.url }}"
        },
        "resource": "block",
        "operation": "getAll"
      },
      "credentials": {
        "notionApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "4f53b6f5-979f-45a6-a439-e7e4cf779f90",
      "name": "Code in JavaScript",
      "type": "n8n-nodes-base.code",
      "position": [
        800,
        -144
      ],
      "parameters": {
        "jsCode": "const blocks = $input.all().map((item) => item.json);\nlet text = \"I have put my company url for context about my brand. Make the video about the following informatiion for a blog post I wrote: \";\n\nblocks.forEach((block) => {\n  if (block.content) {\n    text += block.content + \"\\n\";\n  }\n  if (block.image?.file?.url) {\n    text += block.image.file.url + \"\\n\";\n  }\n});\n\nreturn [{ json: { text }, pairedItem: blocks.map((_, index) => index) }];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "30465de5-53c2-4ff7-96aa-a58ce3a75230",
      "name": "Export a video",
      "type": "n8n-nodes-ozor.ozor",
      "position": [
        512,
        80
      ],
      "parameters": {
        "videoId": "={{ $json.projectId }}",
        "isPublic": true,
        "operation": "export",
        "waitForExportSingle": true
      },
      "credentials": {
        "ozorApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "dfb0d115-2e0d-4568-ab48-69a71395c9cc",
      "name": "Append a block",
      "type": "n8n-nodes-base.notion",
      "position": [
        800,
        80
      ],
      "parameters": {
        "blockId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Get many child blocks').all()[0].json.parent.page_id }}"
        },
        "blockUi": {
          "blockValues": [
            {
              "url": "={{ $json.downloadUrl }}",
              "type": "image"
            }
          ]
        },
        "resource": "block"
      },
      "credentials": {
        "notionApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "2fd5f9ec-9040-474b-838c-4b9a4222aede",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -544,
        -464
      ],
      "parameters": {
        "width": 448,
        "height": 1200,
        "content": "## \ud83c\udfac WORKFLOW OVERVIEW\n**Ozor 03 \u2014 Notion SOP Edited \u2192 LMS Training Video Refresh**\n\nThis workflow automatically monitors a Notion 'Document Hub' database for recently edited SOPs (Standard Operating Procedures) and regenerates an updated LMS training video using Ozor AI \u2014 then appends the new video back to the original Notion page.\n\n### \ud83d\udd04 High-Level Flow\n1. **Schedule Trigger** (every 15 min)\n2. **Fetch** the most recently edited SOP from Notion\n3. **Read** all child blocks of that page\n4. **Compile** content into a single prompt (JS)\n5. **Analyze** the document with Ozor AI \u2192 produces a video plan\n6. **Generate** the video project from that plan\n7. **Export** the rendered 1080p MP4\n8. **Append** the new video link back into the Notion page\n\n### \ud83c\udfaf Use Case\nKeeps internal LMS training videos in sync with the source-of-truth SOPs in Notion \u2014 without anyone manually re-rendering videos every time documentation changes.\n\n## \u26a0\ufe0f REQUIREMENTS\n- **Notion credential** with read + write access to Document Hub\n- **Ozor account** credential configured in n8n\n- **Active network** access to Notion API, Ozor API & Google Cloud Storage\n- **Execution time:** ~5\u201310 min per run (video export is the bottleneck)\n- **Schedule:** Every 15 min \u2014 set to non-overlap with export duration"
      },
      "typeVersion": 1
    },
    {
      "id": "4c201ee9-5edb-4060-8ba9-0f13119e480e",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        192,
        -464
      ],
      "parameters": {
        "width": 224,
        "height": 464,
        "content": "## \ud83d\uddc3\ufe0f NODE 2 \u2014 Notion: Recently Edited SOPs\n\nFetches the single most recently edited SOP page from the Document Hub Notion database. Returns ID, URL, name, timestamps, category, and doc name properties.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "1e07564e-9e19-43d1-be47-5e1cb6566ecf",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -80,
        48
      ],
      "parameters": {
        "width": 256,
        "height": 688,
        "content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## \ud83e\udde0 NODE 5 \u2014 Ozor: Analyze Notion Page\n\nThis is where the AI reads the SOP and figures out what the video should look like.\n\nIt takes all the text and images from the Notion page and sends them to Ozor AI. Ozor then creates a **video plan** \u2014 deciding things like layout, colors, tone, and structure.\n\nThink of it as the **\"creative brief\"** step: the AI understands the content and plans the video before building anything."
      },
      "typeVersion": 1
    },
    {
      "id": "873134fd-f531-450a-a775-8ae8d3122e04",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        720,
        32
      ],
      "parameters": {
        "width": 288,
        "height": 736,
        "content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## \ud83d\udccc NODE 8 \u2014 Append a Block\n**Resource:** Block \u00b7 **Operation:** Append After\n**Target Block ID:**\n`{{ $('Get many child blocks').all()[0].json.parent.page_id }}`\n\u2192 Resolves to the Notion Page ID of the original SOP\n**Block Type:** Image\n**Image URL:** `{{ $json.downloadUrl }}`\n\u2192 The Google Cloud Storage MP4 link from Export node\n\nAppends the rendered training video as an image block directly at the bottom of the original SOP Notion page, making it permanently accessible to anyone reading the doc.\n\n---\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "22699364-d2b1-4164-b02c-e29fa8117a5d",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -80,
        -464
      ],
      "parameters": {
        "height": 480,
        "content": "## \u23f1\ufe0f NODE 1 \u2014 Every 15 Minutes\n**Type:** Schedule Trigger\n**Interval:** Every 15 minutes\nKicks off the entire workflow automatically on a fixed schedule. For testing, use \"Execute workflow\" manually on the canvas."
      },
      "typeVersion": 1
    },
    {
      "id": "55c136fa-2e46-4f3c-9f21-faf1eb9c53d8",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        448,
        -464
      ],
      "parameters": {
        "height": 464,
        "content": "\n## \ud83d\udcc4 NODE 3 \u2014 Get Many Child Blocks\n**Resource:** Block \u00b7 **Operation:** Get Child Blocks\n**Block:** By URL \u2192 `{{ $json.url }}` \u00b7 **Limit:** 50\nReads all content blocks (headings, paragraphs, images) from the SOP page URL. Returns up to 50 blocks with type, content text, and image file URLs.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "1a73c75e-6b2d-4205-ae9b-75f223a3c997",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        720,
        -464
      ],
      "parameters": {
        "width": 288,
        "height": 464,
        "content": "## \ud83d\udd27 NODE 4 \u2014 Code in JavaScript\n**Mode:** Run Once for All Items\nLoops through all blocks and builds a single text string:\n- Appends `block.content` (text blocks) line by line\n- Appends `block.image.file.url` (image URLs) line by line\n- Prepends company context sentence for Ozor AI branding\n"
      },
      "typeVersion": 1
    },
    {
      "id": "024d8ca8-210a-4edb-b1cf-7876eec64021",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        192,
        48
      ],
      "parameters": {
        "height": 704,
        "content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## \ud83c\udfac NODE 6 \u2014 Ozor: Generate From Plan\n\nThis is where Ozor **actually builds the video** based on the plan created in the previous step.\n\nIt takes the plan ID and starts producing the video project \u2014 assembling scenes, applying the design style, adding motion and text. It waits until the video is 100% ready before moving on.\n\nThink of it as the **\"production\"** step: the plan becomes a real video."
      },
      "typeVersion": 1
    },
    {
      "id": "e9e5ce91-0441-478b-acc8-45aae824d37c",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        448,
        32
      ],
      "parameters": {
        "height": 720,
        "content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## \ud83d\udce4 NODE 7 \u2014 Export a Video\n\nThis step **exports the finished video** as a downloadable MP4 file.\n\nOnce the video is built, Ozor renders it at 1080p quality and makes it publicly accessible. The workflow waits here (up to 5 minutes) until the export is fully complete.\n\nThe result is a **direct download link** to the final video file, which gets passed to the next step to be saved back into Notion."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "versionId": "cb9b4143-3a3d-494a-8172-c20e0787cba4",
  "connections": {
    "Export a video": {
      "main": [
        [
          {
            "node": "Append a block",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Every 15 Minutes": {
      "main": [
        [
          {
            "node": "Notion \u2014 Recently Edited SOPs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript": {
      "main": [
        [
          {
            "node": "Ozor \u2014 Analyze Notion Page",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get many child blocks": {
      "main": [
        [
          {
            "node": "Code in JavaScript",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Ozor \u2014 Generate From Plan": {
      "main": [
        [
          {
            "node": "Export a video",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Ozor \u2014 Analyze Notion Page": {
      "main": [
        [
          {
            "node": "Ozor \u2014 Generate From Plan",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Notion \u2014 Recently Edited SOPs": {
      "main": [
        [
          {
            "node": "Get many child blocks",
            "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

Got a Notion doc? Turn it into a polished explainer video without lifting a finger. This workflow watches your Notion database for recently edited pages and uses Ozor AI to automatically generate a professional video from the content — then drops the finished video right back…

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

More Data & Sheets workflows → · Browse all categories →

Related workflows

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

Data & Sheets

This template is designed for social media managers, content creators, data analysts, and anyone who wants to automatically save and analyze their Meta Threads posts in Notion.

HTTP Request, Notion
Data & Sheets

&gt; Transform your content strategy with automated competitor intelligence

HTTP Request, Airtable, Notion +2
Data & Sheets

Plan a full week of scroll-stopping pins in under two minutes! 🚀

Notion, Email Send, Error Trigger
Data & Sheets

⚠️ COMMUNITY TEMPLATE DISCLAIMER: This is a community-contributed template that uses ScrapeGraphAI (a community node). Please ensure you have the ScrapeGraphAI community node installed in your n8n ins

N8N Nodes Scrapegraphai, HTTP Request, Notion +1
Data & Sheets

Your pantry’s calm concierge. Each evening it checks your Notion Pantry for items at or below your Reorder Level, adds tidy rows to Grocery List, and sends a pretty summary email you can shop from. ✨🛒

Notion, Email Send, Error Trigger