oneClickDeleteInstagramPost 一鍵刪除 Instagram 帖子

在 Instagram 的個人頁面的圖片上添加 [Delete] 按鈕,點擊直接刪除图片,不再有確認提示框

目前為 2025-04-18 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name                oneClickDeleteInstagramPost
// @name:en             oneClickDeleteInstagramPost
// @name:ja             oneClickDeleteInstagramPost ワンクリックで削除 Post
// @name:zh-CN          oneClickDeleteInstagramPost 一键删除 Instagram 帖子
// @name:zh-TW          oneClickDeleteInstagramPost 一鍵刪除 Instagram 帖子
// @namespace           https://github.com/catscarlet/oneClickDeleteInstagramPost
// @description         Add [Delete] button on the post in Personal Page on Instagram. Directly delete post without confirm.
// @description:en      Add a [Delete] button to the Personal Page on Instagram. Directly delete post without confirm.
// @description:ja      Instagramの個人ページの投稿に[削除]ボタンを追加してください。 確認なしで投稿を直接削除します。
// @description:zh-CN   在 Instagram 的个人页面的图片上添加 [Delete] 按钮,点击直接删除图片,不再有确认提示框
// @description:zh-TW   在 Instagram 的個人頁面的圖片上添加 [Delete] 按鈕,點擊直接刪除图片,不再有確認提示框
// @version             1.1.1
// @author              catscarlet
// @license             MIT License
// @match               *://www.instagram.com/*
// @require             https://cdn.jsdelivr.net/npm/[email protected]/bignumber.min.js
// @run-at              document-end
// @grant               none
// ==/UserScript==

(function() {
    'use strict';

    let safe_lock = 1; //Set this to 0 to unlock the 'Delete this' button.
    let show_alt = 0; //Hide alt by default. Set this to 1 to show alt of images.

    const InstagramConvert = {
        charset: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_',
        decode: url => {
            let result = BigInt(0);
            let power = BigInt(1);

            for (let i = url.length - 1; i >= 0; i--) {
                const char = url[i];
                const index = InstagramConvert.charset.indexOf(char);
                result += BigInt(index) * power;
                power *= BigInt(64);
            }
            return result.toString();
        },
    };

    let old_path = '';
    let new_path = '';
    let temp_lock = 0;

    historyPushStateMonitor(window.history);
    historyOnpushstate();

    history.onpushstate = function(e) {
        goPendingUrl();
    };

    window.onpopstate = function(event) {
        goPendingUrl();
    };

    function historyPushStateMonitor(history) {
        let pushState = history.pushState;
        history.pushState = function(state) {
            old_path = location.pathname.toString();

            if (typeof history.onpushstate == 'function') {
                history.onpushstate({state: state});
            }

            return pushState.apply(history, arguments);
        };
    }

    function goPendingUrl() {
        new_path = location.pathname.toString();

        if (old_path == new_path) {
            setTimeout(goPendingUrl, 1000);
        } else {
            historyOnpushstate();
        }
    }

    function historyOnpushstate() {
        pending();
    }

    function pending() {
        let article = document.querySelectorAll('.xg7h5cd.x1n2onr6');
        if (!article.length) {
            setTimeout(pending, 500);
        } else {
            ob();
            getPost();
        }
    }

    function ob() {
        let articles = document.querySelector('.xg7h5cd.x1n2onr6').children[0].children[0];

        let observerOptions = {
            childList: true,
            attributes: false,
            subtree: true,
        };

        let observer = new MutationObserver(getPost);

        observer.observe(articles, observerOptions);
    }

    function getPost() {
        let articles = document.querySelector('.xg7h5cd.x1n2onr6').children[0].children[0];
        let own_it = pageOwnerCheck();

        for (let articlesline of articles.children) {
            for (let post of articlesline.children) {
                let link = post.children[0];
                if (!link) {
                    return false;
                }
                if (link.hasAttribute('alte')) {
                    continue;
                }

                let url = link.href;
                let urlSegment = GetUrlSegmentByUrl(url);
                if (!urlSegment) {
                    continue;
                }
                let block = link.children[0];
                let img = block.children[0].children[0];
                let alt = img.alt;

                let btn_div = document.createElement('div');
                btn_div.style.height  = '2rem';
                let media_id = getMediaIdByUrlSegment(urlSegment);

                let btn = document.createElement('button');
                btn.innerHTML = 'delete this: ' + media_id;
                btn.style.backgroundColor  = 'darksalmon';
                btn.onclick = function() {
                    deleteByMediaId(media_id, btn, post);
                };

                post.classList.add('oneClickDeleteInstagramPost_post');

                btn_div.className = 'btn_div';

                if (own_it) {
                    if (safe_lock) {
                        btn.disabled = true;
                        btn.title = 'Safe_lock is ON! You need to edit the script and change the "safe_lock" to 0 in order to delete your post without confirm.';
                    }
                    btn_div.appendChild(btn);
                    post.appendChild(btn_div);
                }

                let alt_div = document.createElement('div');
                alt_div.className = 'alt_div';
                alt_div.style.height  = '1rem';
                let alt_div_style = 'word-break: break-word;';
                if (!show_alt) {
                    alt_div_style += 'display: none;';
                }
                alt_div.innerHTML = '<span style="' + alt_div_style + '">' + alt + '</span>';
                post.appendChild(alt_div);

                let post_style = 'height: calc(' + post.offsetHeight + 'px - 3rem); margin-bottom: 3rem;';
                post.style = post_style;

                link.setAttribute('alte', 1);
            }
        }
    };

    function GetUrlSegmentByUrl(url) {
        let regexp = /https:\/\/www.instagram.com\/(\S+)\/p\/(\?taken-by=\S+)?/;
        let result = url.match(regexp);
        if (result) {
            return result[1];
        } else {
            return false;
        }
    }

    function getMediaIdByUrlSegment(urlSegment) {
        let id = InstagramConvert.decode(urlSegment);

        return id;
    }

    function deleteByMediaId(media_id, btn, post) {
        btn.innerHTML = 'deleting';
        btn.style.backgroundColor  = 'yellow';
        btn.onclick = false;
        btn.disabled = true;

        let url = 'https://www.instagram.com/api/v1/web/create/' + media_id + '/delete/';

        let xmlhttp = new XMLHttpRequest();
        xmlhttp.open('POST', url, true);
        xmlhttp.setRequestHeader('X-CSRFToken', window._sharedData.config.csrf_token);
        xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xmlhttp.send(null);

        xmlhttp.onreadystatechange = function() {
            if (xmlhttp.readyState == 4) {
                if (xmlhttp.status == 200) {
                    let rst = JSON.parse(xmlhttp.response);
                    if (rst.did_delete) {
                        post.style.visibility = 'hidden';
                    } else {
                        btn.innerHTML = 'Failed';
                    }
                } else {
                    btn.innerHTML = 'Failed';
                }
            }
        };
    }

    function pageOwnerCheck() {
        let not_own_it = 0;
        let match_regex = /https:\/\/www.instagram.com\/([^\/]+)\/$/;
        let href = location.href;

        let array1 = match_regex.exec(href);
        if (array1 !== null) {
            if (array1[1] == 'explore') {
                not_own_it++;
            }
        }

        if (document.getElementsByClassName('fx7hk').length && document.getElementsByClassName('fx7hk')[0].childElementCount == 2) {
            not_own_it += 2;
        }

        return !not_own_it;
    };
})();