{ "kind": "open-flow-workflow", "version": 1, "name": "AI Content to Slack", "content": { "modelVersion": 14, "document": { "bindings": {}, "graph": { "nodes": { "n_ee734cc06ed765f4": { "inputs": { "body": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_cf0268166497dff3", "output": "response" } ] } }, "name": "Return full content", "kind": "webhook-response" }, "n_2912ee9718666f29": { "name": "Content request", "kind": "webhook", "bodyFields": [ { "jsonSchema": { "type": "string" }, "nullable": true, "handle": "topic" }, { "jsonSchema": { "type": "string" }, "nullable": true, "handle": "type" }, { "jsonSchema": { "type": "string" }, "nullable": true, "handle": "language" }, { "jsonSchema": { "type": "string" }, "nullable": true, "handle": "tone" } ], "method": "POST", "options": { "responseBody": { "kind": "webhook-response", "nodeId": "n_ee734cc06ed765f4", "timeoutMs": 60000 } } }, "n_ac1fa8c3bcee0a48": { "inputs": { "body": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_2912ee9718666f29", "output": "body" } ] } }, "name": "Build content prompt", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "object" }, "nullable": false, "handle": "body" } ], "outputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "topic" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "contentType" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "language" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "prompt" } ], "name": "Build content prompt", "moduleId": "n_b01e2bf60d1698d4", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_833c50b44bb95125": { "inputs": { "prompt": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_ac1fa8c3bcee0a48", "output": "prompt" } ] } }, "name": "Generate content", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "items": { "type": "object" }, "type": "array" }, "nullable": true, "handle": "messages", "value": null }, { "jsonSchema": { "items": { "type": "object" }, "minItems": 1, "type": "array" }, "nullable": false, "handle": "template", "value": [ { "role": "system", "content": "You are an expert content writer. Produce high-quality, engaging content that provides real value to readers." }, { "role": "user", "content": "{{prompt}}" } ] }, { "jsonSchema": { "type": "object" }, "nullable": false, "handle": "model", "value": { "model": "claude-sonnet-4-6", "max_tokens": 2000 } }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "prompt" } ], "outputs": [ { "description": "Generated response.", "jsonSchema": { "type": "string" }, "nullable": false, "handle": "output" } ], "name": "Generate content", "executor": { "kind": "llm", "mode": "chat" } } }, "n_cf0268166497dff3": { "inputs": { "topic": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_ac1fa8c3bcee0a48", "output": "topic" } ] }, "contentType": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_ac1fa8c3bcee0a48", "output": "contentType" } ] }, "content": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_833c50b44bb95125", "output": "output" } ] } }, "name": "Prepare content delivery", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "topic" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "contentType" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "content" } ], "outputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "text" }, { "jsonSchema": { "type": "array", "items": { "type": "object", "properties": {}, "additionalProperties": true, "description": "A Slack Block Kit block object. Pass the block exactly as Slack documents it." }, "minItems": 1, "description": "Slack Block Kit blocks to render in the message." }, "nullable": false, "handle": "blocks" }, { "jsonSchema": { "type": "object" }, "nullable": false, "handle": "response" } ], "name": "Prepare content delivery", "moduleId": "n_62787c565cf5a514", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_49497a1d82cf9ca0": { "inputs": { "channelId": { "kind": "value", "value": "YOUR_SLACK_CHANNEL_ID" }, "text": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_cf0268166497dff3", "output": "text" } ] }, "blocks": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_cf0268166497dff3", "output": "blocks" } ] } }, "name": "Notify content team", "kind": "task", "task": { "inputs": [ { "description": "The Slack conversation or channel ID.", "jsonSchema": { "type": "string", "minLength": 1, "description": "The Slack conversation or channel ID." }, "nullable": false, "handle": "channelId" }, { "description": "Plain text message content. When blocks are provided, Slack uses this as notification and accessibility fallback text.", "jsonSchema": { "type": "string", "description": "Plain text message content. When blocks are provided, Slack uses this as notification and accessibility fallback text." }, "nullable": true, "handle": "text", "value": null }, { "description": "Slack Block Kit blocks to render in the message.", "jsonSchema": { "type": "array", "items": { "type": "object", "properties": {}, "additionalProperties": true, "description": "A Slack Block Kit block object. Pass the block exactly as Slack documents it." }, "minItems": 1, "description": "Slack Block Kit blocks to render in the message." }, "nullable": true, "handle": "blocks", "value": null }, { "description": "Slack legacy attachments to include in the message.", "jsonSchema": { "type": "array", "items": { "type": "object", "properties": {}, "additionalProperties": true, "description": "A Slack legacy attachment object. Prefer blocks for new messages when possible." }, "minItems": 1, "description": "Slack legacy attachments to include in the message." }, "nullable": true, "handle": "attachments", "value": null }, { "description": "Whether Slack should unfurl links in the message.", "jsonSchema": { "type": "boolean", "description": "Whether Slack should unfurl links in the message." }, "nullable": true, "handle": "unfurlLinks", "value": null }, { "description": "Whether Slack should unfurl media in the message.", "jsonSchema": { "type": "boolean", "description": "Whether Slack should unfurl media in the message." }, "nullable": true, "handle": "unfurlMedia", "value": null }, { "description": "Slack message metadata to attach to the message.", "jsonSchema": { "type": "object", "properties": {}, "additionalProperties": true, "description": "Slack message metadata to attach to the message." }, "nullable": true, "handle": "metadata", "value": null } ], "outputs": [ { "description": "The timestamp identifier of the posted message.", "jsonSchema": { "type": "string", "description": "The timestamp identifier of the posted message." }, "nullable": false, "handle": "ts" }, { "description": "The channel ID where the message was posted.", "jsonSchema": { "type": "string", "description": "The channel ID where the message was posted." }, "nullable": false, "handle": "channelId" } ], "name": "Notify content team", "executor": { "kind": "connector", "action": "slack.post_message" } } } }, "edges": [ { "source": "n_2912ee9718666f29", "target": "n_ac1fa8c3bcee0a48" }, { "source": "n_ac1fa8c3bcee0a48", "target": "n_833c50b44bb95125" }, { "source": "n_833c50b44bb95125", "target": "n_cf0268166497dff3" }, { "source": "n_cf0268166497dff3", "target": "n_49497a1d82cf9ca0" }, { "source": "n_49497a1d82cf9ca0", "target": "n_ee734cc06ed765f4" } ] } }, "modules": { "n_b01e2bf60d1698d4": { "name": "Build content prompt", "imports": [], "source": "export default function contentPrompt({ body }) {\n if (body === null || typeof body !== 'object' || Array.isArray(body)) throw new Error('Request body must be an object');\n for (const field of ['topic', 'type', 'language', 'tone']) {\n if (body[field] != null && typeof body[field] !== 'string') throw new Error(field + ' must be a string');\n }\n const topic = body.topic || 'AI automation trends';\n const contentType = ['blog', 'newsletter', 'social'].includes(body.type) ? body.type : 'blog';\n const language = body.language || 'English';\n const tone = body.tone || 'professional but approachable';\n const prompts = {\n blog: `Write a complete blog post about: \"${topic}\"\\n\\nRequirements:\\n- Title (H1)\\n- Introduction (2-3 sentences)\\n- 3 main sections with H2 headers\\n- Practical examples in each section\\n- Conclusion with call to action\\n- Tone: ${tone}\\n- Language: ${language}\\n- Length: ~600 words`,\n newsletter: `Write a newsletter issue about: \"${topic}\"\\n\\nRequirements:\\n- Catchy subject line\\n- Opening hook (1-2 sentences)\\n- 3 key insights with brief explanations\\n- One actionable tip\\n- Sign-off\\n- Tone: ${tone}\\n- Language: ${language}\\n- Length: ~300 words`,\n social: `Write 3 social media posts about: \"${topic}\"\\n\\nFor each post:\\n- Platform variant (Twitter/X, LinkedIn, Instagram)\\n- Different angle for each\\n- Relevant hashtags\\n- Tone: ${tone}\\n- Language: ${language}`,\n };\n return { topic, contentType, language, prompt: prompts[contentType] };\n}\n" }, "n_62787c565cf5a514": { "name": "Prepare content delivery", "imports": [], "source": "export default function contentResult({ topic, contentType, content }) {\n if (typeof content !== 'string' || !content.trim()) throw new Error('The model returned no content');\n const escape = (text) => text.replace(/&/g, '&').replace(//g, '>');\n const displayTopic = escape(topic.slice(0, 200));\n return {\n text: `✍️ New content generated for topic: *${displayTopic}*`,\n blocks: [\n { type: 'section', text: { type: 'mrkdwn', text: `✍️ *Content Ready*\\nTopic: ${displayTopic}\\nType: ${contentType}` } },\n { type: 'section', text: { type: 'mrkdwn', text: escape(content.slice(0, 500)) + '...' } },\n ],\n response: { status: 'success', topic, contentType, content },\n };\n}\n" } } }, "presentation": { "designer": { "version": 1, "flow": { "direction": "vertical" } } } }