Skip to content

Instantly share code, notes, and snippets.

@MarkDarwin
Created September 24, 2022 09:30
Show Gist options
  • Save MarkDarwin/5f7786d9a508f427bc556acd2739b646 to your computer and use it in GitHub Desktop.
Save MarkDarwin/5f7786d9a508f427bc556acd2739b646 to your computer and use it in GitHub Desktop.
nextdns.io Block Youtube Ads
// CODE FROM : ducktapeonmydesk
const configID = "ABC123"; //the ID of the config, e.g. A1234BCD. Keep the parentheses
const APIKey = "YOURAPIKEY"; //your API key, found at the bottom of your account page. Keep the parentheses. https://my.nextdns.io/account
const retryFailedLinks = "Y"; //Mark "Y" or "N". If "Y", failed links will be retried 4 times at progressively increasing invtervals. If "N", failed links will not be retried. Keep the parentheses
const timeDelay = 800; //time delay between requests in milliseconds. 800 seems to not give any errors but is rather slow while anything faster will give errors (in limited testing). If you want to go lower, it is recommended that "retryFailedLinks" is marked "Y"
const ignoreDomainsSet = new Set([
"clients.l.google.com",
"clients1.google.com",
"clients2.google.com",
"clients3.google.com",
"clients4.google.com",
"clients5.google.com",
"clients6.google.com",
"akamaiedge.net",
]);
const youtubeAdDomainsSet = new Set();
const existingLinkSet = new Set();
const failedLinksSet = new Set();
const failedLinksSet2 = new Set();
const fetchEwprattenDomains = async () => {
const response = await fetch(
"https://raw.githubusercontent.com/Ewpratten/youtube_ad_blocklist/master/blocklist.txt"
);
const text = await response.text();
text.split("\n").forEach((line) => youtubeAdDomainsSet.add(line));
return;
};
const fetchkboghdadyDomains = async () => {
const response = await fetch(
"https://raw.githubusercontent.com/kboghdady/youTube_ads_4_pi-hole/master/youtubelist.txt"
);
const text = await response.text();
text.split("\n").forEach((line) => youtubeAdDomainsSet.add(line));
return;
};
const fetchGoodbyeAdsDomains = async () => {
const response = await fetch(
"https://raw.githubusercontent.com/jerryn70/GoodbyeAds/master/Formats/GoodbyeAds-YouTube-AdBlock-Filter.txt"
);
const text = await response.text();
text.split("\n").forEach((line) => {
if (line.startsWith("||") && line.endsWith("^")) {
const domain = line.substring(2, line.length - 1);
youtubeAdDomainsSet.add(domain);
}
});
return;
};
const fetchExistingLinks = async() => {
const response = await fetch(
`https://api.nextdns.io/profiles/${configID}/denylist`,
{
headers: {
"accept": "application/json, text/plain, */*",
"content-type": "application/json",
"X-Api-Key": JSON.stringify(APIKey),
},
method: "GET",
mode: "cors",
credentials: "include",
}
);
const text = await response.text();
text.split("{").forEach((line) => {
if (line.startsWith("\"id\"") && line.endsWith("\}\,")){
const oldLink = line.substring(6, line.length - 17);
existingLinkSet.add(oldLink);
}
})
return;
};
function sleep (milliseconds) {
return new Promise((resolve) => setTimeout(resolve, milliseconds))
}
const blockDomain = async (domain) =>
fetch(
`https://api.nextdns.io/profiles/${configID}/denylist`,
{
headers: {
"accept": "application/json, text/plain, */*",
"content-type": "application/json",
"X-Api-Key": JSON.stringify(APIKey),
},
body: JSON.stringify({id: domain, active: true}),
method: "POST",
mode: "cors",
credentials: "include",
}
).then((response) => {
if (response.ok) {
return (response.json)
}
throw "Error, going to reattempt 3 times at progressively increasing intervals";
});
const retryFailed = async() => {
const failedLinksArray = Array.from(failedLinksSet);
for (x = 0; x < failedLinksArray.length; x++) {
try {
console.log(
`Retrying to Block ${failedLinksArray[x]} Attempt 1/3 | ${x+1}/${failedLinksArray.length}`
);
await blockDomain(failedLinksArray[x]);
var retryCount = 1
} catch (error) {
console.error(error);
for (var retryCount=2; retryCount < 4; retryCount++){
try {
console.log(
`Retrying to Block ${failedLinksArray[x]} Attempt ${retryCount}/3 | ${x+1}/${failedLinksArray.length}`
);
await sleep(5000*(retryCount));
await blockDomain(failedLinksArray[x]);
}
catch (error) {
console.error(error);
if(retryCount==3){
failedLinksSet2.add(failedLinksArray[x])
};
};
};
};
};
};
const blockDomains = async () => {
console.log(`Downloading domains to block ...`);
await fetchEwprattenDomains(); //I recommend starting with only this list; you can comment out the the two lines below by preceding them with two backwards slashes, as can be seen preceding this comment.
await fetchkboghdadyDomains();
await fetchGoodbyeAdsDomains();
await fetchExistingLinks();
const youtubeAdDomains = Array.from(youtubeAdDomainsSet);
console.log(`Preparing to block ${youtubeAdDomains.length} domains`);
for (let idx = 0; idx < 1300; idx++) {
if (ignoreDomainsSet.has(youtubeAdDomains[idx])) {
console.log(
`Skipping ${youtubeAdDomains[idx]} ${idx}/${youtubeAdDomains.length}`
);
continue;
}
if (existingLinkSet.has(youtubeAdDomains[idx])) {
console.log(
`Skipping ${youtubeAdDomains[idx]} ${idx+1}/${youtubeAdDomains.length}`
);
continue;
}
try {
console.log(
`Blocking ${youtubeAdDomains[idx]} ${idx+1}/${youtubeAdDomains.length}`
);
await blockDomain(youtubeAdDomains[idx]);
} catch (error) {
console.error(error);
failedLinksSet.add(youtubeAdDomains[idx])
}
await sleep(timeDelay);
}
if (retryFailedLinks=="Y"){
await retryFailed();
console.log("Failed Links:", failedLinksSet2);
};
console.log("Have fun!");
};
blockDomains();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment