HaGeZi Most Abused TLDs to NextDNS

27/08/2025, 03:09:08

当前为 2025-08-27 提交的版本,查看 最新版本

// ==UserScript==
// @name        HaGeZi Most Abused TLDs to NextDNS
// @namespace   vietthe.dev
// @match       https://my.nextdns.io/*/*
// @grant       none
// @version     1.0
// @license     MIT
// @author      Salad
// @compatible  firefox Violentmonkey
// @compatible  firefox Tampermonkey
// @compatible  firefox FireMonkey
// @compatible  chrome Violentmonkey
// @compatible  chrome Tampermonkey
// @compatible  opera Violentmonkey
// @compatible  opera Tampermonkey
// @compatible  safari Stay
// @compatible  edge Violentmonkey
// @compatible  edge Tampermonkey
// @compatible  brave Violentmonkey
// @compatible  brave Tampermonkey
// @description 27/08/2025, 03:09:08
// ==/UserScript==

/* jshint esversion:2020 */

(async () => {
  const apiHost = "https://api.nextdns.io"
  const profileId = window.location.href.split("/")[3]
  const invalidTlds = ["non"]

  const sleep = (ms = 500) => new Promise((resolve) => setTimeout(() => resolve(), ms))

  const toHex = (text) => {
    let hex = ''

    for (let i = 0; i < text.length; i++) {
      const charCode = text.charCodeAt(i)
      const hexCode = charCode.toString(16).padStart(2, '0')

      hex += hexCode
    }

    return hex;
  }

  const callApi = (path, options) => fetch(`${apiHost}${path}`, {
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
    mode: "cors",
    credentials: "include",
    ...options,
  })

  const getSecurity = () => callApi(`/profiles/${profileId}/security`).then((res) => res.json())

  const getAllowlist = () => callApi(`/profiles/${profileId}/allowlist`).then((res) => res.json())

  const getAbusedTlds = async () => {
    const content = await fetch("https://raw.githubusercontent.com/hagezi/dns-blocklists/main/adblock/spam-tlds-adblock-aggressive.txt").then(res => res.text())
    const tlds = content.trim().match(/^\|\|(xn--)?\w+\^$/gm).map((e) => e.slice(2, -1))

    return tlds
  }

  const getTldAllowlist = async () => {
    const content = await fetch("https://raw.githubusercontent.com/hagezi/dns-blocklists/main/adblock/spam-tlds-adblock-allow.txt").then(res => res.text())
    const domains = content.trim().split("\n").map((e) => e.slice(4, -1))

    return domains
  }

  const addTld = (tld) => callApi(`/profiles/${profileId}/security/tlds`, {
    method: "POST",
    body: JSON.stringify({ id: tld }),
  })

  const removeTld = (tld) => callApi(`/profiles/${profileId}/security/tlds/hex:${toHex(tld)}`, {
    method: "DELETE",
  })

  const allowlistDomain = (domain) => callApi(`/profiles/${profileId}/allowlist`, {
    method: "POST",
    body: JSON.stringify({ active: true, id: domain }),
  })

  const run = async () => {
    const currentTlds = (await getSecurity()).data.tlds.map(({ id }) => id)
    const currentAllowlist = (await getAllowlist()).data.map(({ id }) => id)
    const tlds = await getAbusedTlds()
    const tldAllowlist = await getTldAllowlist()
    const tldsToAdd = tlds.filter((e) => !currentTlds.includes(e) && !invalidTlds.includes(e))
    const domainsToAllowlist = tldAllowlist.filter((e) => !currentAllowlist.includes(e))

    console.info({ currentTlds, currentAllowlist, tldsToAdd, domainsToAllowlist })

    for (const tld of tldsToAdd) {
      console.info(`Adding .${tld} to TLD blocklist`)
      await addTld(tld)
      await sleep()
    }

    for (const domain of domainsToAllowlist) {
      console.info(`Adding ${domain} to allowlist`)
      await allowlistDomain(domain)
      await sleep()
    }
  }

  console.info("HaGeZi Most Abused TLDs to NextDNS is running...")

  await run()

  console.info("Done.")
})()

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址