Created
June 18, 2025 06:12
-
-
Save whocalledit/8bb50284645b568850e636cc0913930d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Instagram Mass Unfollow Script | |
// WARNING: Use at your own risk. Instagram may detect and penalize automated behavior. | |
async function massUnfollow() { | |
console.log('π Starting improved mass unfollow process...'); | |
// Configuration | |
const DELAY_MIN = 3000; // Minimum delay between actions (3 seconds) | |
const DELAY_MAX = 6000; // Maximum delay between actions (6 seconds) | |
const MODAL_WAIT = 2000; // Wait time for modal to appear | |
let unfollowedCount = 0; | |
let totalAttempts = 0; | |
let errors = 0; | |
// Function to create random delay | |
function randomDelay(min = DELAY_MIN, max = DELAY_MAX) { | |
return Math.floor(Math.random() * (max - min + 1)) + min; | |
} | |
// Function to wait for element to appear | |
function waitForElement(selector, timeout = 5000) { | |
return new Promise((resolve, reject) => { | |
const startTime = Date.now(); | |
function check() { | |
const element = document.querySelector(selector); | |
if (element) { | |
resolve(element); | |
} else if (Date.now() - startTime > timeout) { | |
reject(new Error(`Element ${selector} not found within ${timeout}ms`)); | |
} else { | |
setTimeout(check, 100); | |
} | |
} | |
check(); | |
}); | |
} | |
// Function to find following buttons more accurately | |
function findFollowingButtons() { | |
// Look for buttons with specific text content | |
const allButtons = Array.from(document.querySelectorAll('button')); | |
return allButtons.filter(button => { | |
const text = button.textContent.trim(); | |
const hasFollowingText = text === 'Following' || text === 'following'; | |
// Additional check: look for buttons that have following-related attributes | |
const hasFollowingClass = button.className.includes('follow') || | |
button.getAttribute('aria-label')?.includes('Following'); | |
return hasFollowingText || hasFollowingClass; | |
}); | |
} | |
// Function to handle individual unfollow | |
async function unfollowUser(button) { | |
try { | |
console.log(`π― Attempting to unfollow user...`); | |
// Click the Following button | |
button.scrollIntoView({ behavior: 'smooth', block: 'center' }); | |
await new Promise(resolve => setTimeout(resolve, 500)); | |
button.click(); | |
console.log('β Clicked Following button'); | |
// Wait for modal to appear | |
await new Promise(resolve => setTimeout(resolve, MODAL_WAIT)); | |
// Try multiple selectors for the unfollow confirmation button | |
const unfollowSelectors = [ | |
'button[class*="confirm"]', | |
'button[type="button"]:not([aria-label*="Close"])', | |
'div[role="dialog"] button', | |
'button' | |
]; | |
let confirmButton = null; | |
// First, try to find button by text content | |
const allModalButtons = Array.from(document.querySelectorAll('div[role="dialog"] button, [role="presentation"] button')); | |
confirmButton = allModalButtons.find(btn => { | |
const text = btn.textContent.trim().toLowerCase(); | |
return text === 'unfollow' || text.includes('unfollow'); | |
}); | |
if (!confirmButton) { | |
// If not found by text, try other selectors | |
for (const selector of unfollowSelectors) { | |
const buttons = document.querySelectorAll(selector); | |
const potentialButton = Array.from(buttons).find(btn => { | |
const text = btn.textContent.trim().toLowerCase(); | |
return text === 'unfollow' || text.includes('unfollow'); | |
}); | |
if (potentialButton) { | |
confirmButton = potentialButton; | |
break; | |
} | |
} | |
} | |
if (confirmButton) { | |
confirmButton.click(); | |
console.log('β Clicked Unfollow confirmation'); | |
unfollowedCount++; | |
// Wait for modal to close | |
await new Promise(resolve => setTimeout(resolve, 1000)); | |
return true; | |
} else { | |
console.log('β Could not find Unfollow confirmation button'); | |
// Try to close modal by clicking outside or pressing Escape | |
const backdrop = document.querySelector('[role="presentation"], [data-testid="modal-backdrop"]'); | |
if (backdrop) { | |
backdrop.click(); | |
} else { | |
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape' })); | |
} | |
return false; | |
} | |
} catch (error) { | |
console.error('β Error during unfollow:', error.message); | |
errors++; | |
// Try to close any open modals | |
try { | |
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape' })); | |
} catch (e) {} | |
return false; | |
} | |
} | |
// Main processing function | |
async function processUsers() { | |
console.log('π Looking for Following buttons...'); | |
const followingButtons = findFollowingButtons(); | |
console.log(`π Found ${followingButtons.length} Following buttons`); | |
if (followingButtons.length === 0) { | |
console.log('π No Following buttons found. Scrolling to load more...'); | |
// Scroll to load more | |
window.scrollTo(0, document.body.scrollHeight); | |
await new Promise(resolve => setTimeout(resolve, 3000)); | |
// Check again after scrolling | |
const newButtons = findFollowingButtons(); | |
if (newButtons.length === 0) { | |
console.log('π No more users to unfollow!'); | |
return false; | |
} | |
return true; | |
} | |
// Process users one by one | |
for (let i = 0; i < Math.min(followingButtons.length, 5); i++) { // Process max 5 at a time | |
const button = followingButtons[i]; | |
totalAttempts++; | |
console.log(`\nπ€ Processing user ${totalAttempts} (${i + 1}/${Math.min(followingButtons.length, 5)})`); | |
const success = await unfollowUser(button); | |
if (success) { | |
console.log(`β Successfully unfollowed user ${unfollowedCount}`); | |
} else { | |
console.log(`β Failed to unfollow user`); | |
} | |
// Random delay between users | |
const delay = randomDelay(); | |
console.log(`β±οΈ Waiting ${delay}ms before next user...`); | |
await new Promise(resolve => setTimeout(resolve, delay)); | |
} | |
return true; | |
} | |
// Main execution | |
console.log('π¬ Starting unfollow process...'); | |
console.log('π Make sure you are on your Following list page!'); | |
try { | |
let continueProcessing = true; | |
let rounds = 0; | |
while (continueProcessing && rounds < 50) { // Safety limit | |
rounds++; | |
console.log(`\nπ Round ${rounds}`); | |
continueProcessing = await processUsers(); | |
if (continueProcessing) { | |
// Wait between rounds | |
const roundDelay = randomDelay(5000, 8000); | |
console.log(`βΈοΈ Waiting ${roundDelay}ms before next round...`); | |
await new Promise(resolve => setTimeout(resolve, roundDelay)); | |
} | |
} | |
} catch (error) { | |
console.error('π₯ Fatal error:', error); | |
} | |
// Final summary | |
console.log(`\nπ === FINAL SUMMARY ===`); | |
console.log(`β Successfully unfollowed: ${unfollowedCount} users`); | |
console.log(`π― Total attempts: ${totalAttempts}`); | |
console.log(`β Errors encountered: ${errors}`); | |
console.log(`π Success rate: ${totalAttempts > 0 ? Math.round((unfollowedCount / totalAttempts) * 100) : 0}%`); | |
} | |
// Enhanced debug function to inspect current page | |
function debugInstagramPage() { | |
console.log('π === DEBUG INFO ==='); | |
console.log('Current URL:', window.location.href); | |
const followingButtons = Array.from(document.querySelectorAll('button')).filter(btn => { | |
const text = btn.textContent.trim(); | |
return text === 'Following' || text === 'following'; | |
}); | |
console.log(`Found ${followingButtons.length} Following buttons`); | |
if (followingButtons.length > 0) { | |
console.log('Sample button:', followingButtons[0]); | |
console.log('Sample button text:', followingButtons[0].textContent); | |
console.log('Sample button classes:', followingButtons[0].className); | |
} | |
// Check if we're on the right page | |
const isFollowingPage = window.location.href.includes('/following/') || | |
document.querySelector('h1')?.textContent?.includes('Following'); | |
console.log('On Following page:', isFollowingPage); | |
console.log('==================='); | |
} | |
// Instructions | |
console.log(` | |
π― === INSTAGRAM MASS UNFOLLOW SCRIPT - FIXED VERSION === | |
π SETUP INSTRUCTIONS: | |
1. Go to your Instagram profile | |
2. Click on "96 following" to open your following list | |
3. Wait for the list to fully load | |
4. Open browser console (F12 β Console tab) | |
5. Run this script | |
π§ AVAILABLE COMMANDS: | |
β’ massUnfollow() - Start the unfollow process | |
β’ debugInstagramPage() - Check if setup is correct | |
β οΈ IMPORTANT: | |
- Make sure you're on the Following list page | |
- The script processes 5 users at a time for safety | |
- Uses random delays to avoid detection | |
- Will automatically scroll to load more users | |
π TO START: Type massUnfollow() and press Enter | |
π TO DEBUG: Type debugInstagramPage() and press Enter | |
`); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment