0) {\n validation.platforms.push(platform);\n validation.hasContent = true;\n } else {\n validation.warnings.push(`Missing ${platform} content in field '${field}'`);\n }\n}\n\n// Validate media availability\nfor (const field of mediaFields) {\n if (data[field] && data[field].trim().length > 0) {\n validation.hasMedia = true;\n break;\n }\n}\n\nif (!validation.hasMedia) {\n validation.warnings.push('No media files available (image or video)');\n}\n\n// Critical validations\nif (!validation.hasContent) {\n validation.errors.push('No content available for any platform');\n}\n\nif (validation.platforms.length === 0) {\n validation.errors.push('No valid platforms found with content');\n}\n\n// Prepare cleaned content for each platform\nconst cleanedContent = {};\nfor (const [platform, field] of Object.entries(contentFields)) {\n if (data[field]) {\n // Enhanced content cleaning\n let content = data[field]\n .replace(/[\\n\\r\\t]+/g, ' ') // Line breaks and tabs\n .replace(/\\s{2,}/g, ' ') // Multiple spaces\n .replace(/[\"']/g, (match) => match === '\"' ? '\\\"' : \"'\") // Escape quotes\n .replace(/[\\\\]/g, '\\\\\\\\') // Escape backslashes\n .trim(); // Trim whitespace\n \n // Platform-specific length validation\n const limits = {\n twitter: 280,\n instagram: 2200,\n linkedin: 3000,\n facebook: 63206\n };\n \n if (content.length > limits[platform]) {\n validation.warnings.push(`${platform} content exceeds ${limits[platform]} characters (${content.length})`);\n content = content.substring(0, limits[platform] - 3) + '...';\n }\n \n cleanedContent[platform] = content;\n }\n}\n\nreturn [{\n json: {\n originalData: data,\n validation: validation,\n cleanedContent: cleanedContent,\n recordId: data.id,\n processedAt: new Date().toISOString(),\n mediaAvailable: {\n image: !!data['postiz image'],\n video: !!data['postiz video'],\n imagePath: data['postiz image'] || null,\n videoPath: data['postiz video'] || null\n }\n }\n}];"},"typeVersion":2},{"id":"b973a280-202c-4cc0-b691-e03506e525a0","name":"πŸ“‹ Content Availability Check1","type":"n8n-nodes-base.if","notes":"πŸ” Validates processed content\nβ€’ Ensures content exists for posting\nβ€’ Checks for critical validation errors\nβ€’ Routes to error handling if needed\nβ€’ Prevents unnecessary API calls","position":[960,1660],"parameters":{"options":{},"conditions":{"options":{"version":1,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"has_content","operator":{"type":"boolean","operation":"equals"},"leftValue":"={{ $json.validation.hasContent }}","rightValue":true},{"id":"no_errors","operator":{"type":"number","operation":"equals"},"leftValue":"={{ $json.validation.errors.length }}","rightValue":0}]}},"typeVersion":2},{"id":"bc714a0a-a511-466f-ac0c-754426bd12dc","name":"❌ Content Error1","type":"n8n-nodes-base.stopAndError","notes":"🚫 Handles missing/invalid content\nβ€’ Detailed validation results\nβ€’ Platform-specific feedback\nβ€’ Record identification\nβ€’ Debugging information","position":[1120,1840],"parameters":{"errorMessage":"No valid content found for posting"},"typeVersion":1},{"id":"b74388c2-6f88-4cf1-b098-88dad5287a37","name":"🎯 Upload","type":"n8n-nodes-base.webhook","notes":"πŸš€ Entry point for social media automation\nβ€’ Webhook URL: /webhook/328d95ae-3de0-41bf-a8bf-52071bdb36d3\nβ€’ Triggers entire posting workflow\nβ€’ Can be called from external systems\nβ€’ Starts both media upload and content posting processes","position":[780,300],"webhookId":"5f9b5e6f-cb89-44f5-ab63-81bb663b02e2","parameters":{"path":"328d95ae-3de0-41bf-a8bf-52071bdb36d3","options":{}},"typeVersion":2},{"id":"92997282-93db-4a88-889f-ef56e9b13f39","name":"Post","type":"n8n-nodes-base.webhook","position":[520,1380],"webhookId":"7263d416-6333-429d-9767-528fc6dced38","parameters":{"path":"7263d416-6333-429d-9767-528fc6dced38","options":{}},"typeVersion":2},{"id":"8c1ccf7a-8251-47d2-a378-3762aa8591bd","name":"Video","type":"n8n-nodes-base.webhook","position":[600,2740],"webhookId":"26fd48c7-7ef9-44ad-9816-feedd75426f4","parameters":{"path":"26fd48c7-7ef9-44ad-9816-feedd75426f4","options":{}},"typeVersion":2},{"id":"b1edc2de-fcea-4e8c-a924-bc9da4f36e3c","name":"πŸ“Š Fixed Results Processor","type":"n8n-nodes-base.code","notes":"πŸ“ˆ FIXED: Now correctly maps integration IDs to platforms\nβ€’ Uses your exact integration IDs from Switch node\nβ€’ Detects success via postId field\nβ€’ Tracks all platforms correctly\nβ€’ No more 'undefined' platforms!","position":[2100,1400],"parameters":{"jsCode":"// πŸ“Š FIXED RESULTS PROCESSOR (MINIMAL CHANGES)\nconst items = $input.all();\n\n// Integration ID to platform mapping (from your working Switch node)\nconst integrationToPlatform = {\n 'cmcotolny0001pnal2i86mkrh': { platform: 'instagram', account: 'main' },\n 'cmcg6ifpn001hmx9gakul0358': { platform: 'x', account: 'alt' },\n 'cmcf026ts0001mx9g6o8t5xc4': { platform: 'x', account: 'main' },\n 'cmcf02lp60003mx9gv2yff255': { platform: 'linkedin', account: 'main' },\n 'cmcf054k4000bmx9gg9va2ce1': { platform: 'facebook', account: 'main' },\n 'cmcouv8y00001kub0bb6cchea': { platform: 'youtube', account: 'main' }\n};\n\nconst results = {\n totalPosts: items.length,\n successful: 0,\n failed: 0,\n platforms: {},\n errors: [],\n postIds: [],\n executionSummary: {\n recordId: null,\n startTime: new Date().toISOString(),\n platforms: [],\n overallStatus: 'success'\n }\n};\n\n// Process each posting result\nfor (const item of items) {\n const response = item.json;\n \n // Get platform info from integration ID in the response\n const platformInfo = integrationToPlatform[response.integration] || { platform: 'unknown', account: 'main' };\n const platform = platformInfo.platform;\n const account = platformInfo.account;\n \n if (!results.platforms[platform]) {\n results.platforms[platform] = {\n attempted: 0,\n successful: 0,\n failed: 0,\n accounts: {}\n };\n }\n \n results.platforms[platform].attempted++;\n \n if (!results.platforms[platform].accounts[account]) {\n results.platforms[platform].accounts[account] = {\n status: 'unknown',\n postId: null,\n error: null,\n integrationId: response.integration\n };\n }\n \n // Check if the post was successful - Postiz returns 'postId' on success\n if (response.postId && response.postId.length > 0) {\n results.successful++;\n results.platforms[platform].successful++;\n results.platforms[platform].accounts[account].status = 'success';\n results.platforms[platform].accounts[account].postId = response.postId;\n results.postIds.push({\n platform: platform,\n account: account,\n postId: response.postId,\n integrationId: response.integration,\n url: response.url || null\n });\n } else {\n results.failed++;\n results.platforms[platform].failed++;\n results.platforms[platform].accounts[account].status = 'failed';\n \n // Extract error message\n let errorMessage = 'Unknown error';\n if (response.error) {\n errorMessage = typeof response.error === 'string' ? response.error : JSON.stringify(response.error);\n } else if (response.message) {\n errorMessage = response.message;\n } else if (!response.postId) {\n errorMessage = 'No post ID returned from Postiz';\n }\n \n results.platforms[platform].accounts[account].error = errorMessage;\n results.errors.push({\n platform: platform,\n account: account,\n error: errorMessage,\n integrationId: response.integration,\n details: response\n });\n }\n}\n\n// Set overall status\nif (results.failed > 0) {\n results.executionSummary.overallStatus = results.successful > 0 ? 'partial' : 'failed';\n}\n\n// Try to get record ID from Airtable node\ntry {\n const airtableData = $('πŸ“Š Content Database (Posts)1').first();\n if (airtableData && airtableData.json.id) {\n results.executionSummary.recordId = airtableData.json.id;\n }\n} catch (e) {\n console.log('Could not get record ID from Airtable node');\n}\n\nresults.executionSummary.platforms = Object.keys(results.platforms);\n\n// Add debug info\nresults.debug = {\n itemCount: items.length,\n sampleResponse: items[0]?.json || null,\n integrationMappings: Object.keys(integrationToPlatform).length,\n platformsProcessed: Object.keys(results.platforms)\n};\n\nreturn [{ json: results }];"},"typeVersion":2},{"id":"d1d3833e-2209-4c11-84de-a35ba7f1775d","name":"πŸ–ΌοΈ Image Upload to Postiz2","type":"n8n-nodes-base.httpRequest","notes":"πŸ”„ Uploads image files to Postiz storage\nβ€’ Endpoint: POST /upload\nβ€’ Content-Type: multipart-form-data\nβ€’ Input: Binary image data from Google Drive\nβ€’ Output: Postiz file ID and path for posts\nβ€’ Supports: JPG, PNG, GIF formats\nπŸ“± Used across Instagram, Twitter, LinkedIn, Facebook","position":[1880,520],"parameters":{"url":"=https://postiz.yourdomain.com/api/public/v1/upload","method":"POST","options":{},"sendBody":true,"contentType":"multipart-form-data","authentication":"genericCredentialType","bodyParameters":{"parameters":[{"name":"file","parameterType":"formBinaryData","inputDataFieldName":"data"}]},"genericAuthType":"httpHeaderAuth"},"credentials":{"httpHeaderAuth":{"id":"mEU0ecS6LOVkcowP","name":"Postiz"}},"typeVersion":4.2},{"id":"2786d270-9637-4773-9289-b4147bef6ba0","name":"πŸ’Ύ Save Image Path1","type":"n8n-nodes-base.airtable","notes":"πŸ”„ Updates Airtable with Postiz image path\nβ€’ Operation: Update record\nβ€’ Field: 'postiz image' = upload response path\nβ€’ Used by all image-based social posts\nβ€’ Maintains referential integrity\nπŸ“Š Enables tracking of media usage across platforms","position":[2100,520],"parameters":{"base":{"mode":"list","value":"appTFomwpoQ8GVsSo"},"table":{"mode":"list","value":"tblRnaXqxrvcQhqBw"},"columns":{"value":{"id":"={{ $('πŸ“Š Content Database (Media)').item.json.id }}","postiz_twitter":"={{ $json.path }}"},"schema":[{"id":"id","type":"string","display":true,"readOnly":true,"required":false,"displayName":"id","defaultMatch":true},{"id":"Name","type":"string","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"Name","defaultMatch":false,"canBeUsedToMatch":true},{"id":"recordid","type":"string","display":true,"removed":false,"readOnly":true,"required":false,"displayName":"recordid","defaultMatch":false,"canBeUsedToMatch":true},{"id":"google drive","type":"string","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"google drive","defaultMatch":false,"canBeUsedToMatch":true},{"id":"transcript","type":"string","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"transcript","defaultMatch":false,"canBeUsedToMatch":true},{"id":"initial script","type":"string","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"initial script","defaultMatch":false,"canBeUsedToMatch":true},{"id":"start","type":"boolean","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"start","defaultMatch":false,"canBeUsedToMatch":true},{"id":"upload media","type":"boolean","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"upload media","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Post to socials","type":"boolean","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"Post to socials","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Post shorts","type":"boolean","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"Post shorts","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Short form Video","type":"string","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"Short form Video","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Image for socials","type":"string","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"Image for socials","defaultMatch":false,"canBeUsedToMatch":true},{"id":"postiz image","type":"string","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"postiz image","defaultMatch":false,"canBeUsedToMatch":true},{"id":"postiz video","type":"string","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"postiz video","defaultMatch":false,"canBeUsedToMatch":true},{"id":"twitter image","type":"string","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"twitter image","defaultMatch":false,"canBeUsedToMatch":true},{"id":"postiz_twitter","type":"string","display":true,"removed":false,"readOnly":false,"required":false,"displayName":"postiz_twitter","defaultMatch":false,"canBeUsedToMatch":true},{"id":"Record ID","type":"string","display":true,"removed":false,"readOnly":true,"required":false,"displayName":"Record ID","defaultMatch":false,"canBeUsedToMatch":true},{"id":"youtube_title","type":"string","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"youtube_title","defaultMatch":false,"canBeUsedToMatch":true},{"id":"youtube_description","type":"string","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"youtube_description","defaultMatch":false,"canBeUsedToMatch":true},{"id":"youtube_thumbnail_text","type":"string","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"youtube_thumbnail_text","defaultMatch":false,"canBeUsedToMatch":true},{"id":"twitter single","type":"string","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"twitter single","defaultMatch":false,"canBeUsedToMatch":true},{"id":"twitter_thread","type":"string","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"twitter_thread","defaultMatch":false,"canBeUsedToMatch":true},{"id":"linkedin_post","type":"string","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"linkedin_post","defaultMatch":false,"canBeUsedToMatch":true},{"id":"facebook_post","type":"string","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"facebook_post","defaultMatch":false,"canBeUsedToMatch":true},{"id":"facebook_story_caption","type":"string","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"facebook_story_caption","defaultMatch":false,"canBeUsedToMatch":true},{"id":"instagram_post","type":"string","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"instagram_post","defaultMatch":false,"canBeUsedToMatch":true},{"id":"instagram_reel","type":"string","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"instagram_reel","defaultMatch":false,"canBeUsedToMatch":true},{"id":"tiktok_caption","type":"string","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"tiktok_caption","defaultMatch":false,"canBeUsedToMatch":true},{"id":"youtube_shorts_caption","type":"string","display":true,"removed":true,"readOnly":false,"required":false,"displayName":"youtube_shorts_caption","defaultMatch":false,"canBeUsedToMatch":true}],"mappingMode":"defineBelow","matchingColumns":["id"],"attemptToConvertTypes":false,"convertFieldsToString":false},"options":{},"operation":"update"},"typeVersion":2.1},{"id":"0a4e8a7d-efef-4771-abdd-1e998072b38a","name":"πŸ“₯ Download x image from Drive","type":"n8n-nodes-base.googleDrive","notes":"☁️ Downloads image from Google Drive\nβ€’ Input: Google Drive file ID from Airtable\nβ€’ Field: 'Image for socials'\nβ€’ Output: Binary image data\nβ€’ Used across all visual social platforms\nπŸ“± Optimized for social media dimensions","position":[1660,520],"parameters":{"fileId":"{{FILEID_ID}}","options":{},"operation":"download"},"typeVersion":3},{"id":"1d285bf8-dc2a-4a35-b364-990bcbd718de","name":"When clicking β€˜Execute workflow’","type":"n8n-nodes-base.manualTrigger","position":[880,440],"parameters":{},"typeVersion":1},{"id":"3a573341-05dd-45de-8db8-c3050877631b","name":"Edit Fields","type":"n8n-nodes-base.set","position":[1100,440],"parameters":{"options":{},"assignments":{"assignments":[{"id":"5150e645-480f-428a-b261-32d53ba9c0b3","name":"query.RecordId","type":"string","value":"recuoYjg4icStHsMK"}]}},"typeVersion":3.4}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"","connections":{"Post":{"main":[[{"node":"πŸ“Š Content Database (Posts)","type":"main","index":0}]]},"Video":{"main":[[{"node":"πŸ“Š Content Database (Video)","type":"main","index":0}]]},"Edit Fields":{"main":[[{"node":"πŸ“Š Content Database (Media)","type":"main","index":0}]]},"🎯 Upload":{"main":[[{"node":"πŸ“Š Content Database (Media)","type":"main","index":0}]]},"πŸ”— integrations":{"main":[[{"node":"πŸ”€ Platform Router","type":"main","index":0}]]},"🐦 X/Twitter Posts":{"main":[[{"node":"πŸ“Š Fixed Results Processor","type":"main","index":0}]]},"πŸ”€ Platform Router":{"main":[[{"node":"🧹 Instagram Content Cleaner","type":"main","index":0}],[{"node":"🐦 X/Twitter Posts","type":"main","index":0}],[{"node":"🐦 X/Twitter Alt Account","type":"main","index":0}],[{"node":"🧹 LinkedIn Content Cleaner","type":"main","index":0}],[{"node":"🧹 Facebook Content Cleaner","type":"main","index":0}]]},"πŸ’Ό LinkedIn Publisher":{"main":[[{"node":"πŸ“Š Fixed Results Processor","type":"main","index":0}]]},"πŸ“˜ Facebook Publisher":{"main":[[{"node":"πŸ“Š Fixed Results Processor","type":"main","index":0}]]},"πŸ“Έ Instagram Publisher":{"main":[[{"node":"πŸ“Š Fixed Results Processor","type":"main","index":0}]]},"🐦 X/Twitter Alt Account":{"main":[[{"node":"πŸ“Š Fixed Results Processor","type":"main","index":0}]]},"πŸ”€ Video Platform Router":{"main":[[{"node":"🧹 Instagram Video Cleaner","type":"main","index":0}],[{"node":"🧹 Facebook Video Cleaner","type":"main","index":0}],[{"node":"🎬 YouTube Publisher","type":"main","index":0}]]},"πŸ“Ή Video Upload to Postiz":{"main":[[{"node":"πŸ’Ύ Save Video Path","type":"main","index":0}]]},"🧹 Facebook Video Cleaner":{"main":[[{"node":"πŸ“˜ Facebook Video Publisher","type":"main","index":0}]]},"πŸ”— integrations (Branch 2)":{"main":[[{"node":"πŸ”€ Video Platform Router","type":"main","index":0}]]},"🧹 Instagram Video Cleaner":{"main":[[{"node":"πŸ“Ή Instagram Video Publisher","type":"main","index":0}]]},"πŸ“Š Content Database (Media)":{"main":[[{"node":"πŸ“₯ Download Video from Drive","type":"main","index":0},{"node":"πŸ“₯ Download Image from Drive","type":"main","index":0},{"node":"πŸ“₯ Download x image from Drive","type":"main","index":0}]]},"πŸ“Š Content Database (Posts)":{"main":[[{"node":"πŸ” Content Validator & Cleaner1","type":"main","index":0}]]},"πŸ“Š Content Database (Video)":{"main":[[{"node":"πŸ”— integrations (Branch 2)","type":"main","index":0}]]},"🧹 Facebook Content Cleaner":{"main":[[{"node":"πŸ“˜ Facebook Publisher","type":"main","index":0}]]},"🧹 LinkedIn Content Cleaner":{"main":[[{"node":"πŸ’Ό LinkedIn Publisher","type":"main","index":0}]]},"πŸ“₯ Download Image from Drive":{"main":[[{"node":"πŸ–ΌοΈ Image Upload to Postiz","type":"main","index":0}]]},"πŸ“₯ Download Video from Drive":{"main":[[{"node":"πŸ“Ή Video Upload to Postiz","type":"main","index":0}]]},"πŸ–ΌοΈ Image Upload to Postiz":{"main":[[{"node":"πŸ’Ύ Save Image Path","type":"main","index":0}]]},"🧹 Instagram Content Cleaner":{"main":[[{"node":"πŸ“Έ Instagram Publisher","type":"main","index":0}]]},"πŸ–ΌοΈ Image Upload to Postiz2":{"main":[[{"node":"πŸ’Ύ Save Image Path1","type":"main","index":0}]]},"πŸ“‹ Content Availability Check1":{"main":[[{"node":"πŸ”— integrations","type":"main","index":0}],[{"node":"❌ Content Error1","type":"main","index":0}]]},"πŸ“₯ Download x image from Drive":{"main":[[{"node":"πŸ–ΌοΈ Image Upload to Postiz2","type":"main","index":0}]]},"πŸ” Content Validator & Cleaner1":{"main":[[{"node":"πŸ“‹ Content Availability Check1","type":"main","index":0}]]},"When clicking β€˜Execute workflow’":{"main":[[{"node":"Edit Fields","type":"main","index":0}]]}}}'>
Kurt Bijl

