Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ==UserScript==
- // @name Instagram Auto-Unliker
- // @namespace http://tampermonkey.net/
- // @version 1.0
- // @description Automatically unlikes all Instagram liked posts
- // @author you
- // @match https://www.instagram.com/your_activity/interactions/likes*
- // @grant none
- // ==/UserScript==
- (function() {
- 'use strict';
- const BATCH_SIZE = 10;
- const PAUSE_BETWEEN_BATCHES = 15000;
- const MAX_BATCHES = 10000;
- const STUCK_TIMEOUT = 20000;
- const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
- const saveProgress = (batchCount, totalUnliked) => {
- sessionStorage.setItem('ig_unlike_running', 'true');
- sessionStorage.setItem('ig_unlike_batch', batchCount);
- sessionStorage.setItem('ig_unlike_total', totalUnliked);
- };
- const loadProgress = () => {
- return {
- running: sessionStorage.getItem('ig_unlike_running') === 'true',
- batchCount: parseInt(sessionStorage.getItem('ig_unlike_batch') || '0'),
- totalUnliked: parseInt(sessionStorage.getItem('ig_unlike_total') || '0')
- };
- };
- const clearProgress = () => {
- sessionStorage.removeItem('ig_unlike_running');
- sessionStorage.removeItem('ig_unlike_batch');
- sessionStorage.removeItem('ig_unlike_total');
- };
- const countdown = async (seconds, message) => {
- for (let i = seconds; i > 0; i--) {
- console.log(`⏳ ${message} — ${i}s remaining...`);
- await sleep(1000);
- }
- };
- const humanClick = (el) => {
- const rect = el.getBoundingClientRect();
- const x = rect.left + rect.width / 2;
- const y = rect.top + rect.height / 2;
- const eventOptions = {
- bubbles: true,
- cancelable: true,
- view: window,
- clientX: x,
- clientY: y,
- screenX: x,
- screenY: y,
- buttons: 1
- };
- el.dispatchEvent(new MouseEvent('mouseover', eventOptions));
- el.dispatchEvent(new MouseEvent('mouseenter', eventOptions));
- el.dispatchEvent(new MouseEvent('mousemove', eventOptions));
- el.dispatchEvent(new MouseEvent('mousedown', eventOptions));
- el.dispatchEvent(new MouseEvent('mouseup', eventOptions));
- el.dispatchEvent(new MouseEvent('click', eventOptions));
- };
- const findSelectButton = () => {
- return Array.from(document.querySelectorAll('[data-bloks-name="bk.components.Flexbox"]'))
- .find(el => {
- const style = el.getAttribute('style') || '';
- return el.textContent.trim() === 'Select' && style.includes('cursor: pointer');
- });
- };
- const findUnlikeButton = () => {
- return Array.from(document.querySelectorAll('[data-bloks-name="bk.components.Flexbox"]'))
- .find(el => {
- const style = el.getAttribute('style') || '';
- return el.textContent.trim() === 'Unlike' && style.includes('cursor: pointer');
- });
- };
- const findConfirmUnlikeButton = () => {
- const nativeBtn = Array.from(document.querySelectorAll('button'))
- .find(el => el.textContent.trim() === 'Unlike');
- if (nativeBtn) return nativeBtn;
- const bloksBtn = Array.from(document.querySelectorAll('[data-bloks-name="bk.components.Flexbox"]'))
- .find(el => {
- const style = el.getAttribute('style') || '';
- return el.textContent.trim() === 'Unlike' && style.includes('cursor: pointer');
- });
- if (bloksBtn) return bloksBtn;
- return null;
- };
- const checkForErrorPopup = () => {
- const okBtn = Array.from(document.querySelectorAll('button'))
- .find(el => el.textContent.trim() === 'OK');
- if (okBtn) {
- console.log('⚠️ Error popup detected! Clicking OK and continuing...');
- humanClick(okBtn);
- return true;
- }
- return false;
- };
- const waitForSelectButton = async () => {
- const startTime = Date.now();
- console.log('⏳ Waiting for Select button...');
- while (true) {
- if (checkForErrorPopup()) {
- await sleep(3000);
- }
- const selectBtn = findSelectButton();
- if (selectBtn) return selectBtn;
- if (Date.now() - startTime > STUCK_TIMEOUT) {
- console.log('⚠️ Page stuck! Saving progress and refreshing...');
- return null;
- }
- const waited = Math.round((Date.now() - startTime) / 1000);
- console.log(`⏳ Still waiting for Select button... ${waited}s elapsed`);
- await sleep(1000);
- }
- };
- const getPostRows = () => {
- return Array.from(document.querySelectorAll('[role="button"][data-bloks-name="bk.components.Flexbox"]'))
- .filter(el => {
- return el.getAttribute('aria-label') === 'Image with button';
- });
- };
- (async function unlikeLoop() {
- // Wait for page to fully load before doing anything
- await sleep(5000);
- const progress = loadProgress();
- let batchCount = progress.batchCount;
- let totalUnliked = progress.totalUnliked;
- if (progress.running) {
- console.log(`♻️ Resuming after page refresh — Batch ${batchCount + 1}, ${totalUnliked} unliked so far`);
- } else {
- console.log('🚀 Instagram Auto-Unliker starting...');
- }
- while (batchCount < MAX_BATCHES) {
- console.log(`\n--- Batch ${batchCount + 1} | Total unliked so far: ${totalUnliked} ---`);
- if (checkForErrorPopup()) {
- await sleep(3000);
- }
- const selectBtn = await waitForSelectButton();
- if (!selectBtn) {
- saveProgress(batchCount, totalUnliked);
- console.log('Refreshing page, will auto-resume...');
- await sleep(1000);
- window.location.reload();
- return;
- }
- humanClick(selectBtn);
- console.log('✓ Clicked Select, waiting for UI...');
- await sleep(1500);
- if (checkForErrorPopup()) {
- await sleep(3000);
- continue;
- }
- const rows = getPostRows();
- console.log(`📋 Found ${rows.length} post rows in DOM`);
- if (rows.length === 0) {
- console.log('No post rows found. All done!');
- clearProgress();
- break;
- }
- let selectedCount = 0;
- for (let row of rows) {
- if (selectedCount >= BATCH_SIZE) break;
- humanClick(row);
- selectedCount++;
- console.log(` ☑️ Selected post ${selectedCount}/${BATCH_SIZE}`);
- await sleep(300);
- }
- console.log(`✓ Selected ${selectedCount} posts, looking for Unlike button...`);
- await sleep(1000);
- if (checkForErrorPopup()) {
- await sleep(3000);
- continue;
- }
- const unlikeBtn = findUnlikeButton();
- if (!unlikeBtn) {
- console.log('Unlike button not found. Dumping visible bloks buttons:');
- Array.from(document.querySelectorAll('[data-bloks-name="bk.components.Flexbox"]'))
- .forEach(el => {
- const t = el.textContent.trim();
- const s = el.getAttribute('style') || '';
- if (t && t.length < 30) console.log(` "${t}" | style="${s.substring(0, 60)}"`);
- });
- clearProgress();
- break;
- }
- humanClick(unlikeBtn);
- console.log('✓ Clicked Unlike, waiting for confirmation popup...');
- await sleep(3000);
- if (checkForErrorPopup()) {
- await sleep(3000);
- continue;
- }
- let confirmed = false;
- for (let attempt = 0; attempt < 5; attempt++) {
- if (checkForErrorPopup()) {
- await sleep(3000);
- confirmed = true;
- break;
- }
- const confirmBtn = findConfirmUnlikeButton();
- if (confirmBtn) {
- console.log(`✓ Found confirmation Unlike button, clicking... (attempt ${attempt + 1})`);
- humanClick(confirmBtn);
- await sleep(2000);
- if (checkForErrorPopup()) {
- await sleep(3000);
- confirmed = true;
- break;
- }
- const stillThere = findConfirmUnlikeButton();
- if (!stillThere) {
- console.log('✓ Popup dismissed successfully!');
- confirmed = true;
- break;
- } else {
- console.log('Popup still visible, retrying...');
- }
- } else {
- console.log(`Confirmation button not found (attempt ${attempt + 1}/5). Visible buttons:`);
- Array.from(document.querySelectorAll('button')).forEach(el => {
- const t = el.textContent.trim();
- if (t) console.log(` button: "${t}"`);
- });
- await sleep(1000);
- }
- }
- if (!confirmed) {
- console.log('Could not dismiss confirmation popup. Stopping.');
- clearProgress();
- break;
- }
- totalUnliked += selectedCount;
- batchCount++;
- console.log(`\n✅ Batch ${batchCount} complete! Total unliked: ${totalUnliked}`);
- await countdown(PAUSE_BETWEEN_BATCHES / 1000, `Pausing before batch ${batchCount + 1}`);
- }
- console.log(`\n🎉 All done! Batches completed: ${batchCount}, Total unliked: ${totalUnliked}`);
- clearProgress();
- })();
- })();
Advertisement
Add Comment
Please, Sign In to add comment