Content Automation System

A comprehensive n8n-powered content creation and publishing platform with AI-driven writing, image generation, multi-platform publishing, and Google Sheets calendar integration.

šŸŽÆ Core Features v2.0
  • āœ… AI-powered content research & writing
  • āœ… DALL-E 3 image generation
  • āœ… Multi-platform publishing
  • āœ… Google Sheets editorial calendar
  • āœ… Optimal time scheduling
  • āœ… Telegram bot control
  • āœ… Video script generation
šŸ“Š Supported Platforms 6 Platforms
  • šŸ’¼ LinkedIn (Personal & Company)
  • 🐦 Twitter/X
  • šŸ“˜ Facebook Business
  • šŸ“ø Instagram
  • šŸ“ WordPress
  • šŸŽ¬ Video (YouTube/TikTok ready)
šŸ¤– AI Integration GPT-4o
  • 🧠 OpenAI GPT-4o for writing
  • šŸŽØ DALL-E 3 for images
  • šŸ” SerpAPI for research
  • šŸ—£ļø ElevenLabs for voiceover
  • šŸ“ Custom persona training

System Workflow

šŸ“± Telegram
Command Input
→
šŸ“… Google Sheets
Calendar
↓
šŸŽÆ Master Trigger
Parse & Route
↓
šŸ’” Ideation
AI Brief
→
šŸ” Research
Web Data
→
āœļø Writing
GPT-4o
↓
šŸŽØ Images
DALL-E 3
→
šŸŽ¬ Video
Script + Voice
↓
šŸš€ Publish
6 Platforms
→
šŸ“Š Analytics
Track Results
Quick Start: This system requires n8n (self-hosted or cloud), API keys for OpenAI, and social media accounts. Estimated setup time: 2-3 hours for basic configuration, 4-5 hours for full production deployment.

System Architecture

Workflow Interconnection

Workflow Dependency Map
{
  "workflows": {
    "00-calendar-scheduler": {
      "triggers": ["schedule"],
      "calls": ["01-master-trigger"],
      "description": "Hourly check for scheduled content"
    },
    "01-master-trigger": {
      "triggers": ["telegram", "webhook"],
      "calls": ["02-ideate-research-write"],
      "description": "Entry point for all content requests"
    },
    "02-ideate-research-write": {
      "triggers": ["execute-workflow"],
      "calls": ["03-image-creation", "04-content-publisher"],
      "description": "Content strategy, research, and writing"
    },
    "03-image-creation": {
      "triggers": ["execute-workflow"],
      "calls": ["04-content-publisher"],
      "description": "AI image generation and storage"
    },
    "04-content-publisher": {
      "triggers": ["execute-workflow"],
      "calls": [],
      "description": "Multi-platform publishing"
    },
    "05-video-production": {
      "triggers": ["execute-workflow"],
      "calls": ["04-content-publisher"],
      "description": "Video script and voice generation"
    }
  }
}

Data Flow Schema

Stage Data Structure Storage Duration
Trigger Command + Metadata Memory <1s
Brief Strategy + Research Questions Memory 30-60s
Research SERP Data + Insights Memory 10-30s
Content Full Text + SEO Data Memory + S3 60-120s
Media Image URLs + Video Assets S3 30-90s
Published Post URLs + Analytics Google Sheets Permanent

External Services

OpenAI Required

Models: GPT-4o, DALL-E 3

Cost: ~$0.05-0.15 per content piece

Rate Limit: Tier-dependent (TPM)

AWS S3 Required

Purpose: Image storage

Cost: ~$0.023/GB/month

Region: Close to n8n instance

SerpAPI Optional

Purpose: Web research

Cost: $50-100/month

Alternative: Perplexity API

Workflow 01: Master Trigger & Orchestrator

Overview
JSON Code
Node Details

The entry point for all content creation requests. Accepts input from Telegram bot or Google Sheets calendar, parses commands, validates input, and routes to appropriate child workflows.

Dual Input Support: This workflow handles both immediate Telegram commands and scheduled Google Sheets entries, normalizing them into a common format for downstream processing.

Command Format

Telegram Command Structure
/create [account] [content_type] [topic/idea]

Examples:
/create linkedin-main carousel 5 tax tips for startups
/create twitter-tech thread Why AI won't replace accountants
/create wordpress-blog blog Complete GST registration guide
/create all standard Breaking news: New tax reforms

Input Parameters