Kurt Bijl

Multi-Platform Social Media Publisher with Airtable, Google Drive, and Postiz

πŸ“ POSTIZ MEDIA UPLOAD WORKFLOW

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

🎯 PURPOSE:
Automated media upload pipeline that downloads videos and images from Google Drive and uploads them to Postiz storage for social media posting.

πŸ”„ WORKFLOW PROCESS:

  1. Webhook triggers the workflow
  2. Fetch media metadata from Airtable
  3. Download video + image from Google Drive
  4. Upload both files to Postiz storage
  5. Save Postiz file paths back to Airtable

πŸ”§ TECHNICAL DETAILS:
β€’ API: Postiz /upload endpoint (multipart-form-data)
β€’ Storage: Converts Google Drive files β†’ Postiz URLs
β€’ Integration: Updates Airtable with Postiz paths
β€’ Required: All media must be uploaded before posting

πŸ“± SOCIAL MEDIA POSTING WORKFLOW

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

🎯 PURPOSE:
Automated multi-platform social media posting using Postiz API. Distributes content across Instagram, Twitter/X (2 accounts), LinkedIn, and Facebook with platform-specific content cleaning and formatting.

πŸ”„ COMPLETE WORKFLOW PROCESS:

  1. πŸ“Š Fetch social media content from Airtable database
  2. πŸ”— Get integration IDs for all connected social platforms
  3. πŸ”€ Route each platform to appropriate content processor
  4. 🧹 Clean content to prevent JSON formatting errors
  5. πŸ“± Post to respective social media platforms simultaneously

