/** * Google MyActivity YouTube Comment Deletion Script * * Script to assist in bulk deletion of YouTube comments from Google's MyActivity. * * Usage: * - Navigate to MyActivity YouTube Comments page. * - Open browser's developer console. * - Copy-paste this script, and follow on-screen prompts. * * Features: * - Deletes comments from bottom (oldest first). * - User control: specify number to delete, or cancel anytime. * * Safety: * - Halting: 'cancel' during prompt or close tab. * * Author: Christian Prior-Mamulyan * License: MIT * Source: https://gist.github.com/cprima/2f7ea8e353c18a666506021c85e9773d * * Use cautiously. Deletion is irreversible. */ function navigateToCommentActivityPage() { const desiredURL = "https://myactivity.google.com/page?hl=en&utm_medium=web&utm_source=youtube&page=youtube_comments"; console.warn("The function 'navigateToCommentActivityPage' is deprecated. Please use ensureOnCorrectActivityPage()."); if (window.location.href !== desiredURL) { window.location.href = desiredURL; return false; } return true; } function ensureOnCorrectActivityPage() { const elementsData = [ { url: "https://myactivity.google.com/page?hl=en&utm_medium=web&utm_source=youtube&page=youtube_comments", content: "Your YouTube comments" }, { url: "https://myactivity.google.com/page?hl=en&utm_medium=web&utm_source=youtube&page=youtube_live_chat", content: "Your YouTube live chat messages" }, { url: "https://myactivity.google.com/page?hl=en&utm_medium=web&utm_source=youtube&page=youtube_comment_likes", content: "Your Likes and Dislikes on YouTube Comments" } ]; const currentUrl = window.location.href; const elementsWithClass = Array.from(document.querySelectorAll('.jPCT6')); for (let elementData of elementsData) { if (currentUrl.startsWith(elementData.url)) { if (elementsWithClass.some(el => el.textContent.toLowerCase().includes(elementData.content.toLowerCase()))) { console.log(`Matched URL: ${elementData.url} with content: "${elementData.content}"`); return true; // Matched desired URL with corresponding content. } } } console.log(`You are not on a recognized page. Please navigate to: ${elementsData[0].url}`); return false; } async function scrollToBottom() { while (!document.evaluate('//div[contains(text(), "Looks like you\'ve reached the end")]', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue) { window.scrollTo(0, document.body.scrollHeight); await new Promise(resolve => setTimeout(resolve, 1000)); } } function highlightElement(el) { el.style.backgroundColor = '#ffcccb'; // Light red setTimeout(() => { el.style.backgroundColor = ''; // Reset background color after 1s }, 1000); } function determineBestSelector() { const SELECTORS = [ '.VfPpkd-Bz112c-LgbsSe.yHy1rc.eT1oJ.mN1ivc', '[aria-label^="Delete activity item"]', '[jscontroller="soHxf"]' ]; // Get the selector that matches the least amount of elements (more specific) SELECTORS.sort((a, b) => document.querySelectorAll(a).length - document.querySelectorAll(b).length); return SELECTORS[0]; } let deleteButtons = []; async function deleteComments(deleteBatchSize) { const bestSelector = determineBestSelector(); if (!deleteButtons.length) { deleteButtons = [...document.querySelectorAll(bestSelector)]; //.reverse(); } let count = 0; while (deleteButtons.length && (count < deleteBatchSize || deleteBatchSize === Infinity)) { const btn = deleteButtons.pop(); // Scroll to the button to make it visible before deletion btn.scrollIntoView({ behavior: 'smooth', block: 'center' }); await new Promise(resolve => setTimeout(resolve, 1000)); // Give a moment for the scroll to finish highlightElement(btn); await new Promise(resolve => setTimeout(resolve, 2000)); // Wait for 2s for the highlight to be visible btn.click(); count++; await new Promise(resolve => setTimeout(resolve, 1500)); } return deleteButtons.length; // Return the number of remaining comments } async function initiateCommentDeletion() { // if (!navigateToCommentActivityPage()) { // return; // } if (!ensureOnCorrectActivityPage()) { return; } await scrollToBottom(); const bestSelector = determineBestSelector(); const totalComments = document.querySelectorAll(bestSelector).length; if (!totalComments) { console.log("No comments found for deletion."); return; } let userInput = prompt(`Found ${totalComments} comments. Enter 'a' to delete all comments or input a number to delete that many comments. Press 'Cancel' at any time to stop the script:`); while (userInput !== null) { if (userInput.toLowerCase() === 'a') { await deleteComments(Infinity); console.log("All comments deleted."); return; } else if (!isNaN(parseInt(userInput))) { const deleteBatchSize = parseInt(userInput); const remainingComments = await deleteComments(deleteBatchSize); if (!remainingComments) { console.log("All comments deleted."); return; } userInput = prompt(`${remainingComments} comments remaining. Enter 'a' to delete all remaining comments or input a number to delete that many comments. Press 'Cancel' at any time to stop the script:`); } else { userInput = prompt("Invalid input. Please enter 'a' or a number:"); } } console.log("Operation canceled. No further comments will be deleted."); } initiateCommentDeletion();