oneClickDeleteInstagramPost 一鍵刪除 Instagram 帖子

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

  1. // ==UserScript==
  2. // @name oneClickDeleteInstagramPost
  3. // @name:en oneClickDeleteInstagramPost
  4. // @name:ja oneClickDeleteInstagramPost ワンクリックで削除 Post
  5. // @name:zh-CN oneClickDeleteInstagramPost 一键删除 Instagram 帖子
  6. // @name:zh-TW oneClickDeleteInstagramPost 一鍵刪除 Instagram 帖子
  7. // @namespace https://github.com/catscarlet/oneClickDeleteInstagramPost
  8. // @description Add [Delete] button on the post in Personal Page on Instagram. Directly delete post without confirm.
  9. // @description:en Add a [Delete] button to the Personal Page on Instagram. Directly delete post without confirm.
  10. // @description:ja Instagramの個人ページの投稿に[削除]ボタンを追加してください。 確認なしで投稿を直接削除します。
  11. // @description:zh-CN 在 Instagram 的个人页面的图片上添加 [Delete] 按钮,点击直接删除图片,不再有确认提示框
  12. // @description:zh-TW 在 Instagram 的個人頁面的圖片上添加 [Delete] 按鈕,點擊直接刪除图片,不再有確認提示框
  13. // @version 1.1.0
  14. // @author catscarlet
  15. // @license MIT License
  16. // @match *://www.instagram.com/*
  17. // @require https://cdn.jsdelivr.net/npm/bignumber.js@2.4.0/bignumber.min.js
  18. // @run-at document-end
  19. // @grant none
  20. // ==/UserScript==
  21.  
  22. (function() {
  23. 'use strict';
  24.  
  25. let safe_lock = 1; //Set this to 0 to unlock the 'Delete this' button.
  26. let show_alt = 0; //Hide alt by default. Set this to 1 to show alt of images.
  27.  
  28. const InstagramConvert = {
  29. charset: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_',
  30. decode: url => {
  31. let result = BigInt(0);
  32. let power = BigInt(1);
  33.  
  34. for (let i = url.length - 1; i >= 0; i--) {
  35. const char = url[i];
  36. const index = InstagramConvert.charset.indexOf(char);
  37. result += BigInt(index) * power;
  38. power *= BigInt(64);
  39. }
  40. return result.toString();
  41. },
  42. };
  43.  
  44. let article = document.getElementsByTagName('article');
  45. let old_path = '';
  46. let new_path = '';
  47. let temp_lock = 0;
  48.  
  49. historyPushStateMonitor(window.history);
  50. historyOnpushstate();
  51.  
  52. history.onpushstate = function(e) {
  53. goPendingUrl();
  54. };
  55.  
  56. window.onpopstate = function(event) {
  57. goPendingUrl();
  58. };
  59.  
  60. function historyPushStateMonitor(history) {
  61. let pushState = history.pushState;
  62. history.pushState = function(state) {
  63. old_path = location.pathname.toString();
  64.  
  65. if (typeof history.onpushstate == 'function') {
  66. history.onpushstate({state: state});
  67. }
  68.  
  69. return pushState.apply(history, arguments);
  70. };
  71. }
  72.  
  73. function goPendingUrl() {
  74. new_path = location.pathname.toString();
  75.  
  76. if (old_path == new_path) {
  77. setTimeout(goPendingUrl, 1000);
  78. } else {
  79. historyOnpushstate();
  80. }
  81. }
  82.  
  83. function historyOnpushstate() {
  84. pending();
  85. }
  86.  
  87. function pending() {
  88. if (!article.length || !article[0].children[0].childElementCount || !article[0].children[0].children[0].childElementCount) {
  89. setTimeout(pending, 500);
  90. } else {
  91. ob();
  92. getPost();
  93. }
  94. }
  95.  
  96. function ob() {
  97. let articles = document.getElementsByTagName('article')[0].children[0].children[0];
  98.  
  99. let observerOptions = {
  100. childList: true,
  101. attributes: false,
  102. subtree: true,
  103. };
  104.  
  105. let observer = new MutationObserver(getPost);
  106.  
  107. observer.observe(articles, observerOptions);
  108. }
  109.  
  110. function getPost() {
  111. let articles = document.getElementsByTagName('article')[0].children[0].children[0];
  112. let own_it = pageOwnerCheck();
  113.  
  114. for (let articlesline of articles.children) {
  115. for (let post of articlesline.children) {
  116. let link = post.children[0];
  117. if (!link) {
  118. return false;
  119. }
  120. if (link.hasAttribute('alte')) {
  121. continue;
  122. }
  123.  
  124. let url = link.href;
  125. let urlSegment = GetUrlSegmentByUrl(url);
  126. if (!urlSegment) {
  127. continue;
  128. }
  129. let block = link.children[0];
  130. let img = block.children[0].children[0];
  131. let alt = img.alt;
  132.  
  133. let btn_div = document.createElement('div');
  134. btn_div.style.height = '2rem';
  135. let media_id = getMediaIdByUrlSegment(urlSegment);
  136.  
  137. let btn = document.createElement('button');
  138. btn.innerHTML = 'delete this';
  139. btn.style.backgroundColor = 'darksalmon';
  140. btn.onclick = function() {
  141. deleteByMediaId(media_id, btn, post);
  142. };
  143.  
  144. post.classList.add('oneClickDeleteInstagramPost_post');
  145.  
  146. btn_div.className = 'btn_div';
  147.  
  148. if (own_it) {
  149. if (safe_lock) {
  150. btn.disabled = true;
  151. 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.';
  152. }
  153. btn_div.appendChild(btn);
  154. post.appendChild(btn_div);
  155. }
  156.  
  157. let alt_div = document.createElement('div');
  158. alt_div.className = 'alt_div';
  159. alt_div.style.height = '1rem';
  160. let alt_div_style = 'word-break: break-word;';
  161. if (!show_alt) {
  162. alt_div_style += 'display: none;';
  163. }
  164. alt_div.innerHTML = '<span style="' + alt_div_style + '">' + alt + '</span>';
  165. post.appendChild(alt_div);
  166.  
  167. let post_style = 'height: calc(' + post.offsetHeight + 'px - 3rem); margin-bottom: 3rem;';
  168. post.style = post_style;
  169.  
  170. link.setAttribute('alte', 1);
  171. }
  172. }
  173. };
  174.  
  175. function GetUrlSegmentByUrl(url) {
  176. let regexp = /https:\/\/www.instagram.com\/p\/(\S+)\/(\?taken-by=\S+)?/;
  177. let result = url.match(regexp);
  178. if (result) {
  179. return result[1];
  180. } else {
  181. return false;
  182. }
  183. }
  184.  
  185. function getMediaIdByUrlSegment(urlSegment) {
  186. let id = InstagramConvert.decode(urlSegment);
  187.  
  188. return id;
  189. }
  190.  
  191. function deleteByMediaId(media_id, btn, post) {
  192. btn.innerHTML = 'deleting';
  193. btn.style.backgroundColor = 'yellow';
  194. btn.onclick = false;
  195. btn.disabled = true;
  196.  
  197. let url = 'https://www.instagram.com/api/v1/web/create/' + media_id + '/delete/';
  198.  
  199. let xmlhttp = new XMLHttpRequest();
  200. xmlhttp.open('POST', url, true);
  201. xmlhttp.setRequestHeader('X-CSRFToken', window._sharedData.config.csrf_token);
  202. xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  203. xmlhttp.send(null);
  204.  
  205. xmlhttp.onreadystatechange = function() {
  206. if (xmlhttp.readyState == 4) {
  207. if (xmlhttp.status == 200) {
  208. let rst = JSON.parse(xmlhttp.response);
  209. if (rst.did_delete) {
  210. post.style.visibility = 'hidden';
  211. } else {
  212. btn.innerHTML = 'Failed';
  213. }
  214. } else {
  215. btn.innerHTML = 'Failed';
  216. }
  217. }
  218. };
  219. }
  220.  
  221. function pageOwnerCheck() {
  222. let not_own_it = 0;
  223. let match_regex = /https:\/\/www.instagram.com\/([^\/]+)\/$/;
  224. let href = location.href;
  225.  
  226. let array1 = match_regex.exec(href);
  227. if (array1 !== null) {
  228. if (array1[1] == 'explore') {
  229. not_own_it++;
  230. }
  231. }
  232.  
  233. if (document.getElementsByClassName('fx7hk').length && document.getElementsByClassName('fx7hk')[0].childElementCount == 2) {
  234. not_own_it += 2;
  235. }
  236.  
  237. return !not_own_it;
  238. };
  239. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址