πŸ“‹ PLATFORM COVERAGE:
β€’ πŸ“Έ Instagram (Visual content + captions)
β€’ 🐦 Twitter/X Main Account (Text + images)
β€’ 🐦 Twitter/X Alt Account (Duplicate posting)
β€’ πŸ’Ό LinkedIn (Professional content)
β€’ πŸ“˜ Facebook (Meta ecosystem posting)

⚠️ CRITICAL CONTENT CLEANING:
β€’ Removes line breaks (\n), carriage returns (\r), tabs (\t)
β€’ Replaces multiple spaces with single spaces
β€’ Prevents 'JSON parameter needs to be valid JSON' errors
β€’ ESSENTIAL: Without cleaning, all API calls fail!

πŸ”§ TECHNICAL SPECIFICATIONS:
β€’ API: Postiz /posts endpoint (POST)
β€’ Authentication: HTTP Header Auth
β€’ Content-Type: application/json
β€’ Posting Type: Immediate ('now') + 1 minute delay
β€’ Media: References pre-uploaded Postiz image paths
β€’ Rate Limit: 30 requests/hour (API beta limitation)

πŸ”— DATA SOURCES:
β€’ Content: Airtable
β€’ Media: Pre-uploaded via separate media upload workflow
β€’ Fields: instagram_caption, linkedin_post, twitter single, facebook
β€’ Images: References 'postiz image' field paths

