{
  "name": "PodcastPipeline 01 — Audio to Transcript",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "podcastpipeline-transcript",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "1a000001-0001-0001-0001-000000000001",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [240, 300],
      "webhookId": "podcastpipeline-transcript"
    },
    {
      "parameters": {
        "url": "={{ $json.body.audio_url }}",
        "responseFormat": "file",
        "options": {
          "timeout": 120000
        }
      },
      "id": "1a000001-0001-0001-0001-000000000002",
      "name": "Download Audio",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [460, 300]
    },
    {
      "parameters": {
        "resource": "audio",
        "operation": "transcribe",
        "binaryPropertyName": "data",
        "options": {
          "language": "en",
          "response_format": "verbose_json",
          "timestamp_granularities": ["segment"]
        }
      },
      "id": "1a000001-0001-0001-0001-000000000003",
      "name": "OpenAI Whisper",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "typeVersion": 1.4,
      "position": [680, 300],
      "credentials": {
        "openAiApi": {
          "id": "REPLACE_WITH_YOUR_CREDENTIAL_ID",
          "name": "OpenAI API"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Structure Whisper output into clean transcript with chapter chunks\nconst input = items[0].json;\nconst segments = input.segments || [];\n\nconst CHAPTER_SECONDS = 300;\nconst chapters = [];\nlet current = { start: 0, end: 0, segments: [] };\n\nfor (const seg of segments) {\n  if (seg.start - current.start >= CHAPTER_SECONDS && current.segments.length > 0) {\n    current.end = current.segments[current.segments.length - 1].end;\n    chapters.push(current);\n    current = { start: seg.start, end: seg.end, segments: [seg] };\n  } else {\n    current.segments.push(seg);\n    if (current.segments.length === 1) current.start = seg.start;\n  }\n}\nif (current.segments.length > 0) {\n  current.end = current.segments[current.segments.length - 1].end;\n  chapters.push(current);\n}\n\nconst fmt = (s) => {\n  const h = Math.floor(s / 3600);\n  const m = Math.floor((s % 3600) / 60);\n  const sec = Math.floor(s % 60);\n  return h > 0\n    ? `${h}:${String(m).padStart(2, '0')}:${String(sec).padStart(2, '0')}`\n    : `${m}:${String(sec).padStart(2, '0')}`;\n};\n\nreturn [{\n  json: {\n    full_text: input.text,\n    duration_seconds: input.duration,\n    duration_formatted: fmt(input.duration || 0),\n    language: input.language,\n    word_count: (input.text || '').split(/\\s+/).filter(Boolean).length,\n    chapter_count: chapters.length,\n    chapters: chapters.map((c, i) => ({\n      index: i + 1,\n      start_seconds: c.start,\n      end_seconds: c.end,\n      start_formatted: fmt(c.start),\n      end_formatted: fmt(c.end),\n      text: c.segments.map((s) => s.text).join(' ').trim()\n    })),\n    segments: segments\n  }\n}];"
      },
      "id": "1a000001-0001-0001-0001-000000000004",
      "name": "Structure Transcript",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [900, 300]
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify($json) }}",
        "options": {}
      },
      "id": "1a000001-0001-0001-0001-000000000005",
      "name": "Respond",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [1120, 300]
    }
  ],
  "connections": {
    "Webhook": {
      "main": [[{ "node": "Download Audio", "type": "main", "index": 0 }]]
    },
    "Download Audio": {
      "main": [[{ "node": "OpenAI Whisper", "type": "main", "index": 0 }]]
    },
    "OpenAI Whisper": {
      "main": [[{ "node": "Structure Transcript", "type": "main", "index": 0 }]]
    },
    "Structure Transcript": {
      "main": [[{ "node": "Respond", "type": "main", "index": 0 }]]
    }
  },
  "active": false,
  "settings": { "executionOrder": "v1" },
  "versionId": "00000000-0000-0000-0000-000000000001",
  "id": "podcastpipeline-01-transcript",
  "meta": { "instanceId": "podcastpipeline" },
  "tags": [{ "name": "PodcastPipeline" }]
}