Parameter Type Options Description
account string linkedin-main, linkedin-personal, twitter-tech, twitter-personal, facebook-business, instagram-main, wordpress-blog, all Target platform identifier
content_type string standard, carousel, thread, blog, video, story Format of content
topic string Free text Content subject matter
Complete Workflow JSON
{
  "name": "01 - Master Trigger (Dual Source)",
  "nodes": [
    {
      "parameters": {
        "updates": ["message"],
        "additionalFields": {}
      },
      "name": "Telegram Trigger",
      "type": "n8n-nodes-base.telegramTrigger",
      "typeVersion": 1,
      "position": [250, 200],
      "webhookId": "telegram-master-trigger"
    },
    {
      "parameters": {
        "jsCode": "// Detect trigger source and normalize\nconst telegramData = $input.first().json;\n\n// Check if this is from Telegram or Google Sheets\nif (telegramData.message) {\n  // Telegram source\n  const message = telegramData.message;\n  const text = message.text || '';\n  \n  // Parse command: /create [account] [type] [idea]\n  const commandRegex = /^\\/create\\s+(\\S+)\\s+(\\S+)\\s+(.+)$/i;\n  const match = text.match(commandRegex);\n  \n  if (!match) {\n    return [{\n      valid_command: false,\n      source: 'telegram',\n      chat_id: message.chat.id,\n      error: 'Invalid command format'\n    }];\n  }\n  \n  return [{\n    valid_command: true,\n    source: 'telegram',\n    account: match[1].toLowerCase(),\n    content_type: match[2].toLowerCase(),\n    idea: match[3],\n    chat_id: message.chat.id,\n    user_id: message.from.id,\n    timestamp: new Date().toISOString(),\n    persona_key: null,\n    priority: 'normal'\n  }];\n} else if (telegramData.source === 'google_sheets_calendar') {\n  // Google Sheets source (already formatted)\n  return [{\n    valid_command: true,\n    source: 'google_sheets',\n    ...telegramData\n  }];\n} else {\n  return [{\n    valid_command: false,\n    source: 'unknown',\n    error: 'Unrecognized trigger source'\n  }];\n}"
      },
      "name": "Normalize Input",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [450, 300]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
n              "id": "condition-1",
              "leftValue": "={{ $json.valid_command }}",
              "rightValue": "true",
              "operator": {
                "type": "boolean",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        }
      },
      "name": "Valid Input?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [650, 300]
    },
    {
      "parameters": {
        "chatId": "={{ $json.chat_id }}",
        "text": "āŒ Error: {{ $json.error }}\n\nTelegram format: /create [account] [type] [idea]\nOr use Google Sheets Calendar for scheduled posting.",
        "additionalFields": {}
      },
      "name": "Send Error",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1,
      "position": [650, 500]
    },
    {
      "parameters": {
        "chatId": "={{ $json.chat_id }}",
        "text": "=āœ… Request received from {{ $json.source === 'telegram' ? 'Telegram' : 'Content Calendar' }}!\n\nšŸŽÆ Account: {{ $json.account }}\nšŸ“ Type: {{ $json.content_type }}\nšŸ’” Topic: {{ $json.idea.substring(0, 50) }}...\nā° Priority: {{ $json.priority || 'normal' }}\n\n{{ $json.scheduled_time ? 'šŸ“… Scheduled for: ' + $json.scheduled_time : 'šŸš€ Starting immediately...' }}",
        "additionalFields": {}
      },
      "name": "Confirm Receipt",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1,
      "position": [850, 200]
    },
    {
      "parameters": {
        "workflowId": "02-ideate-research-write",
        "options": {}
      },
      "name": "Execute Content Workflow",
      "type": "n8n-nodes-base.executeWorkflow",
      "typeVersion": 1,
      "position": [1050, 200]
    }
  ],
  "connections": {
    "Telegram Trigger": {
      "main": [[{ "node": "Normalize Input", "type": "main", "index": 0 }]]
    },
    "Normalize Input": {
      "main": [[{ "node": "Valid Input?", "type": "main", "index": 0 }]]
    },
    "Valid Input?": {
      "main": [
        [{ "node": "Confirm Receipt", "type": "main", "index": 0 }],
        [{ "node": "Send Error", "type": "main", "index": 0 }]
      ]
    },
    "Confirm Receipt": {
      "main": [[{ "node": "Execute Content Workflow", "type": "main", "index": 0 }]]
    }
  }
}

Node Specifications

Telegram Trigger Webhook

Type: n8n-nodes-base.telegramTrigger

Webhook ID: telegram-master-trigger

Events: message

Output: Raw Telegram message object

Normalize Input (Code Node) JavaScript

Detects trigger source (Telegram vs Google Sheets) and normalizes into common schema. Validates command format using regex.

Valid Input? (If Node) Condition

Condition: $json.valid_command equals true

True Branch: Proceed to confirmation

False Branch: Send error message

Workflow 02: Ideate → Research → Write

Overview
Persona System
AI Prompts

The core content creation engine. Loads persona configuration, generates content strategy brief, conducts web research (optional), and produces platform-optimized content using GPT-4o.

Load Persona
→
AI Brief
→
Research?
Web Search
→
Analyze
→
AI Write

Processing Stages

Stage Duration Output Cost (USD)
Load Persona <1s Configuration object $0.00
AI Content Brief 5-10s Strategy + structure ~$0.02
Web Research 10-30s SERP data + insights ~$0.01
AI Writing 15-30s Complete content ~$0.05-0.10

Persona Configuration Schema

JavaScript Persona Object
const personas = {
  'professional_ceo': {
    name: 'Professional CEO',
    tone: 'authoritative, insightful, data-driven',
    style: 'business professional with personal touch',
    vocabulary: 'industry terminology, strategic frameworks',
    sentence_structure: 'mix of short punchy and detailed',
    emoji_usage: 'minimal, professional',
    cta_style: 'thought-provoking questions',
    linkedin_specific: 'focus on leadership, trends, culture',
    twitter_specific: 'concise insights, thread storytelling',
    wordpress_specific: 'comprehensive guides, SEO-optimized'
  },
  
  'thought_leader': {
    name: 'Thought Leader',
    tone: 'visionary, challenging, inspiring',
    style: 'provocative ideas with actionable insights',
    vocabulary: 'forward-thinking, disruptive, innovative',
    sentence_structure: 'rhetorical questions + strong opinions',
    emoji_usage: 'strategic for emphasis',
    cta_style: 'invite debate and discussion',
    linkedin_specific: 'contrarian takes, future predictions',
    twitter_specific: 'hot takes, viral hooks',
    wordpress_specific: 'deep dives, research-backed'
  },
  
  'tech_influencer': {
    name: 'Tech Influencer',
    tone: 'enthusiastic, knowledgeable, accessible',
    style: 'explaining complex tech simply',
    vocabulary: 'tech jargon explained, analogies',
    sentence_structure: 'problem-solution format',
    emoji_usage: 'tech-related emojis',
    cta_style: 'ask for experiences',
    linkedin_specific: 'tech trends, career advice',
    twitter_specific: 'quick tips, tool recommendations',
    wordpress_specific: 'tutorials, reviews, comparisons'
  },
  
  'seo_expert': {
    name: 'SEO Expert',
    tone: 'helpful, authoritative, comprehensive',
    style: 'structured, skimmable, keyword-rich',
    vocabulary: 'SEO terminology, action verbs',
    sentence_structure: 'H2/H3 hierarchy, bullet points',
    emoji_usage: 'section dividers',
    cta_style: 'downloadable resources',
    linkedin_specific: 'content marketing tips',
    twitter_specific: 'SEO quick wins',
    wordpress_specific: 'long-form, pillar content'
  }
};
Customization: When cloning workflows for different clients/accounts, modify the persona configuration in the "Load Persona Config" code node to match brand voice.

AI Content Brief Prompt

System Prompt for GPT-4o
You are a content strategist. Based on the persona below, analyze the content idea and create a detailed brief.

PERSONA: {{ $json.persona_config.name }}
TONE: {{ $json.persona_config.tone }}
STYLE: {{ $json.persona_config.style }}

ACCOUNT: {{ $json.account }}
CONTENT TYPE: {{ $json.content_type }}

Create a content brief including:
1. Angle/hook (what makes this interesting)
2. Key messages (3-5 points)
3. Target audience pain points
4. Research questions to investigate
5. Content structure outline
6. Visual requirements (image descriptions)
7. SEO keywords (if applicable)
8. Call-to-action recommendation

AI Writing Prompt

Content Generation Prompt
You are an expert content writer. Write content following these exact specifications:

