{ "kind": "open-flow-workflow", "version": 1, "name": "Archive Empty Notion Database Pages", "content": { "modelVersion": 14, "document": { "bindings": {}, "graph": { "nodes": { "n_d2ccc3ea07eedecb": { "name": "Daily at 02:00 UTC", "kind": "cron", "cronTimes": [ { "type": "cron", "expression": "0 2 * * *", "timezone": "UTC" } ] }, "n_176379642265c707": { "inputs": { "previous": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_176379642265c707", "output": "state" } ] } }, "name": "List accessible database pages", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": true, "handle": "previous" } ], "outputs": [ { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "state" }, { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "more" } ], "name": "List accessible database pages", "moduleId": "n_ec2a63ad440a380f", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [ { "action": "notion.search" }, { "action": "notion.query_data_source" } ] } ] } }, "n_cbfff1bb428ab9e6": { "inputs": {}, "name": "More database pages?", "kind": "condition", "matchMode": "first", "cases": [ { "output": "yes", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_176379642265c707", "output": "more" } }, "operator": "isTrue" } ] } ] } ] }, "n_0e50a9aee7b1c3dc": { "inputs": { "scan": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_176379642265c707", "output": "state" } ] }, "previous": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_0e50a9aee7b1c3dc", "output": "state" } ] }, "confirmation": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_b36753303d3c84e0", "output": "output" } ] } }, "name": "Inspect the next page", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "scan" }, { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": true, "handle": "previous" }, { "jsonSchema": { "type": "object", "properties": { "object": { "const": "page", "description": "The Notion object type." }, "id": { "type": "string", "description": "The page ID." }, "created_time": { "type": "string", "format": "date-time", "description": "The time when the page was created." }, "last_edited_time": { "type": "string", "format": "date-time", "description": "The time when the page was last edited." }, "created_by": { "type": "object", "properties": { "object": { "const": "user", "description": "The Notion object type." }, "id": { "type": "string", "description": "The Notion user ID." }, "name": { "type": [ "string", "null" ], "description": "The user's display name, or null when unavailable." }, "avatar_url": { "type": [ "string", "null" ], "description": "The user's avatar URL, or null when unavailable." }, "type": { "type": "string", "enum": [ "person", "bot" ], "description": "The user type returned by Notion." }, "person": { "type": "object", "properties": { "email": { "type": "string", "format": "email", "description": "The person's email address." } }, "additionalProperties": true, "description": "Details about a person user." }, "bot": { "type": "object", "additionalProperties": { "description": "A Notion API field value." }, "description": "Details about a bot user." } }, "additionalProperties": true, "description": "A Notion user reference." }, "last_edited_by": { "type": "object", "properties": { "object": { "const": "user", "description": "The Notion object type." }, "id": { "type": "string", "description": "The Notion user ID." }, "name": { "type": [ "string", "null" ], "description": "The user's display name, or null when unavailable." }, "avatar_url": { "type": [ "string", "null" ], "description": "The user's avatar URL, or null when unavailable." }, "type": { "type": "string", "enum": [ "person", "bot" ], "description": "The user type returned by Notion." }, "person": { "type": "object", "properties": { "email": { "type": "string", "format": "email", "description": "The person's email address." } }, "additionalProperties": true, "description": "Details about a person user." }, "bot": { "type": "object", "additionalProperties": { "description": "A Notion API field value." }, "description": "Details about a bot user." } }, "additionalProperties": true, "description": "A Notion user reference." }, "cover": { "type": [ "object", "null" ], "additionalProperties": { "description": "A Notion API field value." }, "description": "The page cover object, or null when the page has no cover." }, "icon": { "type": [ "object", "null" ], "additionalProperties": { "description": "A Notion API field value." }, "description": "The page icon object, or null when the page has no icon." }, "parent": { "type": "object", "properties": { "type": { "type": "string", "description": "The parent type, such as workspace, page_id, data_source_id, database_id, or block_id." } }, "additionalProperties": true, "description": "The parent object that contains this Notion object." }, "is_archived": { "type": "boolean", "description": "Whether the page has been archived." }, "in_trash": { "type": "boolean", "description": "Whether the page is in the trash." }, "is_locked": { "type": "boolean", "description": "Whether the page is locked." }, "properties": { "type": "object", "additionalProperties": { "description": "A Notion property value or property schema object." }, "description": "The Notion page, database, or data source properties keyed by property name." }, "url": { "type": "string", "format": "uri", "description": "The canonical Notion URL for the page." }, "public_url": { "type": [ "string", "null" ], "format": "uri", "description": "The public Notion URL if the page is published to the web." } }, "additionalProperties": true, "description": "The updated Notion page object returned by the API." }, "nullable": true, "handle": "confirmation" } ], "outputs": [ { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "state" }, { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "more" }, { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "archive" }, { "jsonSchema": { "type": "string", "description": "The page ID to update." }, "nullable": false, "handle": "pageId" } ], "name": "Inspect the next page", "moduleId": "n_173fabfb9dff0da5", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [ { "action": "notion.retrieve_page" }, { "action": "notion.list_block_children" } ] } ] } }, "n_62407ce56514ef16": { "inputs": {}, "name": "More pages to inspect?", "kind": "condition", "matchMode": "first", "cases": [ { "output": "yes", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_0e50a9aee7b1c3dc", "output": "more" } }, "operator": "isTrue" } ] } ] } ] }, "n_13713433b4ab56d0": { "inputs": {}, "name": "Page confirmed empty?", "kind": "condition", "matchMode": "first", "cases": [ { "output": "yes", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_0e50a9aee7b1c3dc", "output": "archive" } }, "operator": "isTrue" } ] } ] } ] }, "n_b36753303d3c84e0": { "inputs": { "pageId": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_0e50a9aee7b1c3dc", "output": "pageId" } ] }, "in_trash": { "kind": "value", "value": true } }, "name": "Move the page to trash", "kind": "task", "task": { "inputs": [ { "description": "The page ID to update.", "jsonSchema": { "type": "string", "description": "The page ID to update." }, "nullable": false, "handle": "pageId" }, { "description": "The new page title.", "jsonSchema": { "type": "string", "description": "The new page title." }, "nullable": true, "handle": "title", "value": null }, { "description": "The page properties to update.", "jsonSchema": { "type": "object", "additionalProperties": { "description": "A Notion page property value." }, "description": "The page properties to update." }, "nullable": true, "handle": "properties", "value": null }, { "description": "The new page icon object.", "jsonSchema": { "type": "object", "additionalProperties": { "description": "A Notion icon field value." }, "description": "The new page icon object." }, "nullable": true, "handle": "icon", "value": null }, { "description": "The new page cover object.", "jsonSchema": { "type": "object", "additionalProperties": { "description": "A Notion cover field value." }, "description": "The new page cover object." }, "nullable": true, "handle": "cover", "value": null }, { "description": "The data source template payload to apply to the existing page.", "jsonSchema": { "type": "object", "additionalProperties": { "description": "A Notion template field value." }, "description": "The data source template payload to apply to the existing page." }, "nullable": true, "handle": "template", "value": null }, { "description": "Whether to move the page to trash.", "jsonSchema": { "type": "boolean", "description": "Whether to move the page to trash." }, "nullable": true, "handle": "in_trash", "value": null }, { "description": "Whether to lock or unlock the page in the Notion app UI.", "jsonSchema": { "type": "boolean", "description": "Whether to lock or unlock the page in the Notion app UI." }, "nullable": true, "handle": "is_locked", "value": null }, { "description": "Whether to delete all child blocks from the page before applying template changes.", "jsonSchema": { "type": "boolean", "description": "Whether to delete all child blocks from the page before applying template changes." }, "nullable": true, "handle": "erase_content", "value": null } ], "outputs": [ { "description": "The updated Notion page object returned by the API.", "jsonSchema": { "type": "object", "properties": { "object": { "const": "page", "description": "The Notion object type." }, "id": { "type": "string", "description": "The page ID." }, "created_time": { "type": "string", "format": "date-time", "description": "The time when the page was created." }, "last_edited_time": { "type": "string", "format": "date-time", "description": "The time when the page was last edited." }, "created_by": { "type": "object", "properties": { "object": { "const": "user", "description": "The Notion object type." }, "id": { "type": "string", "description": "The Notion user ID." }, "name": { "type": [ "string", "null" ], "description": "The user's display name, or null when unavailable." }, "avatar_url": { "type": [ "string", "null" ], "description": "The user's avatar URL, or null when unavailable." }, "type": { "type": "string", "enum": [ "person", "bot" ], "description": "The user type returned by Notion." }, "person": { "type": "object", "properties": { "email": { "type": "string", "format": "email", "description": "The person's email address." } }, "additionalProperties": true, "description": "Details about a person user." }, "bot": { "type": "object", "additionalProperties": { "description": "A Notion API field value." }, "description": "Details about a bot user." } }, "additionalProperties": true, "description": "A Notion user reference." }, "last_edited_by": { "type": "object", "properties": { "object": { "const": "user", "description": "The Notion object type." }, "id": { "type": "string", "description": "The Notion user ID." }, "name": { "type": [ "string", "null" ], "description": "The user's display name, or null when unavailable." }, "avatar_url": { "type": [ "string", "null" ], "description": "The user's avatar URL, or null when unavailable." }, "type": { "type": "string", "enum": [ "person", "bot" ], "description": "The user type returned by Notion." }, "person": { "type": "object", "properties": { "email": { "type": "string", "format": "email", "description": "The person's email address." } }, "additionalProperties": true, "description": "Details about a person user." }, "bot": { "type": "object", "additionalProperties": { "description": "A Notion API field value." }, "description": "Details about a bot user." } }, "additionalProperties": true, "description": "A Notion user reference." }, "cover": { "type": [ "object", "null" ], "additionalProperties": { "description": "A Notion API field value." }, "description": "The page cover object, or null when the page has no cover." }, "icon": { "type": [ "object", "null" ], "additionalProperties": { "description": "A Notion API field value." }, "description": "The page icon object, or null when the page has no icon." }, "parent": { "type": "object", "properties": { "type": { "type": "string", "description": "The parent type, such as workspace, page_id, data_source_id, database_id, or block_id." } }, "additionalProperties": true, "description": "The parent object that contains this Notion object." }, "is_archived": { "type": "boolean", "description": "Whether the page has been archived." }, "in_trash": { "type": "boolean", "description": "Whether the page is in the trash." }, "is_locked": { "type": "boolean", "description": "Whether the page is locked." }, "properties": { "type": "object", "additionalProperties": { "description": "A Notion property value or property schema object." }, "description": "The Notion page, database, or data source properties keyed by property name." }, "url": { "type": "string", "format": "uri", "description": "The canonical Notion URL for the page." }, "public_url": { "type": [ "string", "null" ], "format": "uri", "description": "The public Notion URL if the page is published to the web." } }, "additionalProperties": true, "description": "The updated Notion page object returned by the API." }, "nullable": false, "handle": "output" } ], "name": "Move the page to trash", "executor": { "kind": "connector", "action": "notion.update_page", "outputMode": "value" } } } }, "edges": [ { "source": "n_d2ccc3ea07eedecb", "target": "n_176379642265c707" }, { "source": "n_176379642265c707", "target": "n_cbfff1bb428ab9e6" }, { "source": "n_cbfff1bb428ab9e6", "target": "n_176379642265c707", "sourceHandle": "yes" }, { "source": "n_cbfff1bb428ab9e6", "target": "n_0e50a9aee7b1c3dc", "sourceHandle": "otherwise" }, { "source": "n_0e50a9aee7b1c3dc", "target": "n_62407ce56514ef16" }, { "source": "n_62407ce56514ef16", "target": "n_13713433b4ab56d0", "sourceHandle": "yes" }, { "source": "n_13713433b4ab56d0", "target": "n_b36753303d3c84e0", "sourceHandle": "yes" }, { "source": "n_13713433b4ab56d0", "target": "n_0e50a9aee7b1c3dc", "sourceHandle": "otherwise" }, { "source": "n_b36753303d3c84e0", "target": "n_0e50a9aee7b1c3dc" } ] } }, "modules": { "n_ec2a63ad440a380f": { "name": "List accessible database pages", "imports": [], "source": "export default async function scan({previous},context){\n const s=previous??{phase:'sources',cursor:null,seen:[],sources:[],pages:[],index:0};\n const call=s.phase==='sources'?'notion.search':'notion.query_data_source';\n if(s.phase==='done')return{state:s,more:false};\n const args=s.phase==='sources'?{filter:{property:'object',value:'data_source'},pageSize:100}:{dataSourceId:s.sources[s.index],pageSize:100};if(s.cursor)args.startCursor=s.cursor;\n const r=await context.actions.call(call,args);if(!r||!Array.isArray(r.results)||typeof r.has_more!=='boolean')throw Error('Invalid Notion page');\n const next=r.next_cursor;if(r.has_more&&(typeof next!=='string'||!next||s.seen.includes(next)))throw Error('Invalid Notion cursor');if(!r.has_more&&next!==null)throw Error('Invalid final Notion cursor');\n if(s.phase==='sources'){const ids=r.results.map(x=>{if(x?.object!=='data_source'||typeof x.id!=='string'||!x.id)throw Error('Invalid data source');return x.id});if(new Set([...s.sources,...ids]).size!==s.sources.length+ids.length)throw Error('Duplicate data source');const sources=[...s.sources,...ids];return{state:{...s,sources,phase:r.has_more?'sources':sources.length?'pages':'done',cursor:r.has_more?next:null,seen:r.has_more?[...s.seen,next]:[]},more:r.has_more||sources.length>0}}\n const pages=r.results.map(x=>{if(x?.object!=='page'||typeof x.id!=='string'||!x.id)throw Error('Invalid database page');return x.id});if(new Set([...s.pages,...pages]).size!==s.pages.length+pages.length)throw Error('Duplicate page');let index=s.index+(r.has_more?0:1),phase=index=scan.pages.length)return{state:s,more:false,archive:false,pageId:'unused'};const id=scan.pages[s.index];if(typeof id!=='string'||!id)throw Error('Invalid page ID');if(s.phase==='page'){const p=await context.actions.call('notion.retrieve_page',{pageId:id});if(p?.id!==id||p?.object!=='page')throw Error('Unexpected page');if(typeof p.in_trash!=='boolean')throw Error('Missing page trash state');if(p.in_trash||!emptyProperties(p.properties))return{state:{...s,index:s.index+1},more:true,archive:false,pageId:'unused'};return{state:{...s,phase:'blocks',pageId:id},more:true,archive:false,pageId:'unused'}}\n if(s.phase!=='blocks'||s.pageId!==id)throw Error('Invalid scan state');const args={blockId:id,pageSize:100,...(s.cursor?{startCursor:s.cursor}:{})},r=await context.actions.call('notion.list_block_children',args);if(!r||!Array.isArray(r.results)||typeof r.has_more!=='boolean')throw Error('Invalid blocks');const cursor=r.next_cursor;if(r.has_more&&(typeof cursor!=='string'||!cursor||s.seen.includes(cursor)))throw Error('Invalid block cursor');if(!r.has_more&&cursor!==null)throw Error('Invalid final block cursor');if(r.results.some(x=>!emptyBlock(x)))return{state:{...s,index:s.index+1,phase:'page',cursor:null,seen:[],pageId:null},more:true,archive:false,pageId:'unused'};if(r.has_more)return{state:{...s,cursor,seen:[...s.seen,cursor]},more:true,archive:false,pageId:'unused'};return{state:{...s,waiting:true},more:true,archive:true,pageId:id}}\n" } } }, "presentation": { "designer": { "version": 1, "flow": { "direction": "vertical" } } } }