{
  "name": "Netflix Norway Top10 \u2192 Seerr",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 8 * * *"
            }
          ]
        }
      },
      "id": "2d12a38d-4340-4bd2-8aa2-3b2e28755b0f",
      "name": "Daily 08:00",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1,
      "position": [
        -1616,
        80
      ]
    },
    {
      "parameters": {
        "url": "https://www.netflix.com/tudum/top10/norway",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "User-Agent",
              "value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
            },
            {
              "name": "Accept",
              "value": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7"
            },
            {
              "name": "Accept-Language",
              "value": "nb-NO,nb;q=0.9,no;q=0.8,nn;q=0.7,en-US;q=0.6,en;q=0.5"
            },
            {
              "name": "Cache-Control",
              "value": "no-cache"
            },
            {
              "name": "sec-ch-ua",
              "value": "\"Chromium\";v=\"124\", \"Google Chrome\";v=\"124\", \"Not-A.Brand\";v=\"99\""
            },
            {
              "name": "sec-ch-ua-mobile",
              "value": "?0"
            },
            {
              "name": "sec-ch-ua-platform",
              "value": "\"Windows\""
            },
            {
              "name": "sec-fetch-dest",
              "value": "document"
            },
            {
              "name": "sec-fetch-mode",
              "value": "navigate"
            },
            {
              "name": "sec-fetch-site",
              "value": "none"
            },
            {
              "name": "sec-fetch-user",
              "value": "?1"
            },
            {
              "name": "Upgrade-Insecure-Requests",
              "value": "1"
            }
          ]
        },
        "options": {
          "response": {
            "response": {
              "responseFormat": "text"
            }
          }
        }
      },
      "id": "9f277e2b-0eed-4766-87b3-0c8badeb7ea2",
      "name": "Fetch Netflix Movies",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4,
      "position": [
        -1408,
        80
      ]
    },
    {
      "parameters": {
        "jsCode": "function parseNetflixPage(html) {\n  const match = html.match(/netflix\\.reactContext\\.models\\.graphql\\s*=\\s*JSON\\.parse\\('([\\s\\S]*?)'\\);\\s*<\\/script>/);\n  if (!match) throw new Error('Netflix graphql blob not found');\n\n  const raw = match[1]\n    .replace(/\\\\'/g, \"'\")\n    .replace(/\\\\\"/g, '\"');\n\n  const data = JSON.parse(raw).data;\n  const seen = new Set();\n  const items = [];\n\n  for (const val of Object.values(data)) {\n    if (!val || val.__typename !== 'PulseTop10ItemEntity') continue;\n    const rank     = val.top10?.weeklyRank;\n    const rawTitle = val.top10Video?.title || '';\n    const nType    = val.displayVideo?.video?.__typename || '';\n    const key      = rank + '|' + rawTitle;\n    if (seen.has(key)) continue;\n    seen.add(key);\n    const title     = nType === 'Season' ? rawTitle.replace(/:\\s+.+$/, '').trim() : rawTitle;\n    const mediaType = nType === 'Movie' ? 'movie' : 'tv';\n    items.push({ rank, title, mediaType });\n  }\n  return items.sort((a, b) => (a.rank || 99) - (b.rank || 99));\n}\n\nconst moviesHtml = $input.first().json.data;\nconst movies = parseNetflixPage(moviesHtml);\n\nconst tvResponse = await this.helpers.httpRequest({\n  method: 'GET',\n  url: 'https://www.netflix.com/tudum/top10/norway/tv',\n  headers: {\n    'User-Agent':              'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',\n    'Accept':                  'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',\n    'Accept-Language':         'nb-NO,nb;q=0.9,no;q=0.8,nn;q=0.7,en-US;q=0.6,en;q=0.5',\n    'Accept-Encoding':         'gzip, deflate, br',\n    'Cache-Control':           'no-cache',\n    'sec-fetch-dest':          'document',\n    'sec-fetch-mode':          'navigate',\n    'sec-fetch-site':          'none',\n    'sec-fetch-user':          '?1',\n    'Upgrade-Insecure-Requests': '1',\n  },\n});\nconst shows = parseNetflixPage(tvResponse);\n\nconst titles = [...movies, ...shows];\nreturn [{ json: { titles } }];"
      },
      "id": "57d6df8c-1fc2-4145-b4e8-131192b50f43",
      "name": "Parse Top10 Titles",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -1184,
        80
      ]
    },
    {
      "parameters": {
        "fieldToSplitOut": "titles",
        "options": {}
      },
      "id": "11005f95-3b18-47c4-8c65-f8024a3978a6",
      "name": "Split Titles",
      "type": "n8n-nodes-base.splitOut",
      "typeVersion": 1,
      "position": [
        -960,
        80
      ]
    },
    {
      "parameters": {
        "url": "http://<YOUR_SEERR_IP>:<PORT>/api/v1/search",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "query",
              "value": "={{ $json.title }}"
            },
            {
              "name": "page",
              "value": "1"
            },
            {
              "name": "language",
              "value": "en"
            }
          ]
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "X-Api-Key",
              "value": "<YOUR_SEERR_API_KEY>"
            }
          ]
        },
        "options": {}
      },
      "id": "45cdfe9a-fb11-4289-8d53-51dfcd285d2e",
      "name": "Search Seerr",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4,
      "position": [
        -736,
        80
      ],
      "continueOnFail": true
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const search   = $input.item.json;\nconst original = $('Split Titles').item.json;\n\nif (search.error) {\n  return { json: { shouldRequest: false, title: original.title, reason: 'search error' } };\n}\n\nconst results   = search.results || [];\nconst mediaType = original.mediaType;\n\nconst match = results.find(r => r.mediaType === mediaType) || results[0];\n\nif (!match) {\n  return { json: { shouldRequest: false, title: original.title, reason: 'no results' } };\n}\n\nconst status        = match.mediaInfo?.status ?? 0;\nconst shouldRequest = status < 2;\n\nreturn { json: {\n  shouldRequest,\n  mediaId:       match.id,\n  mediaType:     match.mediaType,\n  title:         match.title || match.name,\n  currentStatus: status\n} };"
      },
      "id": "157fad6e-7bae-420c-bc2e-53fa5016423a",
      "name": "Check Status",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -528,
        80
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 1
          },
          "conditions": [
            {
              "id": "cond-001",
              "leftValue": "={{ $json.shouldRequest }}",
              "operator": {
                "type": "boolean",
                "operation": "true"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "97ff8ef3-58ca-46d9-b676-edba2d77b91c",
      "name": "Not Yet Requested?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        -304,
        80
      ]
    },
    {
      "parameters": {
        "url": "=http://<YOUR_SEERR_IP>:<PORT>/api/v1/{{ $json.mediaType === 'tv' ? 'tv' : 'movie' }}/{{ $json.mediaId }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "X-Api-Key",
              "value": "<YOUR_SEERR_API_KEY>"
            }
          ]
        },
        "options": {}
      },
      "id": "549bc4d1-120e-4861-aa90-570c0371021f",
      "name": "Fetch TV Seasons",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4,
      "position": [
        -80,
        0
      ],
      "continueOnFail": true
    },
    {
      "parameters": {
        "method": "POST",
        "url": "http://<YOUR_SEERR_IP>:<PORT>/api/v1/auth/local",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "{\"email\":\"<YOUR_BOT_EMAIL>\",\"password\":\"<YOUR_BOT_PASSWORD>\"}",
        "options": {
          "response": {
            "response": {
              "fullResponse": true
            }
          }
        }
      },
      "id": "3aa07388-fbad-4601-8844-0c2da69e953a",
      "name": "Login Bot User",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4,
      "position": [
        144,
        0
      ],
      "continueOnFail": true
    },
    {
      "parameters": {
        "method": "POST",
        "url": "http://<YOUR_SEERR_IP>:<PORT>/api/v1/request",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "Cookie",
              "value": "={{ $json.headers['set-cookie'][0].split(';')[0] }}"
            }
          ]
        },
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "={{ JSON.stringify({ mediaType: $('Not Yet Requested?').item.json.mediaType, mediaId: $('Not Yet Requested?').item.json.mediaId, ...($('Not Yet Requested?').item.json.mediaType === 'tv' ? { seasons: [($('Fetch TV Seasons').item.json.seasons || []).map(s => s.seasonNumber).filter(n => n > 0).sort((a,b) => a - b).pop()].filter(Boolean) } : {}) }) }}",
        "options": {}
      },
      "id": "f0ee9906-267d-4a20-94be-722f7bf089b8",
      "name": "Request in Seerr",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4,
      "position": [
        368,
        0
      ],
      "continueOnFail": true
    }
  ],
  "connections": {
    "Daily 08:00": {
      "main": [
        [
          {
            "node": "Fetch Netflix Movies",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Top10 Titles": {
      "main": [
        [
          {
            "node": "Split Titles",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Titles": {
      "main": [
        [
          {
            "node": "Search Seerr",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Search Seerr": {
      "main": [
        [
          {
            "node": "Check Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Status": {
      "main": [
        [
          {
            "node": "Not Yet Requested?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Not Yet Requested?": {
      "main": [
        [
          {
            "node": "Fetch TV Seasons",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch TV Seasons": {
      "main": [
        [
          {
            "node": "Login Bot User",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Login Bot User": {
      "main": [
        [
          {
            "node": "Request in Seerr",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Netflix Movies": {
      "main": [
        [
          {
            "node": "Parse Top10 Titles",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": true,
  "settings": {
    "executionOrder": "v1",
    "binaryMode": "separate"
  },
  "versionId": "84b97826-22a3-4520-addd-1038987924f6",
  "id": "scktYFnd6h9MMmYB",
  "tags": []
}