PERSONA: {{ $json.persona_config.name }}
WRITING STYLE: {{ $json.persona_config.style }}
TONE: {{ $json.persona_config.tone }}
VOCABULARY: {{ $json.persona_config.vocabulary }}
SENTENCE STRUCTURE: {{ $json.persona_config.sentence_structure }}
EMOJI USAGE: {{ $json.persona_config.emoji_usage }}

CONTENT TYPE: {{ $json.content_type }}
PLATFORM: {{ $json.account }}

PLATFORM-SPECIFIC RULES:
{{ $json.account.includes('linkedin') ? $json.persona_config.linkedin_specific : '' }}
{{ $json.account.includes('twitter') ? $json.persona_config.twitter_specific : '' }}
{{ $json.account.includes('wordpress') ? $json.persona_config.wordpress_specific : '' }}

REQUIREMENTS:
- Hook/Opening must be compelling
- Include 3-5 key takeaways
- Use platform-appropriate formatting
- Include clear CTA
- Optimize for engagement
- If WordPress: Include SEO title, meta description, H2/H3 structure
- If LinkedIn Carousel: Structure as slide-by-slide with image descriptions
- If Twitter Thread: Number tweets, under 280 chars each

Workflow 03: Image Creation

Generates platform-optimized images using DALL-E 3, converts to binary, uploads to AWS S3, and returns public URLs for publishing.

Image Size Specifications

Platform Dimensions DALL-E Size Aspect Ratio
LinkedIn Feed 1200 x 627 1792x1024 1.91:1
LinkedIn Carousel 1080 x 1080 1024x1024 1:1
Twitter/X 1200 x 675 1792x1024 16:9
Instagram Feed 1080 x 1080 1024x1024 1:1
Instagram Story 1080 x 1920 1024x1792 9:16
Facebook 1200 x 630 1792x1024 1.91:1
WordPress Featured 1200 x 630 1792x1024 1.91:1

S3 Storage Structure

Bucket Organization
s3://your-content-bucket/
ā”œā”€ā”€ content-images/
│   ā”œā”€ā”€ 2024/
│   │   ā”œā”€ā”€ 01/
│   │   │   ā”œā”€ā”€ image_001_1705683600.png
│   │   │   └── ...
│   │   ā”œā”€ā”€ 02/
│   │   └── ...
│   └── ...
ā”œā”€ā”€ videos/
│   └── ...
└── assets/
    └── brand-templates/
Important: Configure S3 bucket with public read access for the content-images/ prefix or use CloudFront distribution for secure, cached delivery.

Workflow 04: Content Publisher

Publishes content to LinkedIn, Twitter/X, Facebook, Instagram, and WordPress with platform-specific formatting and API handling.

Platform API Specifications

LinkedIn API OAuth 2.0

Permissions: r_basicprofile, r_organization_social, w_organization_social, w_member_social

Rate Limit: 100 posts per 24 hours

Character Limit: 3,000 (posts), 125 (headlines)

Twitter/X API v2 OAuth 2.0

Access Level: Elevated (required for media uploads)

Rate Limit: 300 tweets per 3 hours

Character Limit: 280 per tweet (4,000 for Twitter Blue)

Instagram Graph API Graph API

Requirements: Business Account connected to Facebook Page

Rate Limit: 25 publishes per 24 hours

Aspect Ratios: 1.91:1 to 4:5 (photos), 9:16 (stories)

WordPress REST API Application Password

Authentication: Basic Auth with Application Password

Endpoint: /wp-json/wp/v2/posts

Features: SEO metadata, featured images, categories, tags

Workflow 05: Video Production

Creates video scripts, generates scene images, and produces voiceover using ElevenLabs. Outputs assets for manual assembly or automated video generation.

Video Production Pipeline

AI Script
→
Scene Breakdown
→
Voiceover
Scene Images
→
Video Assembly
→
Publish

ElevenLabs Configuration

Voice Generation API
{
  "model_id": "eleven_multilingual_v2",
  "text": "{{ script_text }}",
  "voice_settings": {
    "stability": 0.5,
    "similarity_boost": 0.75,
    "style": 0.3,
    "use_speaker_boost": true
  }
}
Voice Options: Use preset voices (Rachel, Domi, Bella) or create custom voice clone for brand consistency. Custom voices require 1-5 minutes of sample audio.

Workflow 00: Calendar Scheduler

Hourly scheduled workflow that checks Google Sheets for approved content due for publishing, calculates optimal posting times, and triggers the content creation pipeline.

Scheduler Logic

Filtering Algorithm
// Check every hour for content to publish
const now = new Date();
const currentHour = now.getHours();
const today = now.toISOString().split('T')[0];

// Filter criteria:
// 1. Status is 'approved' or 'scheduled'
// 2. Date is today
// 3. Optimal time hour matches current hour (±1 hour buffer)
// 4. Not already published or failed

const scheduledContent = rows.filter(row => {
  const status = row.Status?.toLowerCase();
  const rowDate = row.Date;
  const optimalTime = row.Optimal_Time ? new Date(row.Optimal_Time) : null;
  const optimalHour = optimalTime ? optimalTime.getHours() : null;
  
  const isReady = ['approved', 'scheduled'].includes(status);
  const isToday = rowDate === today;
  const isRightTime = optimalHour !== null ? 
    Math.abs(optimalHour - currentHour) <= 1 : true;
  
  return isReady && isToday && isRightTime;
});

Google Sheets Column Mapping

Column Header Data Type Auto/Manual
A Date Date (YYYY-MM-DD) Manual
B Time Time (HH:MM) Manual (optional)
C Platform String (dropdown) Manual
D Content_Type String (dropdown) Manual
E Topic String Manual
F Status String (dropdown) Auto-updated
G Optimal_Time DateTime Auto-calculated
H Persona String (dropdown) Manual
I Priority String (dropdown) Manual
J Created_By String Auto (Apps Script)
K Created_Date DateTime Auto (Apps Script)
L Published_URL String Auto-updated
M Error_Log String Auto-updated
N Content_ID String Auto (formula)

Google Sheets Integration

Setup Instructions

Step 1: Google Cloud Project Required
  1. Visit Google Cloud Console
  2. Create new project named ContentAutomation
  3. Enable APIs: Google Sheets API + Google Drive API
  4. Navigate to IAM & Admin → Service Accounts
  5. Create service account: n8n-content-calendar
  6. Role: Editor (or custom Sheets Editor)
  7. Create key → JSON → Download securely
Step 2: Sheet Configuration Required
  1. Create new Google Sheet named ContentCalendar
  2. Add column headers (A: Date through N: Content_ID)
  3. Set up data validation for dropdown columns (C, D, F, H, I)
  4. Apply conditional formatting for status colors
  5. Share with service account email (Editor access)
  6. Copy Sheet ID from URL: /d/SHEET_ID/edit

Apps Script Automation

Google Apps Script (Extensions → Apps Script)
function onEdit(e) {
  const sheet = e.source.getActiveSheet();
  if (sheet.getName() !== 'ContentCalendar') return;
  
  const row = e.range.getRow();
  const col = e.range.getColumn();
  
  // Auto-timestamp when Date is added
  if (col === 1 && row > 1) {
    const createdDateCell = sheet.getRange(row, 11);
    if (!createdDateCell.getValue()) {
      createdDateCell.setValue(new Date());
    }
    
    // Auto-calculate optimal time
    const platform = sheet.getRange(row, 3).getValue();
    const date = sheet.getRange(row, 1).getValue();
    if (platform && date) {
      const optimalTime = calculateOptimalTime(platform, date);
      sheet.getRange(row, 7).setValue(optimalTime);
    }
  }
  
  // Status change logging
  if (col === 6 && row > 1) {
    const newStatus = e.value;
    if (newStatus === 'published') {
      sheet.getRange(row, 12).setValue(new Date());
    }
  }
}

function calculateOptimalTime(platform, date) {
  const times = {
    'linkedin-main': [9, 12, 17],
    'twitter-tech': [8, 12, 17, 21],
    'facebook-business': [13, 19],
    'instagram-main': [11, 19],
    'wordpress-blog': [9, 14]
  };
  
  const hours = times[platform] || [10];
  const randomHour = hours[Math.floor(Math.random() * hours.length)];
  const randomMinute = Math.floor(Math.random() * 60);
  
  const result = new Date(date);
  result.setHours(randomHour, randomMinute, 0);
  return result;
}

Telegram Bot Commands

Command Reference

Command Format Example Description
/create /create [account] [type] [topic] /create linkedin-main carousel 5 tax tips Create and publish content immediately
/schedule /schedule [account] [type] [date] [topic] /schedule twitter-tech thread 2024-01-20 AI trends Add to Google Sheets calendar
/status /status [content_id] /status 20240115-abc123 Check content status
/accounts /accounts /accounts List available accounts
/help /help /help Show detailed help

