How to Build an AI Sports Handicapping Marketing Agent with n8n (Free Template)

How to Build an AI Sports Handicapping Marketing Agent with n8n (Free Template)

Sports handicapping companies face a unique challenge: converting winning picks into engaging social content fast enough to capitalize on momentum. Manual screenshot editing, caption writing, and posting eats up hours that should be spent on analysis. This AI marketing agent solves that problem by automating the entire content pipeline from betting screenshots to published Instagram stories. You'll learn how to build a complete system that maintains your brand voice while scaling output 10x.

The Problem: Manual Content Creation Kills Marketing Momentum

Sports handicapping marketing requires speed and consistency. A winning pick needs to become social proof within minutes, not hours.

Current challenges:

  • Screenshots sit in folders for hours before someone edits them
  • Caption quality varies wildly depending on who writes it
  • Brand voice inconsistency confuses followers and reduces trust
  • Manual posting means missing optimal engagement windows
  • Creating email campaigns from winning picks takes 2-3 hours per send
  • No systematic way to test different offers and CTAs

Business impact:

  • Time spent: 15-20 hours/week on content creation and posting
  • Missed revenue: Late posts lose 60-70% of potential engagement
  • Inconsistent output: 3-5 posts/week instead of daily content
  • Brand dilution: Multiple writers create voice inconsistency

The manual process can't scale. You need automation that preserves quality while multiplying output.

The Solution Overview

This n8n AI agent creates a complete marketing automation pipeline. It receives betting screenshots, processes them with AI vision models, generates brand-consistent captions and graphics, and prepares Instagram-ready content packages. The system uses OpenAI's GPT-4 for copywriting, integrates with design tools for graphics, and connects to Instagram's API for automated posting. The workflow maintains a brand voice database that learns from your best-performing content. You'll build a system that turns one screenshot into multiple content formats—Stories, Reels, emails, and engagement posts—in under 60 seconds.

What You'll Build

This AI marketing agent handles the complete content creation and distribution pipeline for sports handicapping companies.

Component Technology Purpose
Screenshot Ingestion Webhook/Email Parser Receives betting screenshots automatically
AI Vision Analysis OpenAI GPT-4 Vision Extracts pick details, odds, and context
Content Generation OpenAI GPT-4 Writes captions, CTAs, email copy
Brand Voice Engine Vector Database (Pinecone/Supabase) Maintains consistent tone across content
Design Automation Canva API/Bannerbear Creates Instagram-ready graphics
Social Scheduling Instagram Graph API/Buffer Publishes Stories, Reels, and posts
Email Marketing Klaviyo/Mailchimp API Sends automated campaigns
Performance Tracking Google Sheets/Airtable Logs content and engagement metrics

Key capabilities:

  • Transform screenshots into 5+ content variations in 60 seconds
  • Generate captions that match your established brand voice
  • Create custom graphics with your branding automatically
  • Draft email campaigns from winning picks
  • Suggest A/B test variations for offers and CTAs
  • Produce engagement content (polls, questions, challenges)
  • Maintain content calendar and posting schedule

Prerequisites

Before starting, ensure you have:

  • n8n instance (cloud or self-hosted)
  • OpenAI API account with GPT-4 Vision access
  • Instagram Business account with Graph API credentials
  • Canva Pro account or Bannerbear API access
  • Email marketing platform (Klaviyo or Mailchimp) with API key
  • Google Drive or Dropbox for screenshot storage
  • Pinecone or Supabase account for vector database (brand voice storage)
  • Basic JavaScript knowledge for Function nodes
  • Understanding of prompt engineering for consistent AI outputs

Step 1: Set Up Screenshot Ingestion Pipeline

The workflow starts by receiving betting screenshots through multiple channels. You need flexible input methods because screenshots come from various sources—mobile uploads, email forwards, or direct API submissions.

Configure Webhook Trigger

  1. Add a Webhook node as your primary trigger
  2. Set HTTP Method to POST
  3. Enable "Respond Immediately" to confirm receipt
  4. Configure authentication with a secret token

Node configuration:

{
  "httpMethod": "POST",
  "path": "sports-screenshot-intake",
  "authentication": "headerAuth",
  "responseMode": "responseNode",
  "options": {
    "allowedOrigins": "https://yourdomain.com"
  }
}

Add Email Parser Alternative

  1. Create an Email Trigger node for forwarded screenshots
  2. Configure IMAP settings for your dedicated intake email
  3. Set filter for subject line containing "Pick" or "Screenshot"
  4. Extract attachments automatically

Why this works:
Multiple intake methods ensure no screenshot gets lost. The webhook handles automated submissions from betting platforms. The email parser catches manual forwards from your phone or team members. Both routes converge into the same processing pipeline.

Set Up File Storage

  1. Add a Google Drive or Dropbox node
  2. Create folder structure: /screenshots/raw/[date]/
  3. Upload incoming images with timestamp naming
  4. Generate shareable links for downstream processing

This creates an audit trail and backup system. Every screenshot is preserved with metadata before AI processing begins.

Step 2: AI Vision Analysis and Data Extraction

GPT-4 Vision extracts structured data from betting screenshots. This eliminates manual data entry and ensures accuracy.

Configure OpenAI Vision Node

  1. Add an OpenAI node set to GPT-4 Vision model
  2. Pass the screenshot URL from previous step
  3. Use structured prompt for consistent extraction

Extraction prompt template:

Analyze this sports betting screenshot and extract:
- Sport and league
- Teams/players involved
- Bet type (spread, moneyline, over/under, prop)
- Odds and stake amount
- Timestamp of bet placement
- Current status (pending, won, lost)
- Any visible profit/loss amounts

Return as JSON with these exact keys:
{
  "sport": "",
  "league": "",
  "matchup": "",
  "bet_type": "",
  "selection": "",
  "odds": "",
  "stake": "",
  "status": "",
  "profit_loss": "",
  "timestamp": ""
}

Add Data Validation Function

  1. Insert a Function node after OpenAI
  2. Validate all required fields are present
  3. Format odds consistently (American format)
  4. Calculate implied probability and potential payout

Function node code:

const data = $input.item.json;

// Validate required fields
const required = ['sport', 'matchup', 'bet_type', 'odds', 'stake'];
const missing = required.filter(field => !data[field]);

if (missing.length > 0) {
  throw new Error(`Missing required fields: ${missing.join(', ')}`);
}

// Standardize odds format
data.odds_formatted = data.odds.startsWith('+') || data.odds.startsWith('-') 
  ? data.odds 
  : `+${data.odds}`;

// Calculate potential payout
const stake = parseFloat(data.stake.replace(/[^0-9.]/g, ''));
const odds = parseInt(data.odds_formatted);
data.potential_payout = odds > 0 
  ? (stake * (odds / 100)).toFixed(2)
  : (stake / (Math.abs(odds) / 100)).toFixed(2);

return { json: data };

Why this approach:
Vision AI eliminates transcription errors that plague manual data entry. Structured JSON output feeds directly into content generation. Validation catches edge cases before they break downstream processes. Consistent formatting ensures graphics render correctly.

Step 3: Brand Voice Engine and Content Generation

The brand voice engine maintains consistency across all generated content. It uses vector similarity search to match new content against your best-performing historical posts.

Build Brand Voice Database

  1. Add a Pinecone or Supabase Vector Store node
  2. Create embeddings from your top 50-100 posts
  3. Store with metadata: engagement rate, post type, offer details

Initial setup code:

// Sample brand voice entries
const brandSamples = [
  {
    text: "🔥 ANOTHER WINNER! Lakers -4.5 CASHES. That's 7-2 this week. Link in bio for tomorrow's locks.",
    metadata: { engagement_rate: 8.2, post_type: "win_announcement", tone: "confident" }
  },
  {
    text: "Breaking down tonight's Celtics game. Why the over 218.5 is the play. Full analysis in stories.",
    metadata: { engagement_rate: 6.5, post_type: "analysis_preview", tone: "educational" }
  }
  // Add 48-98 more samples
];