⚑ EXECUTION FLOW:
Airtable β†’ Integrations β†’ Platform Router β†’ Content Cleaners β†’ Social Publishers

🚨 TROUBLESHOOTING:
β€’ JSON Errors: Check content cleaning nodes
β€’ 500 Errors: Verify integration IDs and account connections
β€’ Missing Media: Ensure media upload workflow ran first
β€’ Rate Limits: Space out executions (30/hour limit)

πŸ”„ DEPENDENCIES:
β€’ Requires: Media upload workflow (for image/video paths)
β€’ Connects to: Analytics and monitoring workflows
β€’ Updates: Airtable with posting status and URLs

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

⚠️ CRITICAL NOTES:
β€’ Cannot use external URLs in Postiz posts
β€’ Files must be uploaded to google drive first - id referenced in airtable
β€’ Enables reference tracking for all platforms

πŸ“Š DATA FLOW:
Google Drive β†’ Download β†’ Postiz Upload β†’ Airtable Update

πŸ”— CONNECTS TO:
Main social media posting workflows that reference these uploaded file paths for Instagram, Twitter, LinkedIn, Facebook, and YouTube posting.

🎬 VIDEO POSTING WORKFLOW

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

🎯 PURPOSE:
Automated video content distribution across Instagram, Facebook, and YouTube using Postiz API. Specialized workflow for video content with platform-specific processing and cleaning.

