{ "kind": "open-flow-workflow", "version": 1, "name": "Create and Update a Discourse Post", "content": { "modelVersion": 14, "document": { "bindings": {}, "graph": { "nodes": { "n_b24f0eb35794670c": { "name": "Enter topic details", "kind": "start", "inputDefs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "categoryId" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "title" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "initial" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "updated" } ] }, "n_75b3474e44f5a6e2": { "inputs": { "categoryId": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_b24f0eb35794670c", "output": "categoryId" } ] }, "title": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_b24f0eb35794670c", "output": "title" } ] }, "initial": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_b24f0eb35794670c", "output": "initial" } ] }, "updated": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_b24f0eb35794670c", "output": "updated" } ] } }, "name": "Validate topic details", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "categoryId" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "title" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "initial" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "updated" } ], "outputs": [ { "jsonSchema": { "type": "integer", "minimum": 1 }, "nullable": false, "handle": "categoryId" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "title" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "initial" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "updated" } ], "name": "Validate topic details", "moduleId": "n_4529feb5b645923e", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_6ab80b7a9691ba7f": { "inputs": { "categoryId": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_75b3474e44f5a6e2", "output": "categoryId" } ] }, "title": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_75b3474e44f5a6e2", "output": "title" } ] }, "initial": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_75b3474e44f5a6e2", "output": "initial" } ] } }, "name": "Create the topic", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "integer", "minimum": 1 }, "nullable": false, "handle": "categoryId" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "title" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "initial" } ], "outputs": [ { "jsonSchema": { "type": "object", "properties": { "id": { "type": "integer", "description": "The Discourse post identifier." }, "topicId": { "type": [ "integer", "null" ], "description": "The topic identifier for the post when present." }, "topicSlug": { "type": [ "string", "null" ], "description": "The topic slug for the post when present." }, "postNumber": { "type": [ "integer", "null" ], "description": "The one-based post number inside the topic when present." }, "replyToPostNumber": { "type": [ "integer", "null" ], "description": "The post number this post replies to when present." }, "username": { "type": [ "string", "null" ], "description": "The author's username when present." }, "displayUsername": { "type": [ "string", "null" ], "description": "The author's display username when present." }, "name": { "type": [ "string", "null" ], "description": "The author's display name when present." }, "createdAt": { "type": [ "string", "null" ], "description": "The timestamp when the post was created when present." }, "updatedAt": { "type": [ "string", "null" ], "description": "The timestamp when the post was updated when present." }, "cooked": { "type": [ "string", "null" ], "description": "The cooked HTML post body when present." }, "postType": { "type": [ "integer", "null" ], "description": "The Discourse post type value when present." }, "raw": { "type": "object", "properties": {}, "additionalProperties": true, "description": "The raw Discourse post payload." } }, "required": [ "id", "topicId", "topicSlug", "postNumber", "replyToPostNumber", "username", "displayUsername", "name", "createdAt", "updatedAt", "cooked", "postType", "raw" ], "additionalProperties": false, "description": "A Discourse post summary." }, "nullable": false, "handle": "post" }, { "jsonSchema": { "type": "object", "properties": {}, "additionalProperties": true, "description": "The raw Discourse created post payload." }, "nullable": false, "handle": "raw" } ], "name": "Create the topic", "moduleId": "n_36d1dda97b605c30", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [ { "action": "discourse.create_topic" } ] } ] } }, "n_6d307639f3b1f86b": { "inputs": { "post": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_6ab80b7a9691ba7f", "output": "post" } ] }, "updated": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_75b3474e44f5a6e2", "output": "updated" } ] } }, "name": "Prepare post update", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "object", "properties": { "id": { "type": "integer", "description": "The Discourse post identifier." }, "topicId": { "type": [ "integer", "null" ], "description": "The topic identifier for the post when present." }, "topicSlug": { "type": [ "string", "null" ], "description": "The topic slug for the post when present." }, "postNumber": { "type": [ "integer", "null" ], "description": "The one-based post number inside the topic when present." }, "replyToPostNumber": { "type": [ "integer", "null" ], "description": "The post number this post replies to when present." }, "username": { "type": [ "string", "null" ], "description": "The author's username when present." }, "displayUsername": { "type": [ "string", "null" ], "description": "The author's display username when present." }, "name": { "type": [ "string", "null" ], "description": "The author's display name when present." }, "createdAt": { "type": [ "string", "null" ], "description": "The timestamp when the post was created when present." }, "updatedAt": { "type": [ "string", "null" ], "description": "The timestamp when the post was updated when present." }, "cooked": { "type": [ "string", "null" ], "description": "The cooked HTML post body when present." }, "postType": { "type": [ "integer", "null" ], "description": "The Discourse post type value when present." }, "raw": { "type": "object", "properties": {}, "additionalProperties": true, "description": "The raw Discourse post payload." } }, "required": [ "id", "topicId", "topicSlug", "postNumber", "replyToPostNumber", "username", "displayUsername", "name", "createdAt", "updatedAt", "cooked", "postType", "raw" ], "additionalProperties": false, "description": "A Discourse post summary." }, "nullable": false, "handle": "post" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "updated" } ], "outputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "endpoint" }, { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "body" }, { "jsonSchema": { "type": "integer", "minimum": 1 }, "nullable": false, "handle": "postId" } ], "name": "Prepare post update", "moduleId": "n_8fe080a6ca8d04c2", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_1229767ab88df96f": { "inputs": { "endpoint": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_6d307639f3b1f86b", "output": "endpoint" } ] }, "body": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_6d307639f3b1f86b", "output": "body" } ] } }, "name": "Update the post", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "endpoint" }, { "jsonSchema": {}, "nullable": true, "handle": "body" } ], "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": "Update the post", "executor": { "providerId": "discourse", "method": "PUT", "query": { "mode": "fields", "names": [] }, "headers": { "mode": "fields", "names": [] }, "bodyFormat": "json", "kind": "connector-proxy" } } }, "n_0dfc08d309c03975": { "inputs": { "body": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_1229767ab88df96f", "output": "body" } ] }, "statusCode": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_1229767ab88df96f", "output": "statusCode" } ] }, "bodyEncoding": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_1229767ab88df96f", "output": "bodyEncoding" } ] }, "postId": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_6d307639f3b1f86b", "output": "postId" } ] } }, "name": "Confirm post update", "kind": "task", "task": { "inputs": [ { "jsonSchema": {}, "nullable": true, "handle": "body" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "statusCode" }, { "jsonSchema": { "const": "base64" }, "nullable": true, "handle": "bodyEncoding" }, { "jsonSchema": { "type": "integer", "minimum": 1 }, "nullable": false, "handle": "postId" } ], "outputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "endpoint" } ], "name": "Confirm post update", "moduleId": "n_e8eabd2ead9d355c", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_cb7a9452ccee345f": { "inputs": { "endpoint": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_0dfc08d309c03975", "output": "endpoint" } ] } }, "name": "Read the post", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "endpoint" } ], "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": "Read the post", "executor": { "providerId": "discourse", "method": "GET", "query": { "mode": "fields", "names": [] }, "headers": { "mode": "fields", "names": [] }, "bodyFormat": "none", "kind": "connector-proxy" } } }, "n_7a2c9dec35430cfe": { "inputs": { "body": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_cb7a9452ccee345f", "output": "body" } ] }, "statusCode": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_cb7a9452ccee345f", "output": "statusCode" } ] }, "bodyEncoding": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_cb7a9452ccee345f", "output": "bodyEncoding" } ] }, "postId": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_6d307639f3b1f86b", "output": "postId" } ] } }, "name": "Verify the post", "kind": "task", "task": { "inputs": [ { "jsonSchema": {}, "nullable": true, "handle": "body" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "statusCode" }, { "jsonSchema": { "const": "base64" }, "nullable": true, "handle": "bodyEncoding" }, { "jsonSchema": { "type": "integer", "minimum": 1 }, "nullable": false, "handle": "postId" } ], "outputs": [ { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "post" } ], "name": "Verify the post", "moduleId": "n_3cbc635d682e0632", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_d2c77480e971e17b": { "name": "Discourse post", "kind": "outputs", "outputDefs": [ { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "post" } ], "outputMappings": { "post": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_7a2c9dec35430cfe", "output": "post" } ] } } } }, "edges": [ { "source": "n_b24f0eb35794670c", "target": "n_75b3474e44f5a6e2" }, { "source": "n_75b3474e44f5a6e2", "target": "n_6ab80b7a9691ba7f" }, { "source": "n_6ab80b7a9691ba7f", "target": "n_6d307639f3b1f86b" }, { "source": "n_6d307639f3b1f86b", "target": "n_1229767ab88df96f" }, { "source": "n_1229767ab88df96f", "target": "n_0dfc08d309c03975" }, { "source": "n_0dfc08d309c03975", "target": "n_cb7a9452ccee345f" }, { "source": "n_cb7a9452ccee345f", "target": "n_7a2c9dec35430cfe" }, { "source": "n_7a2c9dec35430cfe", "target": "n_d2c77480e971e17b" } ] } }, "modules": { "n_4529feb5b645923e": { "name": "Validate topic details", "imports": [], "source": "export default function input({categoryId,title,initial,updated}){if(typeof categoryId!=='string'||!/^\\d+$/.test(categoryId)||!Number.isSafeInteger(Number(categoryId))||Number(categoryId)<1)throw Error('Enter a category ID');if([title,initial,updated].some(x=>typeof x!=='string'||!x.trim()))throw Error('Enter a title and both post bodies');return{categoryId:Number(categoryId),title,initial,updated};}\n" }, "n_36d1dda97b605c30": { "name": "Create the topic", "imports": [], "source": "export default async function create({categoryId,title,initial},context){return await context.actions.call('discourse.create_topic',{categoryId,title,raw:initial});}\n" }, "n_8fe080a6ca8d04c2": { "name": "Prepare post update", "imports": [], "source": "export default function prepare({post,updated}){const id=post?.id;if(!Number.isSafeInteger(id)||id<1)throw Error('Discourse returned no post ID');return{endpoint:'/posts/'+id+'.json',body:{post:{raw:updated}},postId:id};}\n" }, "n_e8eabd2ead9d355c": { "name": "Confirm post update", "imports": [], "source": "export default function updated({body,statusCode,bodyEncoding,postId}){if(statusCode!==200||bodyEncoding!=null||!body?.post||body.post.id!==postId)throw Error('Discourse did not confirm the updated post');return{endpoint:'/posts/'+postId+'.json'};}\n" }, "n_3cbc635d682e0632": { "name": "Verify the post", "imports": [], "source": "export default function result({body,statusCode,bodyEncoding,postId}){if(statusCode!==200||bodyEncoding!=null||!body||body.id!==postId)throw Error('Discourse did not return the same post');return{post:body};}\n" } } }, "presentation": { "designer": { "version": 1, "flow": { "direction": "vertical" } } } }