您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Automation tool that sets posts in facebooks activity log to private for the new 2020 design
当前为
// ==UserScript== // @name facebook set posts to private // @description Automation tool that sets posts in facebooks activity log to private for the new 2020 design // @author Yorai Levi // @namespace https://github.com/YoraiLevi // @update https://raw.githubusercontent.com/YoraiLevi/SetFacebookPostsPrivate/master/GreaseMonkeySetFacebookPrivate.user.js // @supportURL https://github.com/YoraiLevi/SetFacebookPostsPrivate/issues // @include https://www.facebook.com/* // @version 0.21.1 // @grant GM_setValue // @grant GM_getValue // @grant GM.openInTab // @grant window.close // @run-at document-idle // ==/UserScript== //3 user scripts merged into a single file: (function () { 'use strict'; const SCRIPT_NAME = "facebook set posts to private" console.log('Loading', SCRIPT_NAME) let GLOBAL_TIMEOUT = Infinity function delayPromise(delay) { return new Promise(resolve => setTimeout(() => { resolve() }, delay)) } async function get_selector_visible(selector, period, timeout = GLOBAL_TIMEOUT) { let s_time = performance.now() while (performance.now() - s_time < timeout) { let obj = document.querySelector(selector) if (obj && !(window.getComputedStyle(obj).display === "none" || window.getComputedStyle(obj).visibility === "hidden")) // checks if exists in dom? and supposedly? visible return obj await delayPromise(period) } throw "Waiting timed out: " + selector; } async function get_selector_not_visible(selector, period, timeout = GLOBAL_TIMEOUT) { let s_time = performance.now() while (performance.now() - s_time < timeout) { let obj = document.querySelector(selector) if (!obj || (window.getComputedStyle(obj).display === "none" || window.getComputedStyle(obj).visibility === "hidden")) // checks if exists in dom? and supposedly? visible return obj await delayPromise(period) } throw "Waiting timed out: " + selector; } //set privacy action if (document.URL.match("https://www.facebook.com/.+/posts/.+|https://www.facebook.com/photo.+")) { (function () { 'use strict'; console.log("Initializing") let three_dot_menu_selector = "div > div.nqmvxvec.j83agx80.jnigpg78.cxgpxx05.dflh9lhu.sj5x9vvc.scb9dxdr.odw8uiq3 > div > div" let menu_buttons_selector = "div.cwj9ozl2.ue3kfks5.pw54ja7n.uo3d90p7.l82x9zwi.nwpbqux9.rq0escxv.jgsskzai.ni8dbmo4.stjgntxs > div > div.j83agx80.cbu4d94t.buofh1pr > div.tojvnm2t.a6sixzi8.k5wvi7nf.q3lfd5jv.pk4s997a.bipmatt0.cebpdrjk.qowsmv63.owwhemhu.dp1hu0rb.dhp61c6y.l9j0dhe7.iyyx5f41.a8s20v7p > div" let only_me_choice_selector = "div.kr520xx4.pedkr2u6.ms05siws.pnx7fd3z.b7h9ocf4.pmk7jnqg.j9ispegn.k4urcfbm > div.cbu4d94t.j83agx80 > div > div > div > div > div > div > div:nth-child(5) > div" window.addEventListener('load', async () => { await delayPromise(1000) setPrivate() }) async function setPrivate() { console.log("Setting post to private") //checking privacy state: const only_me_lock_icon = "https://static.xx.fbcdn.net/rsrc.php/v3/yD/r/JSmL99pVrUz.png" let audience = document.querySelector("div > span > span > div > div > div> img") if (audience && audience.src === only_me_lock_icon) close() //The actual action to set a post to private let three_dot_menu = await get_selector_visible(three_dot_menu_selector) three_dot_menu.click() let edit_audience_menu_button = null await get_selector_visible(menu_buttons_selector) let buttons = document.querySelectorAll(menu_buttons_selector) //audience icrons: //public : https://static.xx.fbcdn.net/rsrc.php/v3/yS/r/k1K2sJ70emI.png //friends with/out : https://static.xx.fbcdn.net/rsrc.php/v3/yH/r/hHt2U1bRtLs.png //specific friends : https://static.xx.fbcdn.net/rsrc.php/v3/yv/r/cD5R2-Z_DDa.png //lock - private : https://static.xx.fbcdn.net/rsrc.php/v3/yU/r/cfUGV2EoMCu.png let imgs = ["https://static.xx.fbcdn.net/rsrc.php/v3/yS/r/k1K2sJ70emI.png", "https://static.xx.fbcdn.net/rsrc.php/v3/yH/r/hHt2U1bRtLs.png", "https://static.xx.fbcdn.net/rsrc.php/v3/yv/r/cD5R2-Z_DDa.png", "https://static.xx.fbcdn.net/rsrc.php/v3/yU/r/cfUGV2EoMCu.png" ] for (const b of buttons) { //make cross language with icon detection instead? let img = b.querySelector("*> img") if (img && imgs.indexOf(img.src) !== -1) edit_audience_menu_button = b } if (edit_audience_menu_button) { edit_audience_menu_button.click() } else { close() } let only_me_choice = await get_selector_visible(only_me_choice_selector) await delayPromise(1000) //dummy(presses the x to close window) // let closeX = await get_selector_visible("#mount_0_0 > div > div:nth-child(1) > div.rq0escxv.l9j0dhe7.du4w35lb > div:nth-child(5) > div > div > div.rq0escxv.l9j0dhe7.du4w35lb > div > div.iqfcb0g7.tojvnm2t.a6sixzi8.k5wvi7nf.q3lfd5jv.pk4s997a.bipmatt0.cebpdrjk.qowsmv63.owwhemhu.dp1hu0rb.dhp61c6y.l9j0dhe7.iyyx5f41.a8s20v7p > div > div > div > div > div.kr520xx4.pedkr2u6.ms05siws.pnx7fd3z.b7h9ocf4.pmk7jnqg.j9ispegn.k4urcfbm > div.cypi58rs.pmk7jnqg.fcg2cn6m.tkr6xdv7 > div") // closeX.click() only_me_choice.click() await get_selector_not_visible(only_me_choice_selector) //wait for privacy to change in page while (audience && audience.src !== "https://static.xx.fbcdn.net/rsrc.php/v3/yD/r/JSmL99pVrUz.png") { console.log("Waiting for audience to update") await delayPromise(100) } close() } })(); } //inject activity manager else if (document.URL.match("https://www.facebook.com/.+/allactivity.+")) { (function () { 'use strict' console.log("Initializing") function get_items() { let activity_selector = "div > div:nth-child(1) > div.rq0escxv.l9j0dhe7.du4w35lb > div.rq0escxv.l9j0dhe7.du4w35lb > div > div > div.j83agx80.cbu4d94t.d6urw2fd.dp1hu0rb.l9j0dhe7.du4w35lb > div.rq0escxv.l9j0dhe7.du4w35lb.j83agx80.pfnyh3mw.jifvfom9.gs1a9yip.owycx6da.btwxx1t3.buofh1pr.dp1hu0rb.ka73uehy > div.rq0escxv.l9j0dhe7.tkr6xdv7.j83agx80.cbu4d94t.pfnyh3mw.d2edcug0.hpfvmrgz.dp1hu0rb.rek2kq2y.o36gj0jk > div > div.q5bimw55.rpm2j7zs.k7i0oixp.gvuykj2m.j83agx80.cbu4d94t.ni8dbmo4.eg9m0zos.l9j0dhe7.du4w35lb.ofs802cu.pohlnb88.dkue75c7.mb9wzai9.d8ncny3e.buofh1pr.g5gj957u.tgvbjcpo.l56l04vs.r57mb794.kh7kg01d.c3g1iek1.k4xni2cv > div.j83agx80.cbu4d94t.buofh1pr > div.aov4n071 > div *> div> a" return document.querySelectorAll(activity_selector) } window.addEventListener('load', async () => { console.log("Injecting GUI") let parent = document.body function insertAfter(referenceNode, newNode) { referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling); } let divInputs = document.createElement('div') let spanMin = document.createElement('div'); spanMin.innerText = "From:(Blank=First)", divInputs.appendChild(spanMin) let min = addInput(divInputs) min.value = GM_getValue("from", null) + 1 //one based let spanMax = document.createElement('div'); spanMax.innerText = "To:(Blank=No Limit)", divInputs.appendChild(spanMax) let max = addInput(divInputs) function openRangeButtonActionClosure(min_input_element, max_input_element) { return function openRangeButtonAction() { //The gui is 1 indexed and the functions are 0 indexed let from = min_input_element.value ? min_input_element.value - 1 : 0 let to = max_input_element.value ? max_input_element.value - 1 : Infinity console.log("Processing range [from:", from, "to:", to, ")") openRange(from, to) } } async function openButtonAction() { openRange(0, Infinity) } let divButtons = document.createElement('div') addButton('Open Range', openRangeButtonActionClosure(min, max), divButtons) addButton('Open All', openButtonAction, divButtons) let div = document.createElement('div') let cssObj = { position: 'fixed', display: "block", 'z-index': 3, background: "#ffffff", border: "3px solid red" } Object.keys(cssObj).forEach(key => div.style[key] = cssObj[key]) div.appendChild(divButtons) div.appendChild(divInputs) parent.insertBefore(div, parent.childNodes[0]) }) function addInput(parentElement = document.body, cssObj) { cssObj = cssObj || { position: 'relative', 'z-index': 3 } let input = document.createElement('input'), btnStyle = input.style parentElement.appendChild(input) input.type = "number" Object.keys(cssObj).forEach(key => btnStyle[key] = cssObj[key]) return input } function addButton(text, onclick, parentElement = document.body, cssObj) { cssObj = cssObj || { position: 'relative', 'z-index': 3 } let button = document.createElement('button'), btnStyle = button.style parentElement.appendChild(button) button.innerHTML = text button.onclick = onclick Object.keys(cssObj).forEach(key => btnStyle[key] = cssObj[key]) return button } async function openRange(from, to) { //zero indexed [0from,to) async function handleRange(from, to) { let items = Array.from(get_items()) let rangeItems = items.slice(from, to) //reseting from value to valid value per iteration GM_setValue("from", from) const only_me_lock_icon = "https://static.xx.fbcdn.net/rsrc.php/v3/yD/r/JSmL99pVrUz.png" for (const item of rangeItems) { console.log("Processing element:", item) let audience = item.querySelector("*>img") if (audience && audience.src !== only_me_lock_icon) { await new Promise(async (resolve, reject) => { let tab = await GM.openInTab(item.href, false) tab.onclose = () => { resolve() } }) } GM_setValue("from", GM_getValue("from", 0) + 1) } return items.length } async function scrollRange(from, max_failures = 30) { //zero indexed [0from,to) let failed = 0; let prevscrollTop = null; while (from > get_items().length - 1) { //from is both an index and is inclusive! let scrolling_container_selector = "div > div:nth-child(1) > div.rq0escxv.l9j0dhe7.du4w35lb > div.rq0escxv.l9j0dhe7.du4w35lb > div > div > div.j83agx80.cbu4d94t.d6urw2fd.dp1hu0rb.l9j0dhe7.du4w35lb > div.rq0escxv.l9j0dhe7.du4w35lb.j83agx80.pfnyh3mw.jifvfom9.gs1a9yip.owycx6da.btwxx1t3.buofh1pr.dp1hu0rb.ka73uehy > div.rq0escxv.l9j0dhe7.tkr6xdv7.j83agx80.cbu4d94t.pfnyh3mw.d2edcug0.hpfvmrgz.dp1hu0rb.rek2kq2y.o36gj0jk > div > div.q5bimw55.rpm2j7zs.k7i0oixp.gvuykj2m.j83agx80.cbu4d94t.ni8dbmo4.eg9m0zos.l9j0dhe7.du4w35lb.ofs802cu.pohlnb88.dkue75c7.mb9wzai9.d8ncny3e.buofh1pr.g5gj957u.tgvbjcpo.l56l04vs.r57mb794.kh7kg01d.c3g1iek1.k4xni2cv" let scrolling_container = document.querySelector(scrolling_container_selector) //are we at the bottom? if (prevscrollTop === scrolling_container.scrollTop) { failed++; //yes we are and for too long, something is either wrong or we're done. if (failed > max_failures) throw "Failure Scrolling Down, is that everything?" } prevscrollTop = scrolling_container.scrollTop scrolling_container.scrollTop = scrolling_container.scrollHeight await delayPromise(1000) } } while (from < to) { await scrollRange(from) from = await handleRange(from, to) } } }()) } //ignore else if (document.URL.match("https://www.facebook.com/permalink.php.*|https://www.facebook.com/groups/.*")) { close() } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址