# Blogger Queues


# BLOGGER_VIDEO_QUEUE

Producer: bloggers-worker Consumer: blogger-video-consumer

# Initial Fetch Message (type: blogger_initial_fetch)

Sent by queueInitialVideoFetch() in bloggerManagement.js or enqueueBloggerInitialFetch() in queueService.js:

{
  type: 'blogger_initial_fetch',
  bloggerId: string,        // UUID — internal blogger ID
  secUid: string | null,    // TikTok secUid only
  externalId: string,       // Platform-specific user ID
  platform: 'TikTok' | 'Instagram' | 'YouTube',
  videoCount: number,       // initial_videos_count
  organizationId: string,
  userId: string,
  requestId: string,
  videoStatus: 'tracking',
  timestamp: string,        // ISO8601
  force: boolean            // Optional — bypass 4-hour cooldown (default: false)
}

Field Details:

Field Required Description
force No When true, bypasses the 4-hour cooldown guard in blogger-video-consumer. Used by the public API GET /v1/bloggers/info?refresh=true to force a fresh video fetch when average stats age ≥ 5 days. Default: false

# Midnight/Noon Batch Message (no type field)

Sent by scheduleMidnightBloggerFetches() in midnightBloggerFetch.ts:

{
  trackingId: string,           // UUID — tracked_accounts.id
  userId: string,
  externalId: string,
  daily_videos_count: number,
  organization_id: string,
  blogger_id: string,
  platform: 'TikTok' | 'Instagram' | 'YouTube'
}

The absence of a type field is how blogger-video-consumer distinguishes midnight batches from initial fetches.


# HIGH_PRIORITY_QUEUE (YouTube stats only)

When blogger-video-consumer saves YouTube videos, it cannot fetch statistics in the same API call. It enqueues batches of up to 50 videos to HIGH_PRIORITY_QUEUE for queue-processor to handle:

{
  type: 'video_batch',
  platform: 'youtube',
  videos: [
    {
      videoUrl: string,
      userId: string,
      organizationId: string,
      externalVideoId: string
    }
  ],
  priority: 'high',
  source: 'blogger-initial-fetch' | 'blogger-midnight-batch',
  batchNumber: number,
  totalBatches: number,
  organizationId: string,
  enqueuedAt: string,
  requestId: string
}

# Queue Flow

bloggers-worker
  ├── POST /blogger/add  ────────────► BLOGGER_VIDEO_QUEUE (type: blogger_initial_fetch)
  └── Cron 0 0,12 * * *  ───────────► BLOGGER_VIDEO_QUEUE (no type)
        (in chunks of 100, sendBatch)

api-worker (public API)
  └── GET /v1/bloggers/info?refresh=true ─► BLOGGER_VIDEO_QUEUE (type: blogger_initial_fetch, force: true)
        └── Only when avg stats age ≥ 5 days

BLOGGER_VIDEO_QUEUE
  └── blogger-video-consumer
        ├── blogger_initial_fetch ──► handleInitialFetch()
        │     └── force: true ──────► bypasses 4-hour cooldown
        └── no type ───────────────► handleMidnightBatch()
              └── YouTube only ────► HIGH_PRIORITY_QUEUE → queue-processor