πŸ”„ WORKFLOW EXECUTION:

  1. πŸ“Š Fetch video content from Airtable database (recuoYjg4icStHsMK)
  2. πŸ”— Get integration IDs for video-enabled platforms
  3. πŸ”€ Route platforms to appropriate video processors
  4. 🧹 Clean content for Instagram & Facebook (YouTube bypassed)
  5. πŸ“Ή Publish to video platforms simultaneously

πŸ“Ή PLATFORM COVERAGE:
β€’ πŸ“± Instagram: Video posts & Reels (βœ… Working)
β€’ πŸ“˜ Facebook: Video content (⚠️ Test mode)
β€’ 🎬 YouTube: Long-form videos (🚨 Broken)

⚑ EXECUTION FLOW:
Airtable β†’ Integrations β†’ Video Router β†’ [3 Parallel Paths]
β”œβ”€β”€ Instagram: Cleaner β†’ Publisher
β”œβ”€β”€ Facebook: Cleaner β†’ Publisher
└── YouTube: [Direct] β†’ Publisher

πŸ—„οΈ DATA SOURCE:
β€’ Base: Netkreatives.com
β€’ Table: Youtube tool
β€’ Video Field: 'post video'
β€’ Content Fields: instagram_caption, facebook

πŸ”§ TECHNICAL SPECS:
β€’ Method: POST
β€’ Auth: HTTP Header (Postiz credentials)
β€’ Timing: Immediate posting (+1 minute delay)
β€’ Media: Pre-uploaded video paths
β€’ Content-Type: application/json

Do you want to automate your business?

Let's talk about your project