{ "kind": "open-flow-workflow", "version": 1, "name": "New YouTube Video to X", "content": { "modelVersion": 14, "document": { "bindings": {}, "graph": { "nodes": { "n_5db573aa18594fb9": { "name": "Check every 30 minutes", "kind": "cron", "cronTimes": [ { "type": "cron", "expression": "*/30 * * * *", "timezone": "UTC" } ] }, "n_d19246ccbd478de7": { "inputs": { "channelId": { "kind": "value", "value": "YOUR_YOUTUBE_CHANNEL_ID" } }, "name": "Set channel and time window", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "channelId" } ], "outputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "channelId" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "after" } ], "name": "Set channel and time window", "moduleId": "n_139cabfa28f5cc19", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_fa530dc4450e9c79": { "inputs": { "endpoint": { "kind": "value", "value": "/search" }, "query.part": { "kind": "value", "value": "snippet" }, "query.type": { "kind": "value", "value": "video" }, "query.channelId": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_d19246ccbd478de7", "output": "channelId" } ] }, "query.publishedAfter": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_d19246ccbd478de7", "output": "after" } ] }, "query.maxResults": { "kind": "value", "value": 1 } }, "name": "Search recent channel videos", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "endpoint" }, { "jsonSchema": { "type": [ "string", "number", "boolean", "null" ] }, "nullable": true, "handle": "query.part" }, { "jsonSchema": { "type": [ "string", "number", "boolean", "null" ] }, "nullable": true, "handle": "query.type" }, { "jsonSchema": { "type": [ "string", "number", "boolean", "null" ] }, "nullable": true, "handle": "query.channelId" }, { "jsonSchema": { "type": [ "string", "number", "boolean", "null" ] }, "nullable": true, "handle": "query.publishedAfter" }, { "jsonSchema": { "type": [ "string", "number", "boolean", "null" ] }, "nullable": true, "handle": "query.maxResults" } ], "outputs": [ { "jsonSchema": {}, "nullable": true, "handle": "body" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "statusCode" }, { "jsonSchema": { "type": "object", "additionalProperties": { "type": "string" } }, "nullable": false, "handle": "headers" }, { "jsonSchema": { "const": "base64" }, "nullable": true, "handle": "bodyEncoding" } ], "name": "Search recent channel videos", "executor": { "providerId": "youtube", "method": "GET", "query": { "mode": "fields", "names": [ "part", "type", "channelId", "publishedAfter", "maxResults" ] }, "headers": { "mode": "fields", "names": [] }, "bodyFormat": "none", "kind": "connector-proxy" } } }, "n_7b0b90adecdcd66e": { "inputs": { "body": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_fa530dc4450e9c79", "output": "body" } ] }, "statusCode": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_fa530dc4450e9c79", "output": "statusCode" } ] } }, "name": "Read the video", "kind": "task", "task": { "inputs": [ { "jsonSchema": {}, "nullable": true, "handle": "body" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "statusCode" } ], "outputs": [ { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "found" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "prompt" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "videoId" } ], "name": "Read the video", "moduleId": "n_fb91f41b16038146", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_810e521b180ed7e6": { "inputs": {}, "name": "No video found", "kind": "condition", "matchMode": "first", "cases": [ { "output": "empty", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_7b0b90adecdcd66e", "output": "found" } }, "operator": "==", "right": { "kind": "value", "value": false } } ] } ] } ] }, "n_f140388619bc8264": { "inputs": { "prompt": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_7b0b90adecdcd66e", "output": "prompt" } ] } }, "name": "Write the X post", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "prompt" } ], "outputs": [ { "description": "The final result produced by the Agent.", "jsonSchema": { "type": "string" }, "nullable": false, "handle": "output" } ], "name": "Write the X post", "executor": { "kind": "agent", "code": false, "model": "gpt-4o-mini", "prompt": "{{prompt}}", "maxRounds": 1, "tools": [] } } }, "n_390a5027ba571d3d": { "inputs": { "text": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_f140388619bc8264", "output": "output" } ] } }, "name": "Publish on X", "kind": "task", "task": { "inputs": [ { "description": "The Tweet text content. Required unless another content source is provided.", "jsonSchema": { "type": "string", "description": "The Tweet text content. Required unless another content source is provided." }, "nullable": true, "handle": "text", "value": null }, { "description": "The card URI to attach to the Tweet.", "jsonSchema": { "type": "string", "description": "The card URI to attach to the Tweet." }, "nullable": true, "handle": "cardUri", "value": null }, { "description": "Whether to mark the Tweet as promoted-only nullcast content.", "jsonSchema": { "type": "boolean", "description": "Whether to mark the Tweet as promoted-only nullcast content." }, "nullable": true, "handle": "nullcast", "value": null }, { "description": "The place ID to attach to the Tweet.", "jsonSchema": { "type": "string", "description": "The place ID to attach to the Tweet." }, "nullable": true, "handle": "geoPlaceId", "value": null }, { "description": "The poll options to create with the Tweet.", "jsonSchema": { "type": "array", "items": { "type": "string", "description": "A string value." }, "description": "The poll options to create with the Tweet." }, "nullable": true, "handle": "pollOptions", "value": null }, { "description": "The Tweet ID to quote in the new Tweet.", "jsonSchema": { "type": "string", "description": "The Tweet ID to quote in the new Tweet." }, "nullable": true, "handle": "quoteTweetId", "value": null }, { "description": "Who can reply to the Tweet.", "jsonSchema": { "type": "string", "enum": [ "following", "mentionedUsers", "subscribers" ], "description": "Who can reply to the Tweet." }, "nullable": true, "handle": "replySettings", "value": null }, { "description": "The uploaded media IDs to attach to the Tweet.", "jsonSchema": { "type": "array", "items": { "type": "string", "description": "A string value." }, "description": "The uploaded media IDs to attach to the Tweet." }, "nullable": true, "handle": "mediaMediaIds", "value": null }, { "description": "Who can reply to the poll Tweet.", "jsonSchema": { "type": "string", "description": "Who can reply to the poll Tweet." }, "nullable": true, "handle": "pollReplySettings", "value": null }, { "description": "The user IDs to tag in the attached media.", "jsonSchema": { "type": "array", "items": { "type": "string", "description": "A string value." }, "description": "The user IDs to tag in the attached media." }, "nullable": true, "handle": "mediaTaggedUserIds", "value": null }, { "description": "The poll duration in minutes.", "jsonSchema": { "type": "integer", "description": "The poll duration in minutes." }, "nullable": true, "handle": "pollDurationMinutes", "value": null }, { "description": "The DM deep link to attach to the Tweet.", "jsonSchema": { "type": "string", "description": "The DM deep link to attach to the Tweet." }, "nullable": true, "handle": "directMessageDeepLink", "value": null }, { "description": "Whether to restrict the Tweet to super followers only.", "jsonSchema": { "type": "boolean", "description": "Whether to restrict the Tweet to super followers only." }, "nullable": true, "handle": "forSuperFollowersOnly", "value": null }, { "description": "The Tweet ID to reply to.", "jsonSchema": { "type": "string", "description": "The Tweet ID to reply to." }, "nullable": true, "handle": "replyInReplyToTweetId", "value": null }, { "description": "The user IDs to exclude from reply mentions.", "jsonSchema": { "type": "array", "items": { "type": "string", "description": "A string value." }, "description": "The user IDs to exclude from reply mentions." }, "nullable": true, "handle": "replyExcludeReplyUserIds", "value": null } ], "outputs": [ { "description": "The ID of the created Tweet.", "jsonSchema": { "type": "string", "description": "The ID of the created Tweet." }, "nullable": false, "handle": "id" }, { "description": "The text content of the created Tweet.", "jsonSchema": { "type": "string", "description": "The text content of the created Tweet." }, "nullable": false, "handle": "text" }, { "description": "The edit history Tweet IDs returned by the X API.", "jsonSchema": { "type": "array", "items": { "type": "string", "description": "A string value." }, "description": "The edit history Tweet IDs returned by the X API." }, "nullable": true, "handle": "editHistoryTweetIds" }, { "description": "The raw create Tweet response returned by the X API.", "jsonSchema": { "type": "object", "properties": {}, "additionalProperties": true, "description": "The raw create Tweet response returned by the X API." }, "nullable": false, "handle": "raw" } ], "name": "Publish on X", "executor": { "kind": "connector", "action": "twitter.creation_of_a_post" } } }, "n_9bcbb313f5c6e0b8": { "inputs": { "found": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_7b0b90adecdcd66e", "output": "found" } ] }, "id": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_390a5027ba571d3d", "output": "id" } ] }, "text": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_390a5027ba571d3d", "output": "text" } ] }, "videoId": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_7b0b90adecdcd66e", "output": "videoId" } ] } }, "name": "Confirm the post", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "found" }, { "jsonSchema": { "type": "string" }, "nullable": true, "handle": "id" }, { "jsonSchema": { "type": "string" }, "nullable": true, "handle": "text" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "videoId" } ], "outputs": [ { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "result" } ], "name": "Confirm the post", "moduleId": "n_348f56b446b9e8c2", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_c41e2276c354682c": { "inputs": {}, "name": "No recent video", "kind": "task", "task": { "inputs": [], "outputs": [ { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "result" } ], "name": "No recent video", "moduleId": "n_b7f26980de5c7414", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_6ceb8bc56c91adb9": { "name": "Return the outcome", "kind": "outputs", "outputDefs": [ { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "result" } ], "outputMappings": { "result": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_9bcbb313f5c6e0b8", "output": "result" }, { "kind": "node", "nodeId": "n_c41e2276c354682c", "output": "result" } ] } } } }, "edges": [ { "source": "n_5db573aa18594fb9", "target": "n_d19246ccbd478de7" }, { "source": "n_d19246ccbd478de7", "target": "n_fa530dc4450e9c79" }, { "source": "n_fa530dc4450e9c79", "target": "n_7b0b90adecdcd66e" }, { "source": "n_7b0b90adecdcd66e", "target": "n_810e521b180ed7e6" }, { "source": "n_810e521b180ed7e6", "target": "n_f140388619bc8264", "sourceHandle": "otherwise" }, { "source": "n_810e521b180ed7e6", "target": "n_c41e2276c354682c", "sourceHandle": "empty" }, { "source": "n_f140388619bc8264", "target": "n_390a5027ba571d3d" }, { "source": "n_390a5027ba571d3d", "target": "n_9bcbb313f5c6e0b8" }, { "source": "n_9bcbb313f5c6e0b8", "target": "n_6ceb8bc56c91adb9" }, { "source": "n_c41e2276c354682c", "target": "n_6ceb8bc56c91adb9" } ] } }, "modules": { "n_139cabfa28f5cc19": { "name": "Set channel and time window", "imports": [], "source": "export default function search({channelId}){if(typeof channelId!=='string'||!channelId.trim()||channelId==='YOUR_YOUTUBE_CHANNEL_ID')throw Error('Configure your YouTube channel ID');return{channelId:channelId.trim(),after:new Date(Date.now()-30*60000).toISOString()};}\n" }, "n_fb91f41b16038146": { "name": "Read the video", "imports": [], "source": "export default function video({body,statusCode}){if(statusCode!==200||!body||!Array.isArray(body.items))throw Error('YouTube search failed or returned invalid items');if(body.items.length===0)return{found:false,prompt:'',videoId:''};if(body.items.length!==1)throw Error('YouTube returned more than one video');const v=body.items[0],id=v?.id?.videoId,title=v?.snippet?.title,description=v?.snippet?.description;if(typeof id!=='string'||!id||typeof title!=='string'||typeof description!=='string')throw Error('YouTube result lacks video fields');return{found:true,videoId:id,prompt:`Write an engaging post about my latest YouTube video for X (Twitter) of no more than 140 characters in length. Link to the video at https://youtu.be/${id} use this title and description: ${title} ${description}`};}\n" }, "n_348f56b446b9e8c2": { "name": "Confirm the post", "imports": [], "source": "export default function result({found,id,text,videoId}){if(!found)return{result:{posted:false}};if(typeof id!=='string'||!id||typeof text!=='string')throw Error('X did not confirm the post; inspect the account before retrying');return{result:{posted:true,videoId,id,text}};}\n" }, "n_b7f26980de5c7414": { "name": "No recent video", "imports": [], "source": "export default function empty(){return{result:{posted:false}};}\n" } } }, "presentation": { "designer": { "version": 1, "flow": { "direction": "vertical" } } } }