BotFather Configuration

Command List for @BotFather
setcommands

start - Start the bot and see welcome message
create - Create content immediately (format: /create account type idea)
schedule - Schedule content for later (format: /schedule account type date idea)
status - Check status of content by ID
accounts - List all available social media accounts
help - Show detailed help and examples
Webhook Setup: After deploying n8n, set webhook URL:
https://your-n8n-instance.com/webhook/telegram-master-trigger

API Credentials Matrix

Service Type Cost Rate Limits Priority
OpenAI API Key Pay-per-use Tier-dependent Critical
Telegram Bot Token Free 30 msgs/sec Critical
AWS S3 Access Key Storage + bandwidth 3,500 PUTs/sec Critical
LinkedIn OAuth 2.0 Free 100 posts/day Platform
Twitter/X OAuth 2.0 Free-$5000/mo 300 tweets/3hrs Platform
Facebook/IG Graph API Free 25 posts/day Platform
WordPress App Password Free Server-dependent Platform
SerpAPI API Key $50/mo+ 5,000 searches/mo Optional
ElevenLabs API Key $5/mo+ Character limits Video

Credential Setup in n8n

OpenAI Configuration

Name: OpenAI Account

API Key: sk-...

Base URL: https://api.openai.com/v1

Google Sheets Service Account

Name: Google Sheets Account

Type: Service Account

Email: n8n-content-calendar@...

Private Key: -----BEGIN PRIVATE KEY-----...

Persona Configuration

Define writing styles, tones, and platform-specific rules for each brand voice.

Professional CEO B2B

Tone: Authoritative, insightful, data-driven

Style: Business professional with personal touch

Best for: LinkedIn company pages, industry leadership

Thought Leader Influencer

Tone: Visionary, challenging, inspiring

Style: Provocative ideas with actionable insights

Best for: Personal LinkedIn, Twitter, opinion pieces

Tech Influencer Tech

Tone: Enthusiastic, knowledgeable, accessible

Style: Explaining complex tech simply

Best for: Developer tools, SaaS products, tutorials

Visual Storyteller Creative

Tone: Inspiring, aesthetic, narrative-driven

Style: Story-first approach

Best for: Instagram, lifestyle brands, behind-scenes

SEO Expert Content

Tone: Helpful, authoritative, comprehensive

Style: Structured, skimmable, keyword-rich

Best for: WordPress blogs, long-form content, guides

Optimal Posting Times

Platform Best Days Peak Times Timezone
LinkedIn Tue, Wed, Thu 8-10am, 12-2pm, 5-6pm Audience local time
Twitter/X Mon-Thu 8-10am, 12-1pm, 5-7pm, 9-11pm Audience local time
Facebook Wed, Thu, Fri 1-4pm, 7-9pm Audience local time
Instagram Sat, Sun 7-9am, 11am-1pm, 7-9pm Audience local time
WordPress Tue, Thu 9-11am, 2-4pm Audience local time
Time Calculation Algorithm
function calculateOptimalTime(platform, targetDate, timezone = 'Asia/Kolkata') {
  const schedules = {
    'linkedin-main': {
      slots: [
        { start: 8, end: 10, weight: 0.9 },
        { start: 12, end: 14, weight: 1.0 },
        { start: 17, end: 18, weight: 0.8 }
      ],
      bestDays: [1, 2, 3] // Mon-Wed
    },
    'twitter-tech': {
      slots: [
        { start: 8, end: 10, weight: 0.8 },
        { start: 12, end: 13, weight: 0.9 },
        { start: 17, end: 19, weight: 1.0 },
        { start: 21, end: 23, weight: 0.85 }
      ],
      bestDays: [0, 1, 2, 3]
    }
    // ... additional platforms
  };
  
  // Weighted random selection within best slots
  const config = schedules[platform];
  const totalWeight = config.slots.reduce((sum, s) => sum + s.weight, 0);
  let random = Math.random() * totalWeight;
  
  const selected = config.slots.find(slot => {
    random -= slot.weight;
    return random <= 0;
  });
  
  // Random minute within selected hour range
  const hour = selected.start + Math.random() * (selected.end - selected.start);
  const minute = Math.floor(Math.random() * 60);
  
  const result = new Date(targetDate);
  result.setHours(Math.floor(hour), minute, 0, 0);
  
  return result.toLocaleString('en-US', { timeZone: timezone });
}

