Telegram Ad Filter

Collapses messages that contain words from the ad-word list

2019-03-21 기준 버전입니다. 최신 버전을 확인하세요.

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==UserScript==
// @name        Telegram Ad Filter
// @version     0.2.2
// @description Collapses messages that contain words from the ad-word list
// @license     MIT
// @author      VChet
// @namespace   Telegram-Ad-Filter
// @include     https://web.telegram.org/*
// @grant       GM_addStyle
// @grant       GM_getValue
// @grant       GM_setValue
// @grant       GM_registerMenuCommand
// ==/UserScript==
"use strict";

const defaultList = [
  "#взаимопиар",
  "#партнерский",
  "#постпроплачен",
  "#реклама",
  "#рекламныйпост",
  "#текстприслан",
];

let messages;
let messagesLength;
let adWords = GM_getValue("ad-words", defaultList);
let delay = GM_getValue("update-interval", 3000);

const applyStyles = messages => {
  // console.log({ adWords });
  messages.forEach(message => {
    message = message.querySelector(".im_message_body");
    if (message.innerText && adWords.some(v => message.innerText.toLowerCase().indexOf(v.toLowerCase()) >= 0)) {
      message.classList.add("advertisementMessage");
      message.onclick = () => message.classList.toggle("advertisementMessage");
    } else {
      message.classList.remove("advertisementMessage");
      message.onclick = null;
    }
  });
};

let eventTimeout;
const eventThrottler = delay => {
  if (!eventTimeout) {
    eventTimeout = setTimeout(() => {
      eventTimeout = null;
      messages = document.querySelectorAll(".im_history_message_wrap");
      if (messages.length === messagesLength || messages.length === 0) return;
      messagesLength = messages.length;
      // console.log({ messagesLength });
      applyStyles(messages);
    }, delay);
  }
};

GM_addStyle(`
  .advertisementMessage {
    max-height: 40px;
  }
  .advertisementMessage > div:before {
    color: dodgerblue;
    font-weight: bold;
    text-decoration: underline dotted;
    content: "Advertisement";
  }
`);

GM_registerMenuCommand("Filter list", () => {
  const wordList = GM_getValue("ad-words", adWords);
  let val = prompt("Enter words to filter, separated by comma:", wordList);
  if (val !== null && typeof val === "string") {
    // Convert string to array, remove empty entries, trim values
    val = val.split(",").filter(v => v).map(v => v.trim());
    adWords = val;
    GM_setValue("ad-words", val);
    messages = document.querySelectorAll(".im_history_message_wrap");
    applyStyles(messages);
  }
});

GM_registerMenuCommand("Update interval", () => {
  const updateInteval = GM_getValue("update-interval", delay);
  const val = prompt("Enter message scanning frequency (in ms):", updateInteval);
  if (val !== null && typeof val === "string") {
    delay = val;
    GM_setValue("update-interval", val);
  }
});

// Run the script when an API message is received, throttled with delay
window.addEventListener("message", () => eventThrottler(delay), false);