--- description: |

Instagram Active/Inactive discover

. This is a script to discover active and inactive users in instagram It does this by user input: click on followers, or following, then click on the scrollable element. The script will then scroll through the list and determine if the user is active or inactive (has a reel, is verified, etc) params: | {type} describe what you expect to see as input {type} describe what you expect to see as input returns: | {bool} something something authors: | Kyle Suttlemyre originalsource: https://github.com/ktsuttlemyre/RogueBookmarklets layout: script --- {{ raw }} let parentScroll=null let list=null let lastElement=null let iterations=5 let storedData = localStorage.getItem('SHIPWASH_activityDB'); let activityDB = storedData ? JSON.parse(storedData) : {}; let scrollTimerID=null document.addEventListener('click', function(event) { console.log("You clicked this element:", event.target); // 1. Get the target element let targetElement = event.target; if(event.shiftKey){ if(list){ let listElement=findListElement(targetElement) let json=toJSON(listElement) activityDB[json.name]=1 localStorage.setItem('SHIPWASH_activityDB', JSON.stringify(activityDB)); } }else{ if(!parentScroll){ parentScroll = findHiddenOverflowParent(targetElement).parentElement if(!parentScroll){ console.warn('Choose an element to scroll') return }else{ scrollBy() } } } }); function findListElement(element){ //given element traverse up until you find the element that is equal to list variable let parent = element.parentElement; let listElement = element while (parent) { if (parent === list) { return listElement; } listElement = parent parent = parent.parentElement; } return null; } function findHiddenOverflowParent(element) { let parent = element.parentElement; while (parent) { // Get the computed style of the parent element const style = window.getComputedStyle(parent); // Check for 'overflow', 'overflow-x', or 'overflow-y' being 'hidden' or 'clip' // Note: 'clip' is an alternative to 'hidden' with similar behavior if ( style.overflow === 'hidden' || style.overflow === 'clip' || style.overflowX === 'hidden' || style.overflowX === 'clip' || style.overflowY === 'hidden' || style.overflowY === 'clip' ) { return parent; } // Move up to the next parent parent = parent.parentElement; } // If no parent with hidden overflow is found, return null return null; } function scrollBy(){ console.log('scrolling') if(!parentScroll){ console.warn('Choose an element to scroll') return } if(!list){ list=parentScroll.firstElementChild.firstElementChild hookMutator(list) } if(!list){ console.warn('cant find list to scroll') } //parent.scrollTo(0, list.lastElementChild.); parentScroll.scrollBy(0,9999) // 3. Scroll to the element with a smooth animation //list.lastElementChild.scrollIntoView({ // behavior: 'smooth', // block: 'end' // Aligns the top of the element to the top of the viewport //}); } function toJSON(element){ let o={ //hasReel:null, // isActive:null, // posts:null, // followers:null, // following:null, //isVerfied:null, //name:null, //isUser:null, // id:null, // link:null } //test for elements let test={} test.hasReel=!!element.querySelector('.html-div .html-div .html-div [role="button"][tabindex="0"]'); test.hasNotReel=!element.querySelector('.html-div .html-div .html-div [role="button"][aria-disabled="true"][tabindex="-1"]'); //turn tests into valid answers if(test.hasReel==true && test.hasNotReel==true){ o.hasReel=true } test.hasVerified=!!element.querySelector('svg[aria-label="Verified"][role="img"]') test.hasNotVerified=!!element.querySelector('svg[aria-label="Verified"][role="img"]') if(test.hasVerified==true && test.hasNotVerified==true){ o.isVerfied=true } test.name=element.querySelector('span[dir="auto"]') test.name=(test.name)?test.name.textContent:null; if(o.isVerfied||o.hasReel){ o.isUser=true; } Object.assign(o, activityDB[test.name]) o.name=test.name //return object return o } function hookMutator(list){ // 2. Create a MutationObserver instance const observer = new MutationObserver(function(mutationsList, observer) { // Loop through all reported mutations for(const mutation of mutationsList) { // Check if the change was adding child nodes if (mutation.type === 'childList') { // Check if any nodes were actually added if (mutation.addedNodes.length > 0) { //console.warn('New elements were added to the List!'); if(!iterations--){ return } clearTimeout(scrollTimerID) scrollTimerID=setTimeout(scrollBy,1000 * getRandomArbitrary(11,22)) // You can access the added nodes via mutation.addedNodes mutation.addedNodes.forEach(node => { // Ensure the added node is an actual element (not text/comment node) if (node.nodeType === Node.ELEMENT_NODE) { //console.warn('Added element:', node); let json = toJSON(node) //console.log(json) if(json.name){ if(json.isUser || activityDB[json.name]===1){ activityDB[json.name]=1 node.remove() }else{ activityDB[json.name]=json } } } }); localStorage.setItem('SHIPWASH_activityDB', JSON.stringify(activityDB)); } } } }); // 3. Configure and start the observer // We need to observe for childList changes const config = { childList: true }; // Start observing the target node for configured mutations observer.observe(list, config); } function getRandomArbitrary(min, max) { return Math.random() * (max - min) + min; } {{ endraw }}