Friday, July 21, 2017

Netflix to Trakt.tv Sync

Update Details Below. Note that if the dialog shows an older version you may need to recreate your bookmarklet.

Also note that this will probably only work in English, though you may be able to temporally change your language on Netflix to get the sync to work.

There used to be a nice Chrome plugin to synchronize by Netflix history with Trakt.tv but it had been unreliable and doesn't seam to be working now.  I wrote this code to solve my own need but it does the same thing and I am posting it here for others to use.

Note that this is not 100% perfect as some show names aren't exactly the same and some Netflix show's don't use episode names at all. This code it not using any Netflix API calls but rather just scraping your Viewing Activity page and then making API calls to your Trakt.tv account to post the item's it finds.



You may need to manually select some episodes or shows on the Tract.tv side if they aren't matched and it is possible that duplicates could get synced if the names cause issues though I tried to prevent this. In short I'm not out to make this 100% perfect but it should get you 90% of the way and it shows all the changes it will post for confirmation before posting.

Usage

  • Drag this link, Sync to Trakt.tv, to your bookmark bar or bookmerks menu.
    • This is a bit of Javascript that will inject the Sync tool into your Netflix activity page.
  • Open Netflix in your browser and log in.
    • This is tested and working in Safari and Chrome.
  • Go here https://www.netflix.com/viewingactivity to see your history or click on your name in the top right, then on Account, and finally on Viewing Activity.
  • Netflix will not load your entire history so you will need to scroll down to get it to load more.  Keep doing this until all the history you want to sync has been loaded.
    • You don't have to do everything, if you are doing this regularly then the first screen or two will be sufficient.
  • Now for the magic click the bookmarklet you added while looking at the history page.
    • Note: The first tim you do this you will need to log in to Trakt.tv and click the bookmark again.
  • The script will scrape the Netflix page, they check each item in Trakt.tv and build a list of already synced items, items not found, and items scheduled to sync.
    • If re-running the tool past plays will be greyed out, new plays to by synced will be green,  items that could not be cached will remain white, and duplicate plays that are being ignored will be orange.
  • When you are satisfied just click Sync Now to post the changes.  You can then check Trakt.tv or reload the page and run the script again to see the results.

How It Works

This solution is a simple bit of javascript that scans your Netflix history page and sync's plays over to Trakt.tv. It also needs to read your list of past plays in Trakt.tv along with the history it reads from the Netflix page.

None of this data is saved or sent to any other servers in any way. As the script runs a listing of all the changes that will be posted to Trakt.tv is show with a confirmation option. No passwords or logins are prompted or recorded in any way. You are logging in yourself to Netflix and Trakt.tv, though you do have to grant this application API access to your account. The only bit that is saved is the Trakt.tv access token so that you don't have to log in on every use of the tool. You can even remove this by clearing the cookies for the www.netflix.com domain.

You can view the entire script here first if you wish. The bookmarklet code is an easy way to inject this code into your netflix page, you could also run this code manually in your browser console.

function load(filename, type){
 if(type == 'js'){
  var fileref=document.createElement('script');
  fileref.setAttribute('type','text/javascript');
  fileref.setAttribute('src',filename);
 }
 else if (type == 'css'){
  var fileref=document.createElement('link');
  fileref.setAttribute('rel','stylesheet');
  fileref.setAttribute('type','text/css');
  fileref.setAttribute('href',filename);
 }
 document.getElementsByTagName('head')[0].appendChild(fileref);
}
load('https://www.inkonit.com/netflix/netflix-sync.js?v1.5','js');
load('https://www.inkonit.com/netflix/netflix-sync.css?v1.5','css');

Working On/Planned

  • Ability to manually re-query a episode/movie with a custom name.
  • Ability to provide episode numbers or auto-detect them based on episode watch order.
  • Ability to tie track items to unknown items so they don't sync duplicates.
  • Ability to post mapping corrections back to the server so the corrections persist.

Updates

  • Updated 8/22/2017, v1.1
    • Added version number to script.
    • Fixes for many situations where a show, movie, or episode not being found would cause the entire script to never complete processing.
    • Manual fixes added for: MSK3k The Return, Marvel's The Defenders, items using Series and Collection nomenclature, items with (U.S) suffix.
    • Removed unneeded jquery-ui script.
  • Updated 8/23/2017, v1.2
    • Added error detection for cases where episode titles can't be determined.
    • Added checkbox option to prevent specific items form syncing in odd cases where they match incorrectly.
  • Update 8/24/2017, v1.3
    • Added another fix hard error when show name wasnt found.
    • Added support for shows and movies with Unicode charecters in names.
    • Fix for past plays in the format Title: Seaseon ##: Episode wouldnt match properly in history.
  • Update 8/28/2017, v1.4
    • Fix a typo breaking movies detection.
    • Added version number to console output.
  • Update 9/8/2017, v1.5
    • Added logic to guess episode numbers in Netflix based on play order. This will not work as expected if episodes are played out or order or if only part of the season is visible in the Netflix history. This is also only done as a last chance if no name matching finds a match. If there are incorrect items you can uncheck them to prevent errors or add #no-guess to your page url before running the script to disable this option.
    • Fixes for shows with numbers in the title. This was originally working but some unicode fixes I made broke it.
    • Fixes for shows with Part # in roman numerals.
    • Fixes for MythBusters, Stranger Things, and Wet Hot American Summer.

