Task: Plex Scrobbler to TraktTV

n8n workflow JSON:
{"id":9,"name":"Plex Scrobbler","nodes":[{"name":"Switch","type":"n8n-nodes-base.switch","position":[580,320],"parameters":{"rules":{"rules":[{"value2":"movie"},{"output":1,"value2":"episode"},{"output":2,"value2":"track"}]},"value1":"={{$json[\"type\"]}}","dataType":"string","fallbackOutput":3},"typeVersion":1},{"name":"Search Movie","type":"n8n-nodes-base.httpRequest","position":[1740,120],"parameters":{"url":"=https://api.trakt.tv/search/movie?query={{$json[\"title\"]}}","options":{},"authentication":"oAuth2","headerParametersUi":{"parameter":[{"name":"trakt-api-key","value":""},{"name":"trakt-api-version","value":"2"}]}},"credentials":{"oAuth2Api":{"id":"13","name":"TraktTV"}},"typeVersion":1},{"name":"Plex","type":"n8n-nodes-base.webhook","position":[-560,360],"webhookId":"d89e6873-6948-4005-bd31-a5591c93f261","parameters":{"path":"d89e6873-6948-4005-bd31-a5591c93f261","options":{},"httpMethod":"POST"},"typeVersion":1},{"name":"Parse payload","type":"n8n-nodes-base.functionItem","position":[-380,360],"parameters":{"functionCode":"item = JSON.parse(item.body.payload);\n\nreturn item;"},"typeVersion":1},{"name":"Select Movie","type":"n8n-nodes-base.functionItem","position":[2200,120],"parameters":{"functionCode":"return {\n  resource: item.filter(i => {\n    return i.movie.year === $node[\"Filter data\"].json[\"year\"]\n  })[0].movie\n}\n"},"typeVersion":1},{"name":"Scrobble","type":"n8n-nodes-base.httpRequest","position":[2620,120],"parameters":{"url":"=https://api.trakt.tv/scrobble/{{$json[\"action\"]}}","options":{"ignoreResponseCode":true},"requestMethod":"POST","authentication":"oAuth2","bodyParametersUi":{"parameter":[{"name":"={{$node[\"Add scrobble data\"].json[\"type\"]}}","value":"={{$json[\"payload\"]}}"},{"name":"progress","value":"={{$node[\"Add scrobble data\"].json[\"progress\"]}}"}]},"headerParametersUi":{"parameter":[{"name":"trakt-api-key","value":""},{"name":"trakt-api-version","value":"2"}]}},"credentials":{"oAuth2Api":{"id":"13","name":"TraktTV"}},"typeVersion":1},{"name":"Build request","type":"n8n-nodes-base.set","position":[2420,120],"parameters":{"values":{"number":[{"name":"progress","value":"={{$node[\"Add scrobble data\"].json[\"progress\"]}}"}],"string":[{"name":"type","value":"={{$node[\"Add scrobble data\"].json[\"type\"]}}"},{"name":"action","value":"={{$node[\"Add scrobble data\"].json[\"action\"]}}"},{"name":"payload","value":"={{$json[\"resource\"]}}"}]},"options":{"dotNotation":false},"keepOnlySet":true},"typeVersion":1},{"name":"Add scrobble data","type":"n8n-nodes-base.functionItem","position":[140,340],"parameters":{"functionCode":"switch(item.event) {\n  case 'media.play':\n  case 'media.resume':\n    item.action = 'start';\n    item.progress = 0;\n    break;\n  case 'media.pause':\n  case 'media.stop':\n    item.action = 'stop';\n    item.progress = 0;\n    break;\n  case 'media.scrobble':\n    item.action = 'stop';\n    item.progress = 90;\n    break;\n}\n\nreturn item;"},"typeVersion":1},{"name":"Filter data","type":"n8n-nodes-base.set","position":[-40,340],"parameters":{"values":{"number":[{"name":"year","value":"={{$json[\"Metadata\"][\"year\"]}}"}],"string":[{"name":"event","value":"={{$json[\"event\"]}}"},{"name":"type","value":"={{$json[\"Metadata\"][\"type\"]}}"},{"name":"grandparentTitle","value":"={{$json[\"Metadata\"][\"grandparentTitle\"]}}"},{"name":"parentTitle","value":"={{$json[\"Metadata\"][\"parentTitle\"]}}"},{"name":"title","value":"={{$json[\"Metadata\"][\"title\"]}}"},{"name":"providerData","value":"={{$json[\"Metadata\"][\"Guid\"]}}"},{"name":"season","value":"={{$json[\"Metadata\"][\"parentIndex\"]}}"},{"name":"episode","value":"={{$json[\"Metadata\"][\"index\"]}}"},{"name":"grandparentGuid","value":"={{$json[\"Metadata\"][\"grandparentGuid\"]}}"}]},"options":{},"keepOnlySet":true},"typeVersion":1},{"name":"Parse providers","type":"n8n-nodes-base.functionItem","position":[1030,480],"parameters":{"functionCode":"if (item.providerData) {\n  item.providerData = item.providerData.map(data => {\n    const id = data.id;\n  \n    return {\n      name: id.substr(0,4),\n      id: id.substr(7)\n    }\n  });\n}\n\nreturn item;"},"typeVersion":1},{"name":"SplitInBatches","type":"n8n-nodes-base.splitInBatches","position":[1480,480],"parameters":{"options":{"reset":false},"batchSize":1},"typeVersion":1},{"name":"Transform providers","type":"n8n-nodes-base.function","position":[1300,480],"parameters":{"functionCode":"let result = [];\nfor (item of items) {\n  for (provider of item.json.providerData) {\n    result.push({\n      json: provider\n    })\n  }\n}\n\nreturn result;\n"},"typeVersion":1},{"name":"If found","type":"n8n-nodes-base.if","position":[1960,480],"parameters":{"conditions":{"number":[{"value1":"={{Object.keys($json[\"0\"]).length}}","operation":"notEqual"}]}},"typeVersion":1},{"name":"Search Show & Episode","type":"n8n-nodes-base.httpRequest","position":[1740,480],"parameters":{"url":"=https://api.trakt.tv/search/{{$json[\"name\"]}}/{{$json[\"id\"]}}","options":{},"authentication":"oAuth2","headerParametersUi":{"parameter":[{"name":"trakt-api-key","value":""},{"name":"trakt-api-version","value":"2"}]}},"credentials":{"oAuth2Api":{"id":"13","name":"TraktTV"}},"typeVersion":1},{"name":"Select Episode","type":"n8n-nodes-base.functionItem","position":[2200,500],"parameters":{"functionCode":"return {\n  resource: item[0].episode\n};\n"},"typeVersion":1},{"name":"Search Show","type":"n8n-nodes-base.httpRequest","position":[1740,300],"parameters":{"url":"=https://api.trakt.tv/search/{{$json[\"providerData\"][\"name\"]}}/{{$json[\"providerData\"][\"showId\"]}}?type=show","options":{},"authentication":"oAuth2","headerParametersUi":{"parameter":[{"name":"trakt-api-key","value":""},{"name":"trakt-api-version","value":"2"}]}},"credentials":{"oAuth2Api":{"id":"13","name":"TraktTV"}},"typeVersion":1},{"name":"Parse parentGuid","type":"n8n-nodes-base.functionItem","position":[1030,310],"parameters":{"functionCode":"const thetvdbRegex = new RegExp(/com\\.plexapp\\.agents\\.(.*):\\/\\/(\\d*)/g);\nconst match = thetvdbRegex.exec(item.grandparentGuid);\nconst provider = match[1];\nconst showId = match[2];\n\nif (provider && showId) {\n  let providerName;\n\n  switch(provider) {\n    case 'thetvdb':\n      providerName = 'tvdb';\n      break;\n    case 'themoviedb':\n      providerName = 'tmdb';\n      break;\n  }\n  \n  item.providerData = {\n    name: providerName,\n    showId: showId    \n  }\n}\n\nreturn item;\n"},"typeVersion":1},{"name":"Search Episodes","type":"n8n-nodes-base.httpRequest","position":[1960,300],"parameters":{"url":"=https://api.trakt.tv/shows/{{$json[\"0\"][\"show\"][\"ids\"][\"trakt\"]}}/seasons?extended=episodes","options":{},"authentication":"oAuth2","headerParametersUi":{"parameter":[{"name":"trakt-api-key","value":""},{"name":"trakt-api-version","value":"2"}]}},"credentials":{"oAuth2Api":{"id":"13","name":"TraktTV"}},"typeVersion":1},{"name":"Find & Select Episode","type":"n8n-nodes-base.functionItem","position":[2200,300],"parameters":{"functionCode":"const season = item.find(season => {\n  return season.number == $node[\"Add scrobble data\"].json[\"season\"]\n})\n\nconst episode = season.episodes.find(episode => {\n  return episode.number == $node[\"Add scrobble data\"].json[\"episode\"]\n})\n\nreturn {\n  resource: episode\n}"},"typeVersion":1},{"name":"If providers empty","type":"n8n-nodes-base.if","position":[840,340],"parameters":{"conditions":{"string":[{"value1":"={{$json[\"providerData\"]}}","operation":"isEmpty"}]}},"typeVersion":1},{"name":"NoOp","type":"n8n-nodes-base.noOp","position":[580,480],"parameters":{},"typeVersion":1},{"name":"If start or stop","type":"n8n-nodes-base.if","position":[380,340],"parameters":{"conditions":{"string":[{"value1":"={{$json[\"action\"]}}","value2":"start"},{"value1":"={{$json[\"action\"]}}","value2":"stop"}]},"combineOperation":"any"},"typeVersion":1},{"name":"IF","type":"n8n-nodes-base.if","position":[-220,360],"parameters":{"conditions":{"string":[{"value1":"={{ $node[\"Parse payload\"].json[\"Account\"][\"title\"] }}","value2":"kinduff"}]}},"typeVersion":1},{"name":"NoOp2","type":"n8n-nodes-base.noOp","position":[-40,500],"parameters":{},"typeVersion":1},{"name":"Note","type":"n8n-nodes-base.stickyNote","position":[-600,100],"parameters":{"width":900,"height":560,"content":"# Receive & Parse Plex Webhook"},"typeVersion":1},{"name":"Note1","type":"n8n-nodes-base.stickyNote","position":[340,100],"parameters":{"width":420,"height":560,"content":"# Detect Movie or Episode"},"typeVersion":1},{"name":"Note2","type":"n8n-nodes-base.stickyNote","position":[800,100],"parameters":{"width":380,"height":560,"content":"# Determine Data Provider"},"typeVersion":1},{"name":"Note4","type":"n8n-nodes-base.stickyNote","position":[1220,20],"parameters":{"width":900,"height":700,"content":"# Resource search"},"typeVersion":1},{"name":"Note5","type":"n8n-nodes-base.stickyNote","position":[2160,20],"parameters":{"width":660,"height":700,"content":"# Request to TraktTV"},"typeVersion":1}],"active":true,"connections":{"IF":{"main":[[{"node":"Filter data","type":"main","index":0}],[{"node":"NoOp2","type":"main","index":0}]]},"Plex":{"main":[[{"node":"Parse payload","type":"main","index":0}]]},"Switch":{"main":[[{"node":"Search Movie","type":"main","index":0}],[{"node":"If providers empty","type":"main","index":0}]]},"If found":{"main":[[{"node":"Select Episode","type":"main","index":0}],[{"node":"SplitInBatches","type":"main","index":0}]]},"Filter data":{"main":[[{"node":"Add scrobble data","type":"main","index":0}]]},"Search Show":{"main":[[{"node":"Search Episodes","type":"main","index":0}]]},"Search Movie":{"main":[[{"node":"Select Movie","type":"main","index":0}]]},"Select Movie":{"main":[[{"node":"Build request","type":"main","index":0}]]},"Build request":{"main":[[{"node":"Scrobble","type":"main","index":0}]]},"Parse payload":{"main":[[{"node":"IF","type":"main","index":0}]]},"Select Episode":{"main":[[{"node":"Build request","type":"main","index":0}]]},"SplitInBatches":{"main":[[{"node":"Search Show & Episode","type":"main","index":0}]]},"Parse providers":{"main":[[{"node":"Transform providers","type":"main","index":0}]]},"Search Episodes":{"main":[[{"node":"Find & Select Episode","type":"main","index":0}]]},"If start or stop":{"main":[[{"node":"Switch","type":"main","index":0}],[{"node":"NoOp","type":"main","index":0}]]},"Parse parentGuid":{"main":[[{"node":"Search Show","type":"main","index":0}]]},"Add scrobble data":{"main":[[{"node":"If start or stop","type":"main","index":0}]]},"If providers empty":{"main":[[{"node":"Parse parentGuid","type":"main","index":0}],[{"node":"Parse providers","type":"main","index":0}]]},"Transform providers":{"main":[[{"node":"SplitInBatches","type":"main","index":0}]]},"Find & Select Episode":{"main":[[{"node":"Build request","type":"main","index":0}]]},"Search Show & Episode":{"main":[[{"node":"If found","type":"main","index":0}]]}}}