Greasy Fork is available in English.

Block Promoted Tweets and Stuff

If twitter promotes their tweet, we'll block it, or your money back!

Verze ze dne 24. 07. 2023. Zobrazit nejnovější verzi.

// ==UserScript==
// @name           Block Promoted Tweets and Stuff
// @name:fr        Bloque les Gazouillis Sponsorisés et Tout Ça
// @namespace      Itsnotlupus Industries
// @match          https://twitter.com/*
// @grant          none
// @version        1.5
// @author         -
// @description    If twitter promotes their tweet, we'll block it, or your money back!
// @description:fr Si twitter promouvois leur gazouillage, on les bloque, ou remboursé!
// @license        MIT
// @require        https://greatest.deepsurf.us/scripts/468394-itsnotlupus-tiny-utilities/code/utils.js
// @require        https://unpkg.com/[email protected]/dist/moduleraid.umd.js
// ==/UserScript==
/*jshint esversion: 11 */
/*globals $$$: false */

(async ()=> {

  // English twitter strings we use to find the bits of page content we need.
  const strings = [ 'Verified', 'Promoted', 'More', 'Get Verified'];

  const i18n = { 'en': strings.reduce((o, v) => (o[v]=v,o), {}) };
  const lang = document.documentElement.lang;
  if (lang !== 'en') {
    // Translate those strings using Twitter's own data.
    // This means this script works with all languages Twitter supports.
    const mR = new moduleraid({ entrypoint: "webpackChunk_twitter_responsive_web", debug: false });
    const [[,twitterI18N]] = mR.findConstructor('knownLanguages');
    await twitterI18N.loadLanguage('en');
    const stringIds = strings.map(s=>Object.keys(twitterI18N).find(k => twitterI18N[k]===s));
    await twitterI18N.loadLanguage(lang);
    i18n[lang] = stringIds.map(id => twitterI18N[id]).reduce((o,v,i) => (o[strings[i]]=v,o), {});
  }

  const t = s => i18n[lang]?.[s] ?? s;

  // inject styles to hide elmo's upselling - respect yoself, don't buy a checkmark
  addStyles(`
  [aria-label="${t`Verified`}"] {
    display: none !important;
  }
  `);

  // auto-block promoters.
  (async function blockPromotedAccounts() {
    while (true) {
      const tweets = await untilDOM(()=>$$$(`//article[@role='article']/div/div/div/div/div/div/div/span[text()='${t`Promoted`}']/../../../../..`));
      for (const tweet of tweets) {
        const moreButton = tweet.querySelector(`[aria-label="${t`More`}"]`);
        if (moreButton) {
          console.log("Found a promoted Tweet!", tweet.innerText);
          moreButton.click();
          (await untilDOM('[data-testid="block"]')).click();
          (await untilDOM('[data-testid="confirmationSheetConfirm"]')).click();
          console.log("Blocked tweet promoter");
        }
      }
      // twitter is buggy, so blocking someone doesn't necessarily remove their tweets immediately. sleep on it.
      await sleep(500);
    }
  })();

  // remove "Get Verified" upsell in the right column
  (async function removeGetVerifiedBlock() {
    while (true) {
      (await untilDOM(() => $$$(`.//*[text()[contains(.,'${t`Get Verified`}')]]/../../..`)[0])).remove();
    }
  })();

})();