├── README.md └── core.js /README.md: -------------------------------------------------------------------------------- 1 | # Note: Github fixed it so no longer works but someting is kind interesting 🤣 2 | GitHub fixed it by using Base64 encoded timestamp (LOL🤣) page index instead of page number so it is harder to quickly navigate to different pages as predict the excat timestamp is hard. 3 | 4 | The page index looks like Base64 to me so I decoded some: 5 | 6 | Following: 7 | ``` 8 | Y3Vyc29yOnYyOpK5MjAxOS0wNi0wOVQxOToyNDo0MC0wNDowMM4Cut97 -> cursor:v2:2019-06-09T19:24:40-04:00{ 9 | Y3Vyc29yOnYyOpK5MjAxOS0wNi0yNVQyMTo0NzoxNi0wNDowMM4Cwicz -> cursor:v2:2019-06-25T21:47:16-04:00'3 10 | Y3Vyc29yOnYyOpK5MjAxOS0wNS0yNFQxMDowNDo1OC0wNDowMM4CsqPx -> cursor:v2:2019-05-24T10:04:58-04:00 11 | ``` 12 | 13 | Followers: 14 | ``` 15 | Y3Vyc29yOnYyOpK5MjAxNy0xMS0xMlQwMTowMToxMy0wNTowMM4Bve -> cursor:v2:2017-11-12T01:01:13-05:00 16 | Y3Vyc29yOnYyOpK5MjAxNy0xMS0xMlQwMDo1ODo1Ny0wNTowMM4Bve9S -> cursor:v2:2017-11-12T00:58:57-05:00R 17 | ``` 18 | 19 | That makes sense because the timestamp is used for pagination now instead of page number (from the timestamp get 20 records). 20 | I'm sure there is another easy way to get around this. Just don't have time to play with it. 21 | Have fun! 22 | 23 | 24 | 25 | ## Getting Started 26 | 27 | 1. add chrome extension `cjs` (add jQuery) 28 | 2. add the following code 29 | 3. goto followers or following page -> refresh page ... 30 | 31 | 32 | ```javascript 33 | 34 | $(document).ready(function() { 35 | // 1~2 sec 36 | var seed = parseInt(Math.random() * 1000) + 1000; 37 | 38 | //page 1 39 | var bt_disabled = $('.pagination span').text() === "Previous"; 40 | 41 | //last page, not prev/next btn 42 | var pre_next_btn = $('.pagination a').length; 43 | 44 | //users haven't been followed this page 45 | var users = $('.follow button'); 46 | 47 | //ex: "?page=100&tab=following" 48 | var urlPara = location.search; 49 | 50 | var currentPage = location.search.match(/-?\d+\.?\d*/) ? parseInt(location.search.match(/-?\d+\.?\d*/)[0]) : 0; 51 | 52 | //remove all unfollow form 53 | $('.unfollow').remove(); 54 | 55 | users.each(function(index, value) { 56 | let _this = $(this); 57 | setTimeout(function() { 58 | _this.trigger('click'); 59 | }, index * seed); 60 | }); 61 | 62 | setTimeout(function() { 63 | if (bt_disabled) { 64 | $('.pagination a')[0].click(); 65 | } else if (pre_next_btn === 0) { 66 | console.log('done......'); 67 | } else { 68 | window.location = window.location.pathname + location.search.replace(currentPage, currentPage + 1); 69 | } 70 | }, users.length * seed); 71 | }); 72 | 73 | 74 | ``` 75 | 76 | ## ~~What's next?~~ 77 | ~~Current speed: 12 following / sec (43,000 / hour), it is easy to get 300k following but to scale up to 10 million following this is slow.~~ 78 | 79 | 80 | ### make sure you know what you are doing... LoL (your account could get suspended 😂😂😂 ...) 81 | -------------------------------------------------------------------------------- /core.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | // 1~2 sec 3 | var seed = parseInt(Math.random() * 1000) + 1000; 4 | //page 1 5 | var bt_disabled = $('.pagination span').text() === "Previous"; 6 | //last page, not prev/next btn 7 | var pre_next_btn = $('.pagination a').length; 8 | //users haven't been followed this page 9 | var users = $('.follow button'); 10 | 11 | //ex: "?page=100&tab=following" 12 | var urlPara = location.search; 13 | 14 | var currentPage = location.search.match(/-?\d+\.?\d*/) ? parseInt(location.search.match(/-?\d+\.?\d*/)[0]) : 0; 15 | //remove all unfollow form 16 | $('.unfollow').remove(); 17 | 18 | users.each(function(index, value) { 19 | let _this = $(this); 20 | setTimeout(function() { 21 | _this.trigger('click'); 22 | }, index * seed); 23 | }); 24 | 25 | setTimeout(function() { 26 | if (bt_disabled) { 27 | $('.pagination a')[0].click(); 28 | } else if (pre_next_btn === 0) { 29 | console.log('done......'); 30 | } else { 31 | window.location = window.location.pathname + location.search.replace(currentPage, currentPage + 1); 32 | } 33 | }, users.length * seed); 34 | }); 35 | --------------------------------------------------------------------------------