Setup Guide

Step 1: Infrastructure

Docker Compose (Recommended)
version: '3.8'

services:
  n8n:
    image: n8nio/n8n:latest
    restart: always
    ports:
      - "5678:5678"
    environment:
      - N8N_BASIC_AUTH_ACTIVE=true
      - N8N_BASIC_AUTH_USER=admin
      - N8N_BASIC_AUTH_PASSWORD=your_secure_password
      - N8N_PROTOCOL=https
      - N8N_HOST=automation.yourdomain.com
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n
      - DB_POSTGRESDB_PASSWORD=db_password
      - N8N_ENCRYPTION_KEY=your_32_char_encryption_key
    volumes:
      - ~/.n8n:/home/node/.n8n
    depends_on:
      - postgres

  postgres:
    image: postgres:14-alpine
    restart: always
    environment:
      - POSTGRES_USER=n8n
      - POSTGRES_PASSWORD=db_password
      - POSTGRES_DB=n8n
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

Step 2: Install n8n

Installation Commands
# Create directory
mkdir ~/n8n-automation && cd ~/n8n-automation

# Save docker-compose.yml above
nano docker-compose.yml

# Start services
docker-compose up -d

# Check logs
docker-compose logs -f n8n

# Access at https://your-server-ip:5678

Step 3: Import Workflows

  1. Open n8n web interface
  2. Workflows → Import from File
  3. Import in order: 00, 01, 02, 03, 04, 05
  4. Update credential references in each workflow
  5. Activate workflows (toggle in top right)

Step 4: Configure Webhooks

Telegram Webhook Setup
# Set webhook
curl -F "url=https://your-n8n-instance.com/webhook/telegram-master-trigger" \
     https://api.telegram.org/botYOUR_BOT_TOKEN/setWebhook

# Verify
curl https://api.telegram.org/botYOUR_BOT_TOKEN/getWebhookInfo

Deployment Checklist

Pre-Deployment

  • Server provisioned (2 vCPU, 4GB RAM minimum)
  • Domain name configured with SSL
  • DNS A record pointing to server IP
  • Firewall rules: 443 (HTTPS), 5678 (n8n) open
  • Docker and Docker Compose installed

Credentials

  • OpenAI API key generated and funded
  • Telegram Bot created via BotFather
  • LinkedIn Developer App created and approved
  • Twitter Developer account approved (Elevated)
  • Facebook Business Manager verified
  • Instagram Business Account connected
  • WordPress Application Password generated
  • AWS Account with S3 bucket created
  • Google Cloud project with Sheets API enabled

Configuration

  • All workflow JSON files imported
  • Credentials created in n8n for all services
  • Google Sheet shared with service account
  • Sheet ID updated in all Google Sheets nodes
  • S3 bucket policy configured for public read
  • Persona configurations customized

Testing

  • Telegram webhook set successfully
  • Test message received in n8n
  • OpenAI connection test passed
  • Image generation test passed
  • S3 upload test passed
  • LinkedIn test post (draft) successful
  • Twitter test tweet successful
  • WordPress test post (draft) successful
  • Google Sheets calendar read test passed
Go-Live: After completing all checks, activate the Schedule Trigger in Workflow 00 to enable automated calendar publishing.

Troubleshooting

OpenAI Rate Limit Error

Symptom: 429 errors in OpenAI nodes

Solution: Add Wait node with exponential backoff, or upgrade to paid tier for higher TPM limits

LinkedIn Token Expired Auth

Symptom: 401 errors on publish

Solution: OAuth tokens expire every 60 days. Reconnect credential in n8n UI

Twitter Duplicate Content

Symptom: 403 error: duplicate content

Solution: Add unique timestamp or hash to each tweet content

Instagram Aspect Ratio Media

Symptom: Media upload failed

Solution: Ensure images are between 1.91:1 and 4:5 aspect ratio

S3 Permission Denied Storage

Symptom: 403 on image upload

Solution: Update bucket CORS policy and IAM permissions

Debug Commands

Useful Commands
# Check n8n health
curl http://localhost:5678/healthz

# View recent logs
docker logs n8n --tail 100

# Reset Telegram webhook
curl -F "url=" https://api.telegram.org/bot/setWebhook

# Test OpenAI
curl https://api.openai.com/v1/models \
  -H "Authorization: Bearer $OPENAI_API_KEY"

# Check S3 access
aws s3 ls s3://your-bucket/content-images/