36 comments:

Odin Hauge Mo said...

Thank you so much for making this!

But, I'm not able to use it. It won't scan titles that's not available in my region. It just gives me this error:

[Error] TypeError: null is not an object (evaluating 'title.replace')
clean_title (netflix-sync.js:116)
(anonymous function) (netflix-sync.js:309)
filter
(anonymous function) (netflix-sync.js:308)
c (none:2:5841)
add (none:2:6143)
(anonymous function) (netflix-sync.js:293)
c (none:2:5841)
add (none:2:6143)
(anonymous function) (netflix-sync.js:275)
each (none:1:57534)
each (none:1:55386)
do_sync (netflix-sync.js:254)
(anonymous function) (netflix-sync.js:239)
c (none:2:5841)
fireWith (none:2:6649)
n (none:3:20507)
t (none:3:26832)

If I remove that title from the activity history, I get this error on another title (which is also not available in my region):

[Error] TypeError: undefined is not an object (evaluating 'data[0].show')
ajax (none:3:23126)
(anonymous function) (none:3:23402)
(anonymous function) (netflix-sync.js:268)
each (none:1:57534)
each (none:1:55386)
do_sync (netflix-sync.js:254)
(anonymous function) (netflix-sync.js:239)
c (none:2:5841)
fireWith (none:2:6649)
n (none:3:20507)
t (none:3:26832)

Unknown said...

Mine gets stuck at the red circle going around and around forever. I let it run for almost 24 hours and it never synced.

Odin Hauge Mo said...

You should check the chrome console, if there's any useful error messages. Right click the page > Inspect > Console.

Ryan Casler said...

Failed to load resource: the server responded with a status of 404 ()

Failed to load resource: net::ERR_BLOCKED_BY_CLIENT
none:3 [Deprecation] Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.

Odin Hauge Mo said...

That most likely means you are using adblock, and it's blocking something on the page. It that the only thing you see in the console? Run the netflix-sync script, while you have the console open. You can see at the right side of the console, which process that's reporting the entry. It should be 'netflix-sync-js'.

Jeremy Pyne said...

I made some updates to make this script quite a bit more reliable. It was crapping out when unknown shows, movies, or seasons were encountered in many cases instead of properly adding them to the Unknown Plays list. Should be cleared up now.

The Synchronous XMLHttpRequest error should not causes issues. This comes form async calls when comparing shows but if I turn that off it takes a lot longer to process.

I was running this in a clean browser so I don't know how add/script blockers may affect it.

Also note that that this will likely not work well in other languages.

Odin Hauge Mo said...

Thank you so much for taking time to improve your script for us.
It seems to be working now, but before I click the sync button. Does the script overwrite a trakt.tv watch history item if I already have a record of one of the episodes in my netflix history on both places, or does it add it as seen twice? Does it skip the item if it's already added on trakt?

Odin Hauge Mo said...

I tried to run the scrip for another user on my Netflix account, and get this error:

Loaded: Grand Hotel
⛔️ Uncaught TypeError: Cannot read property 'replace' of null
at clean_title (netflix-sync.js:120)
at netflix-sync.js:319
at Array.filter ()
at Object. (netflix-sync.js:318)
at c (none:2)
at Object.add [as done] (none:2)
at Object. (netflix-sync.js:303)
at c (none:2)
at Object.add [as done] (none:2)
at Object. (netflix-sync.js:282)


The script just stops at this point, and I'm stuck at the loading circle, and can't click the sync button.

Jeremy Pyne said...

It will try and match of past plays on both sides to prevent duplicate entries. So if you have one episode played on both sides on the same date it wont add it again. Unfortunately if the play date's don't match, or in some edge cases with weird title matching issues the player man get duplicated.

I have started code to manually change the matching name, and to specifically remove items from the sync that you know are messed up but said functionality isn't there yet.

Jeremy Pyne said...

I added more error code that should prevent the failing on shows where it can't find the episode title.

The issues for Grand Hotel I don't seam to have in my region so I can't test. Post the link to the item in Netflix and I can test.

Regardless it should not fail now but rather will just ignore the item.

Odin Hauge Mo said...

Here's the link to Grand Hotel: https://www.netflix.com/title/70308105

Odin Hauge Mo said...

I got that error for Pablo Escobar.

Odin Hauge Mo said...

I don't know why my comment isn't being displayed. This was the error I was talking about (Pablo Escobar). It stops the script, and I'm not able to sync.

Odin Hauge Mo said...