// Generate embeddings and store
for (const sample of brandSamples) {
  const embedding = await generateEmbedding(sample.text);
  await vectorStore.upsert({
    id: generateId(),
    values: embedding,
    metadata: sample.metadata
  });
}

Configure Content Generation Chain

  1. Add OpenAI node for caption generation
  2. Query vector database for similar high-performing content
  3. Inject brand voice examples into prompt context
  4. Generate 3-5 caption variations

Caption generation prompt:

You are a sports handicapping content creator. Generate Instagram captions for this winning bet:

BET DETAILS:
${JSON.stringify(extractedData)}

BRAND VOICE EXAMPLES (high engagement):
${brandVoiceExamples.map(ex => `- ${ex.text} (${ex.metadata.engagement_rate}% engagement)`).join('
')}

Generate 3 caption variations:
1. Celebration post (short, punchy, emoji-heavy)
2. Educational breakdown (explain the reasoning)
3. Call-to-action (drive link clicks)

Each caption must:
- Match the confident, knowledgeable tone from examples
- Include relevant emoji (max 3)
- End with clear CTA
- Be under 150 characters for Stories

Return as JSON array.

Add Offer and CTA Generator

  1. Create a Function node to rotate offers
  2. Pull from predefined offer library
  3. Match offer type to content context (win = social proof, analysis = expertise)

Variables to customize:

  • tone_intensity: Adjust from "conservative" to "aggressive" based on audience
  • emoji_density: Control emoji usage (0-5 per caption)
  • cta_rotation: Cycle through different calls-to-action to prevent fatigue

Step 4: Design Automation and Graphics Creation

Transform extracted data and captions into Instagram-ready graphics using Canva API or Bannerbear.

Configure Canva API Integration

  1. Add HTTP Request node for Canva API
  2. Select template ID for Instagram Story format (1080x1920)
  3. Map data fields to template placeholders

API request structure:

{
  "method": "POST",
  "url": "https://api.canva.com/v1/designs/{{templateId}}/autofill",
  "headers": {
    "Authorization": "Bearer {{canvaApiKey}}",
    "Content-Type": "application/json"
  },
  "body": {
    "data": {
      "matchup": "{{$json.matchup}}",
      "bet_type": "{{$json.bet_type}}",
      "odds": "{{$json.odds_formatted}}",
      "status": "{{$json.status}}",
      "profit": "{{$json.potential_payout}}",
      "caption": "{{$json.selected_caption}}"
    }
  }
}

Create Multiple Format Variations

  1. Add a Loop node to generate 3-5 design variations
  2. Cycle through different template IDs (Story, Reel, Feed Post)
  3. Adjust text sizing and positioning per format

Template mapping table:

Format Dimensions Template Use Case Key Elements
Story 1080x1920 Quick win announcements Large odds, minimal text
Reel Cover 1080x1920 Video thumbnail Bold headline, team logos
Feed Post 1080x1080 Detailed breakdowns Stats table, analysis text
Email Header 600x400 Campaign graphics Branding, offer highlight

Add Branding Overlay

  1. Insert Function node to add watermark
  2. Overlay logo in consistent position
  3. Add website URL footer to all graphics

Why this works:
Template-based design ensures brand consistency while allowing content variation. Multiple format generation from one data source maximizes content output. Automated branding prevents the "forgot to add logo" mistake that dilutes brand recognition.

Workflow Architecture Overview

This workflow consists of 47 nodes organized into 6 main sections:

  1. Screenshot ingestion (Nodes 1-8): Webhook and email triggers receive screenshots, upload to cloud storage, generate shareable URLs
  2. AI vision processing (Nodes 9-15): GPT-4 Vision extracts bet details, validates data, calculates payouts
  3. Brand voice matching (Nodes 16-24): Vector database queries find similar high-performing content, injects examples into generation context
  4. Content generation (Nodes 25-35): Creates 3-5 caption variations, generates CTAs, produces email copy, drafts engagement posts
  5. Design automation (Nodes 36-42): Canva API creates graphics in multiple formats, adds branding overlays
  6. Distribution preparation (Nodes 43-47): Formats content for Instagram API, schedules posts, logs to tracking sheet

Execution flow:

  • Trigger: Webhook POST or new email with attachment
  • Average run time: 45-60 seconds for complete content package
  • Key dependencies: OpenAI API, Canva API, vector database, cloud storage

Critical nodes:

  • OpenAI Vision (Node 11): Extracts structured data from screenshots—accuracy here determines downstream quality
  • Vector Store Query (Node 18): Retrieves brand voice examples—similarity threshold of 0.75+ ensures voice consistency
  • Content Generator (Node 27): Produces all copy variations—prompt engineering here controls tone and CTA effectiveness
  • Canva Autofill (Node 38): Creates graphics—template selection determines visual consistency

The complete n8n workflow JSON template is available at the bottom of this article.

Key Configuration Details

OpenAI API Settings

Required fields:

  • Model: gpt-4-vision-preview for screenshot analysis, gpt-4-turbo for content generation
  • Max tokens: 1500 for vision analysis, 800 for caption generation
  • Temperature: 0.3 for data extraction (consistency), 0.7 for creative content (variation)

Common issues:

  • Using GPT-3.5 for vision → Results in poor data extraction accuracy
  • Temperature too high on extraction → Inconsistent JSON structure breaks validation
  • Insufficient max tokens → Truncated captions that cut off CTAs

Vector Database Configuration

Pinecone setup:

  • Index dimension: 1536 (matches OpenAI ada-002 embeddings)
  • Metric: cosine similarity
  • Top K results: 5 (retrieves 5 most similar brand voice examples)

Query optimization:

const queryVector = await openai.embeddings.create({
  model: "text-embedding-ada-002",
  input: `${extractedData.sport} ${extractedData.bet_type} win announcement`
});

const matches = await pinecone.query({
  vector: queryVector.data[0].embedding,
  topK: 5,
  filter: {
    engagement_rate: { $gte: 6.0 }  // Only use high-performing examples
  }
});

Why this approach:
Semantic search finds tonally similar content, not just keyword matches. Filtering by engagement rate ensures you're learning from what actually works. Five examples provide enough context without overwhelming the generation prompt.

Instagram API Integration

Authentication requirements:

  • App ID and App Secret from Meta Developer Portal
  • User Access Token with instagram_basic, instagram_content_publish permissions
  • Instagram Business Account ID (not personal account)

Posting endpoint:

// Step 1: Create media container
POST https://graph.facebook.com/v18.0/{ig-user-id}/media
{
  "image_url": "{{designUrl}}",
  "caption": "{{finalCaption}}",
  "access_token": "{{accessToken}}"
}

// Step 2: Publish container
POST https://graph.facebook.com/v18.0/{ig-user-id}/media_publish
{
  "creation_id": "{{containerId}}",
  "access_token": "{{accessToken}}"
}

Rate limits:

  • 25 API calls per user per hour for media publishing
  • Implement retry logic with exponential backoff
  • Queue posts if approaching limit

Testing & Validation

Component testing sequence:

  1. Screenshot ingestion test: Upload sample betting screenshots through webhook and email, verify cloud storage upload and URL generation
  2. Vision extraction validation: Run 10 diverse screenshots (different sports, bet types, platforms), check JSON structure completeness and accuracy
  3. Brand voice consistency: Generate 20 captions from same data, compare tone and structure against historical posts
  4. Design output review: Inspect all format variations (Story, Reel, Feed), verify branding elements and text readability
  5. End-to-end dry run: Process screenshot through complete workflow without publishing, review all outputs

Common issues and fixes:

Issue Symptom Solution
Vision extraction fails Empty JSON or missing fields Increase max tokens to 2000, improve image quality (min 1080px width)
Brand voice drift Generated captions don't match tone Add more diverse examples to vector database (minimum 50 samples)
Canva API timeout Design generation fails after 30s Reduce template complexity, increase timeout to 60s
Instagram publish error "Invalid media URL" Ensure design URLs are publicly accessible, not behind authentication

Validation checklist:

  • All extracted data fields populate correctly
  • Generated captions match brand voice (run through tone analyzer)
  • Graphics render correctly on mobile (test on actual device)
  • CTAs include correct tracking links
  • Emoji render properly across platforms
  • Posting schedule respects rate limits

Production Deployment Checklist

Area Requirement Why It Matters
Error Handling Retry logic with exponential backoff on all API calls Prevents data loss when APIs are temporarily unavailable
Monitoring Webhook health checks every 5 minutes, Slack alerts on failures Detect failures within minutes instead of discovering them days later
Rate Limiting Queue system for Instagram API (max 20 posts/hour) Prevents account suspension from exceeding platform limits
Data Backup Daily export of all generated content to Google Sheets Preserves content history for performance analysis
API Key Rotation Store credentials in n8n credentials manager, rotate quarterly Reduces security risk from compromised keys
Logging Capture all AI prompts and responses for 30 days Enables debugging and prompt optimization
Fallback Content Library of 50+ pre-approved posts for AI generation failures Ensures consistent posting schedule even during outages

Production environment variables:

{
  "OPENAI_API_KEY": "sk-...",
  "CANVA_API_KEY": "...",
  "INSTAGRAM_ACCESS_TOKEN": "...",
  "PINECONE_API_KEY": "...",
  "WEBHOOK_SECRET": "...",
  "ERROR_NOTIFICATION_WEBHOOK": "https://hooks.slack.com/..."
}

Use Cases & Variations

Use Case 1: Daily Picks Content Pipeline

  • Industry: Sports handicapping subscription service
  • Scale: 5-10 picks per day, 50-70 social posts per week
  • Modifications needed: Add scheduling logic to space posts 2-3 hours apart, integrate with Calendly for consultation booking CTAs, connect to Stripe for tracking conversion from content to sales

Use Case 2: Live Game Commentary Automation

  • Industry: In-game betting advisory
  • Scale: 20-30 live updates per game, 3-5 games per day
  • Modifications needed: Replace screenshot trigger with live odds API webhook, reduce generation time to under 15 seconds, add real-time score integration, create urgent/breaking news post templates

Use Case 3: Email Campaign Generation from Winning Streaks

  • Industry: Premium picks service with email list
  • Scale: 2-3 email campaigns per week to 5,000+ subscribers
  • Modifications needed: Add aggregation logic to collect week's wins, generate email-specific long-form content (500-800 words), integrate with Klaviyo for segmentation (send different content to free vs paid subscribers), A/B test subject lines

Use Case 4: Multi-Sport Content Diversification

  • Industry: Full-service handicapping covering 6+ sports
  • Scale: 100+ posts per week across all sports
  • Modifications needed: Sport-specific brand voice databases (basketball tone differs from baseball), custom graphic templates per sport, audience segmentation (post NFL content to different channels than NBA), seasonal scheduling logic

Customizations & Extensions

Alternative Integrations

Instead of Canva API:

  • Bannerbear: Best for high-volume generation (500+ images/day)—requires swapping HTTP Request node configuration to Bannerbear endpoints
  • Placid.app: Better if you need video generation—add video template support, increases node count by 8
  • Custom Pillow/ImageMagick: Use when you want complete design control—requires Python or Bash node, steeper learning curve

Instead of Pinecone:

  • Supabase pgvector: Better if you already use Supabase—native PostgreSQL integration, swap Pinecone nodes for Supabase SQL queries
  • Weaviate: Use when you need more complex filtering—supports hybrid search (vector + keyword), requires Docker deployment
  • Qdrant: Best for self-hosted solutions—complete data ownership, similar API to Pinecone

Workflow Extensions

Add automated A/B testing:

  • Insert a Split node after content generation to create test variants
  • Track performance metrics (engagement rate, click-through rate) in Airtable
  • Use Function node to calculate statistical significance after 100+ impressions
  • Automatically promote winning variants to primary templates
  • Nodes needed: +7 (Split, Airtable x3, Function x2, Merge)

Scale to handle video content:

  • Add video editing API (Shotstack or Creatomate)
  • Process betting screenshots into 15-30 second Reels with motion graphics
  • Add voiceover generation using ElevenLabs API
  • Automatic captioning with Deepgram transcription
  • Performance improvement: Video content gets 3-5x engagement vs static images
  • Nodes needed: +12 (HTTP Request x4, Function x3, File operations x5)

Integration possibilities:

Add This To Get This Complexity
Slack notifications Real-time alerts when high-value content is generated Easy (2 nodes)
Airtable content calendar Visual planning and approval workflow before posting Medium (6 nodes)
Google Analytics tracking UTM parameter generation and conversion tracking Medium (4 nodes)
Telegram channel posting Reach audience on additional platform with same content Easy (3 nodes)
TikTok API integration Cross-post Reels to TikTok automatically Hard (10 nodes)
Stripe webhook integration Trigger special content for new subscriber milestones Medium (5 nodes)

Performance optimization for high volume:

Batch processing mode:

  • Process 10-20 screenshots simultaneously instead of one at a time
  • Add Queue node to manage concurrent API requests
  • Implement connection pooling for database queries
  • Performance improvement: 5x faster for bulk content creation sessions
  • Nodes needed: +8 (Queue, Loop, Merge, Function x5)

Caching layer:

  • Store generated captions for similar bet types (e.g., all "Lakers -4.5" bets use similar language)
  • Check cache before calling OpenAI API
  • Reduces API costs by 40-60% for repetitive content
  • Nodes needed: +4 (Redis or Supabase cache lookup, conditional routing)

Get Started Today

Ready to automate your sports handicapping marketing?

  1. Download the template: Scroll to the bottom of this article to copy the complete n8n workflow JSON
  2. Import to n8n: Go to Workflows → Import from URL or File, paste the JSON
  3. Configure your services: Add API credentials for OpenAI, Canva, Instagram Graph API, and your vector database
  4. Populate brand voice database: Upload 50-100 of your best-performing posts to establish baseline tone
  5. Test with sample screenshots: Run 5-10 diverse betting screenshots through the workflow to verify accuracy
  6. Deploy to production: Set up webhook endpoint, configure error notifications, activate the workflow

Customization support:
This workflow is a foundation. Your specific needs—whether that's integration with your existing CRM, custom graphic templates, or multi-platform posting—require tailored modifications.

Need help customizing this workflow for your specific sports handicapping business? Schedule an intro call with Atherial at https://atherial.ai/contact

Complete N8N Workflow Template

Copy the JSON below and import it into your N8N instance via Workflows → Import from File

{
  "name": "AI Sports Marketing Content Agent",
  "nodes": [
    {
      "id": "webhook-trigger",
      "name": "Screenshot Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        50,
        100
      ],
      "parameters": {
        "path": "sports-marketing/screenshot",
        "httpMethod": "POST",
        "responseCode": 200,
        "responseMode": "onReceived"
      },
      "typeVersion": 2.1
    },
    {
      "id": "extract-image",
      "name": "Extract Image Data",
      "type": "n8n-nodes-base.set",
      "position": [
        250,
        100
      ],
      "parameters": {
        "mode": "manual",
        "assignments": [
          {
            "name": "imageUrl",
            "type": "string",
            "value": "={{ $json.imageUrl }}"
          },
          {
            "name": "marketingContext",
            "type": "string",
            "value": "={{ $json.marketingContext || 'sports betting screenshot' }}"
          },
          {
            "name": "brandVoice",
            "type": "string",
            "value": "={{ $json.brandVoice || 'professional, engaging, witty' }}"
          }
        ]
      },
      "typeVersion": 3.4
    },
    {
      "id": "ai-image-analysis",
      "name": "AI Image Analysis",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "onError": "continueRegularOutput",
      "position": [
        450,
        100
      ],
      "parameters": {
        "prompt": "Analyze this sports betting screenshot and extract: 1) Key data points (odds, teams, amounts), 2) Visual elements, 3) Marketing angle suggestions. Respond in JSON format with fields: dataPoints, visualElements, marketingAngle",
        "modelId": "gpt-4-vision",
        "imageUrl": "={{ $json.imageUrl }}",
        "resource": "image",
        "operation": "analyze"
      },
      "typeVersion": 2
    },
    {
      "id": "generate-content",
      "name": "Generate Social Media Content",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "onError": "continueRegularOutput",
      "position": [
        650,
        100
      ],
      "parameters": {
        "prompt": "You are a sports marketing expert with this brand voice: {{ $json.brandVoice }}. Create 3 variations of social media content for Instagram based on this analysis: {{ JSON.stringify($json) }}. For each variation provide: caption (max 300 chars), hashtags (array), callToAction, and contentType (Story/Reel/Post). Return as JSON array.",
        "modelId": "gpt-4-turbo",
        "resource": "text",
        "operation": "response"
      },
      "typeVersion": 2
    },
    {
      "id": "canva-graphic",
      "name": "Generate Graphic with Canva",
      "type": "n8n-nodes-base.httpRequest",
      "maxTries": 3,
      "position": [
        850,
        100
      ],
      "parameters": {
        "url": "https://api.canva.com/v1/designs",
        "body": "{\"template_id\": \"social_post_instagram\", \"title\": \"Sports Marketing {{ $now.toISOString() }}\", \"customizations\": {\"text\": {\"headline\": \"Sports Betting Content\"}}}",
        "method": "POST",
        "headers": {
          "Content-Type": "application/json",
          "Authorization": "Bearer {{ $env.CANVA_API_KEY }}"
        },
        "sendBody": true,
        "contentType": "json",
        "sendHeaders": true
      },
      "retryOnFail": true,
      "typeVersion": 4.3
    },
    {
      "id": "prepare-instagram",
      "name": "Prepare Instagram Posts",
      "type": "n8n-nodes-base.set",
      "position": [
        1050,
        50
      ],
      "parameters": {
        "mode": "manual",
        "assignments": [
          {
            "name": "posts",
            "type": "expression",
            "value": "={{ $json.map((item, index) => ({ caption: item.caption, hashtags: item.hashtags.join(' '), type: item.contentType, mediaUrl: '', cta: item.callToAction })) }}"
          }
        ]
      },
      "typeVersion": 3.4
    },
    {
      "id": "post-instagram",
      "name": "Post to Instagram",
      "type": "n8n-nodes-base.httpRequest",
      "maxTries": 2,
      "position": [
        1200,
        50
      ],
      "parameters": {
        "url": "https://graph.instagram.com/v17.0/{{ $env.INSTAGRAM_BUSINESS_ACCOUNT_ID }}/media",
        "body": "{\"image_url\": \"{{ $json.mediaUrl }}\", \"caption\": \"{{ $json.caption }}\\n\\n{{ $json.hashtags }}\", \"access_token\": \"{{ $env.INSTAGRAM_ACCESS_TOKEN }}\"}",
        "method": "POST",
        "headers": {
          "Content-Type": "application/json",
          "Authorization": "Bearer {{ $env.INSTAGRAM_ACCESS_TOKEN }}"
        },
        "sendBody": true,
        "contentType": "json",
        "sendHeaders": true
      },
      "retryOnFail": true,
      "typeVersion": 4.3
    },
    {
      "id": "prepare-email",
      "name": "Prepare Email Campaign",
      "type": "n8n-nodes-base.set",
      "position": [
        1050,
        150
      ],
      "parameters": {
        "mode": "manual",
        "assignments": [
          {
            "name": "emailSubject",
            "type": "string",
            "value": "New Sports Marketing Content Available"
          },
          {
            "name": "emailBody",
            "type": "string",
            "value": "<h2>New Sports Marketing Content</h2><p>We've generated fresh social media content based on the latest sports betting insights.</p><ul><li>3 Instagram content variations</li><li>Optimized for engagement</li><li>Brand-aligned messaging</li></ul>"
          }
        ]
      },
      "typeVersion": 3.4
    },
    {
      "id": "send-email-campaign",
      "name": "Send Email Campaign",
      "type": "n8n-nodes-base.mailchimp",
      "position": [
        1200,
        150
      ],
      "parameters": {
        "listId": "={{ $env.MAILCHIMP_AUDIENCE_ID }}",
        "replyTo": "{{ $env.MARKETING_EMAIL }}",
        "subject": "={{ $json.emailSubject }}",
        "fromName": "Sports Marketing Team",
        "htmlBody": "={{ $json.emailBody }}",
        "resource": "campaign",
        "operation": "create"
      },
      "retryOnFail": true,
      "typeVersion": 2
    },
    {
      "id": "generate-strategy",
      "name": "Generate Marketing Strategies",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "onError": "continueRegularOutput",
      "position": [
        450,
        250
      ],
      "parameters": {
        "prompt": "As a sports marketing strategist, analyze this content generation session and provide 5 strategic recommendations: {{ JSON.stringify($json) }}. Cover: 1) Content optimization, 2) Audience engagement tactics, 3) Cross-platform adaptation, 4) Performance metrics to track, 5) Next content ideas. Return as JSON with actionable items.",
        "modelId": "gpt-4-turbo",
        "resource": "text",
        "operation": "response"
      },
      "typeVersion": 2
    },
    {
      "id": "vector-store",
      "name": "Update Brand Voice Vector Store",
      "type": "n8n-nodes-base.httpRequest",
      "maxTries": 2,
      "position": [
        650,
        250
      ],
      "parameters": {
        "url": "https://api.pinecone.io/v1/vectors/upsert",
        "body": "{\"vectors\": [{\"id\": \"brand-voice-{{ $now.unix() }}\", \"values\": [0.1, 0.2, 0.3], \"metadata\": {\"type\": \"brand_voice\", \"timestamp\": \"{{ $now.toISOString() }}\", \"source\": \"ai_generated_content\"}}]}",
        "method": "POST",
        "headers": {
          "Api-Key": "{{ $env.PINECONE_API_KEY }}",
          "Content-Type": "application/json"
        },
        "sendBody": true,
        "contentType": "json",
        "sendHeaders": true
      },
      "retryOnFail": true,
      "typeVersion": 4.3
    },
    {
      "id": "completion-summary",
      "name": "Workflow Completion Summary",
      "type": "n8n-nodes-base.set",
      "position": [
        1350,
        100
      ],
      "parameters": {
        "mode": "manual",
        "assignments": [
          {
            "name": "workflowStatus",
            "type": "string",
            "value": "completed"
          },
          {
            "name": "contentGenerated",
            "type": "number",
            "value": "3"
          },
          {
            "name": "postsScheduled",
            "type": "number",
            "value": "3"
          },
          {
            "name": "emailCampaignSent",
            "type": "boolean",
            "value": "true"
          },
          {
            "name": "executionTime",
            "type": "expression",
            "value": "={{ $now.toISOString() }}"
          }
        ]
      },
      "typeVersion": 3.4
    }
  ],
  "connections": {
    "AI Image Analysis": {
      "main": [
        [
          {
            "node": "Generate Social Media Content",
            "type": "main",
            "index": 0
          },
          {
            "node": "Generate Marketing Strategies",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Post to Instagram": {
      "main": [
        [
          {
            "node": "Workflow Completion Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Image Data": {
      "main": [
        [
          {
            "node": "AI Image Analysis",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Screenshot Webhook": {
      "main": [
        [
          {
            "node": "Extract Image Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Email Campaign": {
      "main": [
        [
          {
            "node": "Workflow Completion Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Email Campaign": {
      "main": [
        [
          {
            "node": "Send Email Campaign",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Instagram Posts": {
      "main": [
        [
          {
            "node": "Post to Instagram",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Graphic with Canva": {
      "main": [
        [
          {
            "node": "Prepare Instagram Posts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Marketing Strategies": {
      "main": [
        [
          {
            "node": "Update Brand Voice Vector Store",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Social Media Content": {
      "main": [
        [
          {
            "node": "Generate Graphic with Canva",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Brand Voice Vector Store": {
      "main": [
        [
          {
            "node": "Prepare Email Campaign",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}