Giter Club home page Giter Club logo

rapidunlike's Introduction

๐Ÿš€ RapidUnlike ๐Ÿ’”

JavaScript Stars Size License: Unlicense IsMaintained

New year new you?

Want to start fresh?

Or just want to clean up your liked tweets?

RapidUnlike is a script that unlikes all your liked tweets at an impressive speed. It's simple, efficient, and user-friendly.

๐Ÿ”ง Features

  • Efficiency: Unlike thousands of tweets in minutes.
  • Smart Wait Times: Prevent rate-limiting with smart wait times between unlikes.
  • User-Friendly: Simple execution with UI start and stop, while providing a text preview of the unliked tweets, count total, and total time taken.

๐Ÿ“œ Instructions

  1. Navigate to your profile's "posts liked" page: https://www.x.com/yourusername/likes.

  2. Open the browser's console:

    • Linux, Windows, ChromeOS: Ctrl + Shift + J
    • macOS: Cmd + Option + J
  3. Copy the entirety of RapidUnlike and paste into the console then press Enter

    //โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
    //โ”‚  ____             _     _ _   _       _ _ _         โ”‚
    //โ”‚ |  _ \ __ _ _ __ (_) __| | | | |_ __ | (_) | _____  โ”‚
    //โ”‚ | |_) / _` | '_ \| |/ _` | | | | '_ \| | | |/ / _ \ โ”‚
    //โ”‚ |  _ < (_| | |_) | | (_| | |_| | | | | | |   <  __/ โ”‚
    //โ”‚ |_| \_\__,_| .__/|_|\__,_|\___/|_| |_|_|_|_|\_\___| โ”‚
    //โ”‚            |_|   https://github.com/ajwdd           โ”‚
    //โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
    
    // Configuration
    const config = {
      MAX_UNLIKES: 5500,
      BASE_WAIT_TIME: 250,
      INCREMENT_WAIT: 200,
      DECREMENT_WAIT: 50,
      RETRY_COUNT: 3,
      RATE_LIMIT_WINDOW: 60 * 1000, 
      RATE_LIMIT_MAX_UNLIKES: 50,
      PROGRESS_REPORT_INTERVAL: 60 * 1000,
    };
    
    // Helper functions
    function fetchLikes(lastButton = null) {
      const buttons = document.querySelectorAll('[data-testid="unlike"]');
      if (lastButton) {
        const lastButtonIndex = Array.from(buttons).findIndex(
          (button) => button === lastButton
        );
        return Array.from(buttons).slice(lastButtonIndex + 1);
      }
      return buttons;
    }
    
    function fetchTweetText(button) {
      const tweetElement = button
        .closest("article")
        .querySelector('[data-testid="tweetText"]');
      return tweetElement ? tweetElement.textContent : "No text found";
    }
    
    function wait(ms) {
      return new Promise((resolve) => setTimeout(resolve, ms));
    }
    
    function saveProgress(count) {
      localStorage.setItem("totalUnlikeCount", count);
    }
    
    function loadProgress() {
      return localStorage.getItem("totalUnlikeCount") || 0;
    }
    
    // UI elements
    const uiContainer = document.createElement("div");
    uiContainer.style.position = "fixed";
    uiContainer.style.top = "10px";
    uiContainer.style.right = "10px";
    uiContainer.style.backgroundColor = "#333";
    uiContainer.style.color = "#fff";
    uiContainer.style.padding = "10px";
    uiContainer.style.zIndex = "9999";
    
    const startButton = document.createElement("button");
    startButton.textContent = "Start";
    startButton.style.marginRight = "10px";
    const stopButton = document.createElement("button");
    stopButton.textContent = "Stop";
    stopButton.disabled = true;
    stopButton.style.marginRight = "10px";
    const pauseButton = document.createElement("button");
    pauseButton.textContent = "Pause";
    pauseButton.disabled = true;
    pauseButton.style.marginRight = "10px";
    const resumeButton = document.createElement("button");
    resumeButton.textContent = "Resume";
    resumeButton.disabled = true;
    const statusText = document.createElement("div");
    statusText.style.marginTop = "10px";
    const errorText = document.createElement("div");
    errorText.style.marginTop = "5px";
    
    uiContainer.appendChild(startButton);
    uiContainer.appendChild(stopButton);
    uiContainer.appendChild(pauseButton);
    uiContainer.appendChild(resumeButton);
    uiContainer.appendChild(statusText);
    uiContainer.appendChild(errorText);
    document.body.appendChild(uiContainer);
    
    let isRunning = false;
    let isPaused = false;
    let shouldStop = false;
    let unlikeCount = 0;
    let totalUnlikeCount = loadProgress();
    let errorCount = 0;
    let waitTime = config.BASE_WAIT_TIME;
    let lastUnlikeTime = Date.now();
    let lastProcessedButton = null;
    
    async function unlikeAll() {
      isRunning = true;
      isPaused = false;
      shouldStop = false;
      startButton.disabled = true;
      stopButton.disabled = false;
      pauseButton.disabled = false;
      resumeButton.disabled = true;
    
      const startTime = performance.now();
      let likeButtons = fetchLikes();
      let retryCount = 0;
    
      while (
        likeButtons.length > 0 &&
        unlikeCount < config.MAX_UNLIKES &&
        !shouldStop
      ) {
        for (const button of likeButtons) {
          if (isPaused) {
            await waitForResume();
          }
    
          if (shouldStop) {
            break;
          }
    
          try {
            const tweetText = fetchTweetText(button).slice(0, 150);
            console.log(`Unliking tweet: "${tweetText}"`);
            button.click();
            console.log(`%cUnliked ${++unlikeCount} tweets`, "color: aqua;");
            totalUnlikeCount++;
            saveProgress(totalUnlikeCount);
            updateUI();
            await wait(waitTime);
    
            // Adaptive timing
            if (waitTime > 1000 && errorCount === 0) {
              waitTime -= config.DECREMENT_WAIT;
            }
    
            // Rate limiting
            const now = Date.now();
            const elapsedTime = now - lastUnlikeTime;
            if (elapsedTime < config.RATE_LIMIT_WINDOW) {
              const unlikes = unlikeCount - loadProgress();
              if (unlikes >= config.RATE_LIMIT_MAX_UNLIKES) {
                const remainingTime = config.RATE_LIMIT_WINDOW - elapsedTime;
                console.log(
                  `Rate limit reached, waiting ${remainingTime / 1000} seconds`
                );
                await wait(remainingTime);
              }
            }
            lastUnlikeTime = now;
            retryCount = 0;
            lastProcessedButton = button;
          } catch (error) {
            console.error(`%cError unliking tweet: ${error}`, "color: red;");
            errorCount++;
            updateError(error);
            waitTime += config.INCREMENT_WAIT;
            retryCount++;
    
            if (retryCount >= config.RETRY_COUNT) {
              break;
            }
          }
        }
    
        if (errorCount === 0 && likeButtons.length > 0) {
          window.scrollTo(0, document.body.scrollHeight);
          await wait(3000);
          likeButtons = fetchLikes(lastProcessedButton);
        } else {
          errorCount = 0;
        }
      }
    
      const endTime = performance.now();
      const totalTime = (endTime - startTime) / 1000;
      console.log(`%cUnliked this session: ${unlikeCount}`, "color: aquamarine;");
      console.log(
        `%cTotal unliked with RapidUnlike = ${totalUnlikeCount}`,
        "color: aquamarine;"
      );
      console.log(
        `%cTotal time taken: ${totalTime.toFixed(2)} seconds`,
        "color: aquamarine;"
      );
    
      isRunning = false;
      startButton.disabled = false;
      stopButton.disabled = true;
      pauseButton.disabled = true;
      resumeButton.disabled = true;
      unlikeCount = 0;
    }
    
    function updateUI() {
      statusText.textContent = `Unliked this session: ${unlikeCount} | Total unliked with RapidUnlike: ${totalUnlikeCount}`;
    
      if (isRunning && !shouldStop) {
        setTimeout(updateUI, config.PROGRESS_REPORT_INTERVAL);
      }
    }
    
    function updateError(error) {
      errorText.textContent = `Error: ${error}`;
    }
    
    function waitForResume() {
      return new Promise((resolve) => {
        const checkResume = () => {
          if (!isPaused) {
            resolve();
          } else {
            setTimeout(checkResume, 1000);
          }
        };
        checkResume();
      });
    }
    
    startButton.addEventListener("click", unlikeAll);
    stopButton.addEventListener("click", () => {
      shouldStop = true;
    });
    pauseButton.addEventListener("click", () => {
      isPaused = true;
      pauseButton.disabled = true;
      resumeButton.disabled = false;
    });
    resumeButton.addEventListener("click", () => {
      isPaused = false;
      pauseButton.disabled = false;
      resumeButton.disabled = true;
    });

    C'est fini!


Note: Adjust the wait time (in milliseconds) according to your internet speed if needed.

rapidunlike's People

Contributors

ajwdd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Forkers

realdirac

rapidunlike's Issues

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.