https://pastebin.com/qwQzhUgW

Jeremy Pyne said...

I added yet another fix for unexpected errors with shows not found.

Also unicode characters are causing issues and will not be matched properly. I'll see about a fix for this.

Odin Hauge Mo said...

Now I get this error for a movie called Results: https://pastebin.com/ypxqtLDc

Jeremy Pyne said...

Fixed erro on movie names. I don't see your error lining up to my lines of code. Ty again and may sure it says V1.4 in the dialog/console.

Also if still errors you can run watched or watched_history into the console to see the working objects and inspect them of any issues.

Each watched item that IsShow should have a title, season, show, and date. Each watched items that is a movie will just have a date and title.

watched_history would be a list of the item's processed so far before the crash that are expected to be synced.

Odin Hauge Mo said...

I was now able to sync watch history for all user on my Netflix account, thank you!
A minor problem, that I don't think is your fault, is Mythbusters is not syncing due to the seasons being numbers (1, 2 ,3...) on Netflix, and years on Trakt (2003, 2004, 2005...)

Stefan Preisinger said...

How can i help to get this script in the german version of netflix running? I need the sync that much ;)

Odin Hauge Mo said...

Just change the language to english in netflix settings, before you run the script.

Stefan Preisinger said...

I found it out 1 minute ago ;) Maybe you can post this in the main section. Thank you!

Odin Hauge Mo said...

That would be up to Jeremy Pyne. I did not make this article or the script.

Stefan Preisinger said...

Sorry, i have another question - How can i drag a play in the unknown plays of trakt an how can i specify a episode number eg in the unknown plays in netflix ? The text is greyed out- for example I want to specify House of Cards.

Odin Hauge Mo said...

I think that if they're unknown plays in trakt, you already have them on your trakt account. I just add unknown items manually. I haven't really figured out the "drag to specify" feature Jeremy Pyne added.

Jeremy Pyne said...

Sadly it's only planed and not yet working.

Jeremy Pyne said...

Mythbusters should work now but I can't test it.

smosse said...

thx alot for this amazing work !

Unknown said...

Thank you for this solution!

Hubert said...

Thank you Sooooo Much i was trying to figure out how simkl was doing it but your method was easier than making something. Thanks for sharing!

Odin Hauge Mo said...

The script now only detects movies, and skips episodes from series, telling me "Coudn't find movie: [episode name]" (btw, it's couldn't).

Jeremy Pyne said...

Hrm. I'm not seing that on my end. Has the episode name syntax changed on the netflix page. I see my history like so: Arrested Development: Season 3: "Family Ties" and the script breaks the string on :'s and trim's "'s. I'm not sure where the [episode name] is coming from. I did change it the other day to use javascript template literals but that should work on any browsers that this is designed for(Ff, Chrome, Safari).

What version is the dialog reporting, browser version, also try typing this in the console to see if literals are working.
`Netflix Sync: ${netflix_sync_version}`

Odin Hauge Mo said...

For me there is no quotations marks in the Netflix history. And my Netflix region and language is English/US (in case that makes a difference).

It says "v1.5.3 @10/9/2017" in the Trakt.tv Sync window.
I'm running Google Chrome 61.0.3163.100 (Official Build) (64-bit)

Console:

ᐳ `Netflix Sync: ${netflix_sync_version}`
ᑅ "Netflix Sync: 1.5.3"

Jeremy Pyne said...

Yes, so the quotations are the issues. I'm not sure why we are getting different rendering when using the same language but I'v updated the code to make the "'s optional. You will need to be getting v1.5.4 to get this fix.

Odin Hauge Mo said...

Okay, I'll test it right now.

Odin Hauge Mo said...

It looks like it's working again. Thank you!

Odin Hauge Mo said...

Just tried to run the script for another netflix user and got this error:


netflix-sync.js:20 Netflix Sync: 1.5.4
netflix-sync.js:184 Uncaught TypeError: Cannot read property 'indexOf' of null
at clean_title (netflix-sync.js:184)
at Object. (netflix-sync.js:285)
at none:1
at Function.grep (none:1)
at r (none:1)
at re.fn.init.filter (none:2)
at Object. (netflix-sync.js:281)
at Function.each (none:1)
at Object.success (netflix-sync.js:275)
at c (none:2)
clean_title @ netflix-sync.js:184
(anonymous) @ netflix-sync.js:285
(anonymous) @ none:1
grep @ none:1
r @ none:1
filter @ none:2
(anonymous) @ netflix-sync.js:281
each @ none:1
(anonymous) @ netflix-sync.js:275
c @ none:2
fireWith @ none:2
n @ none:3
t @ none:3
XMLHttpRequest.send (async)
send @ none:3
ajax @ none:3
re.(anonymous function) @ none:3
do_scrape @ netflix-sync.js:272
(anonymous) @ netflix-sync.js:88
none:3 [Violation] 'readystatechange' handler took 8992ms