---
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 }}