Created
January 8, 2025 03:00
-
-
Save penk/1e66baba614f2c002bafb453a19153c1 to your computer and use it in GitHub Desktop.
Block unwanted post on facebook
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Helper to find parent element matching a condition | |
function findParentMatching(element, condition, maxDepth = 10) { | |
let current = element; | |
let depth = 0; | |
while (current && depth < maxDepth) { | |
if (condition(current)) { | |
return current; | |
} | |
current = current.parentElement; | |
depth++; | |
} | |
return null; | |
} | |
// Helper to find exactly "Follow" buttons | |
function findFollowButtons() { | |
// Find spans containing exactly "Follow" | |
const followSpans = Array.from(document.querySelectorAll('span')).filter( | |
(span) => span.textContent.trim() === 'Follow' | |
); | |
// Get their button parents | |
const followButtons = followSpans | |
.map((span) => findParentMatching(span, (el) => el.getAttribute('role') === 'button')) | |
.filter(Boolean); | |
console.log(`Found ${followButtons.length} Follow buttons`); | |
return followButtons; | |
} | |
function findMenuButton(followButton) { | |
let current = followButton; | |
let depth = 0; | |
while (current && depth < 20) { | |
// Does this container have the 3-dot menu inside it? | |
const menuButton = current.querySelector('div[aria-label="Actions for this post"]'); | |
if (menuButton) { | |
return menuButton; | |
} | |
current = current.parentElement; | |
depth++; | |
} | |
console.log('Could not find menu button'); | |
return null; | |
} | |
// Function to wait for and find a menu item by partial or exact text | |
async function findMenuItem(text, timeout = 3000) { | |
const startTime = Date.now(); | |
while (Date.now() - startTime < timeout) { | |
// Look for menu items containing the text | |
const items = Array.from(document.querySelectorAll('div[role="menuitem"]')).filter((item) => | |
item.textContent.includes(text) | |
); | |
if (items.length > 0) { | |
return items[0]; | |
} | |
// Wait a bit before trying again | |
await new Promise((resolve) => setTimeout(resolve, 100)); | |
} | |
return null; | |
} | |
// Function to block a post | |
async function blockPost(followButton) { | |
try { | |
console.log('Starting to process post...'); | |
// Find and click menu button | |
const menuButton = findMenuButton(followButton); | |
if (!menuButton) { | |
console.log('❌ Could not find the 3-dot menu for this post'); | |
return false; | |
} | |
console.log('Found menu button, clicking...'); | |
menuButton.click(); | |
// Find and click "Not interested" | |
console.log('Looking for Not interested option...'); | |
const notInterestedButton = await findMenuItem('Not interested'); | |
if (!notInterestedButton) { | |
console.log('❌ Could not find "Not interested" option in the menu'); | |
return false; | |
} | |
console.log('Clicking Not interested...'); | |
notInterestedButton.click(); | |
// Find and click "Block" or "Block profile" | |
console.log('Looking for Block profile option...'); | |
// The text might be "Block" or "Block profile" or "Block X", so we’ll try "Block" | |
const blockButton = await findMenuItem('Block'); | |
if (!blockButton) { | |
console.log('❌ Could not find Block/Block Profile option in the menu'); | |
return false; | |
} | |
console.log('Clicking Block profile...'); | |
blockButton.click(); | |
console.log('🚫 Successfully blocked profile'); | |
return true; | |
} catch (error) { | |
console.error('Error blocking post:', error); | |
return false; | |
} | |
} | |
// Main monitoring function | |
async function monitorPosts() { | |
console.log('🔎 Starting Facebook post blocker...'); | |
// Process any found posts | |
async function processNewPosts() { | |
const followButtons = findFollowButtons(); | |
for (const button of followButtons) { | |
console.log('Processing a post with Follow button...'); | |
const blocked = await blockPost(button); | |
if (blocked) { | |
console.log('✅ Successfully blocked post'); | |
} else { | |
console.log('❌ Failed to block post'); | |
} | |
// Wait between processing posts | |
await new Promise((resolve) => setTimeout(resolve, 2000)); | |
} | |
} | |
// Create observer for new content (so if FB loads more posts, we can re-scan) | |
const observer = new MutationObserver((mutations) => { | |
let hasNewContent = false; | |
mutations.forEach((mutation) => { | |
mutation.addedNodes.forEach((node) => { | |
if (node.nodeType === 1) { | |
hasNewContent = true; | |
} | |
}); | |
}); | |
if (hasNewContent) { | |
// Wait a bit for DOM to settle, then re-process | |
setTimeout(processNewPosts, 1500); | |
} | |
}); | |
// Start observing | |
const mainContent = document.querySelector('[role="main"]') || document.body; | |
observer.observe(mainContent, { | |
childList: true, | |
subtree: true, | |
}); | |
// Process existing posts | |
await processNewPosts(); | |
return observer; | |
} | |
// Start monitoring | |
const observer = monitorPosts(); | |
window.fbMonitor = observer; | |
// To stop monitoring later, type in console: | |
// window.fbMonitor.disconnect(); | |
console.log( | |
'%c✅ Paste successful! Facebook Post Blocker is now running.', | |
'color: #fff; background: green; padding:4px;' | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment