Discord Fake Message Editor

Change the appearance of a Discord message locally with clickable links, styled pings, and images below text

  1. // ==UserScript==
  2. // @name Discord Fake Message Editor
  3. // @namespace http://tampermonkey.net/
  4. // @homepageURL https://discord.gg/gFNAH7WNZj
  5. // @version 1.0.0
  6. // @description Change the appearance of a Discord message locally with clickable links, styled pings, and images below text
  7. // @author Bacon But Pro
  8. // @match *://discord.com/channels/*
  9. // @icon https://cdn141.picsart.com/351217840073211.png
  10. // @license MIT
  11. // @grant none
  12. // ==/UserScript==
  13.  
  14. (function() {
  15. 'use strict';
  16.  
  17. let originalMessages = {};
  18. let boxVisible = true;
  19. let clickToCopyEnabled = false;
  20. let helpBox;
  21.  
  22. const ANIMATION_DURATION = 500;
  23.  
  24. function startLoading() {
  25. let loadingBox = document.createElement('div');
  26. loadingBox.id = 'loadingBox';
  27. loadingBox.style.position = 'fixed';
  28. loadingBox.style.top = '50%';
  29. loadingBox.style.left = '50%';
  30. loadingBox.style.transform = 'translate(-50%, -50%) translateY(-20px)';
  31. loadingBox.style.opacity = '0';
  32. loadingBox.style.background = 'linear-gradient(135deg, #7289da, #2c2f33)';
  33. loadingBox.style.color = 'white';
  34. loadingBox.style.padding = '30px';
  35. loadingBox.style.borderRadius = '10px';
  36. loadingBox.style.boxShadow = '0 4px 20px rgba(0, 0, 0, 0.3)';
  37. loadingBox.style.textAlign = 'center';
  38. loadingBox.style.zIndex = '9999';
  39. loadingBox.style.minWidth = '350px';
  40. loadingBox.style.fontFamily = `'Segoe UI', Tahoma, Geneva, Verdana, sans-serif`;
  41. loadingBox.style.transition = `opacity ${ANIMATION_DURATION}ms ease, transform ${ANIMATION_DURATION}ms ease`;
  42.  
  43. let loadingText = document.createElement('div');
  44. loadingText.innerText = 'Loading Userscript';
  45. loadingText.style.fontSize = '20px';
  46. loadingText.style.marginBottom = '20px';
  47. loadingBox.appendChild(loadingText);
  48.  
  49. let barContainer = document.createElement('div');
  50. barContainer.id = 'loadingBarContainer';
  51. barContainer.style.width = '100%';
  52. barContainer.style.height = '12px';
  53. barContainer.style.background = 'rgba(0, 0, 0, 0.2)';
  54. barContainer.style.borderRadius = '6px';
  55. barContainer.style.overflow = 'hidden';
  56. barContainer.style.marginTop = '10px';
  57. loadingBox.appendChild(barContainer);
  58.  
  59. let loadingBar = document.createElement('div');
  60. loadingBar.id = 'loadingBar';
  61. loadingBar.style.height = '100%';
  62. loadingBar.style.width = '100%';
  63. loadingBar.style.background = 'linear-gradient(90deg, #99aab5, #7289da)';
  64. loadingBar.style.transformOrigin = 'right';
  65. loadingBar.style.transition = 'transform 10s linear';
  66. barContainer.appendChild(loadingBar);
  67.  
  68. document.body.appendChild(loadingBox);
  69.  
  70. requestAnimationFrame(() => {
  71. loadingBox.style.opacity = '1';
  72. loadingBox.style.transform = 'translate(-50%, -50%) translateY(0)';
  73. });
  74.  
  75. requestAnimationFrame(() => {
  76. loadingBar.style.transform = 'scaleX(0)';
  77. });
  78.  
  79. setTimeout(() => {
  80. loadingBox.style.opacity = '0';
  81. loadingBox.style.transform = 'translate(-50%, -50%) translateY(20px)';
  82. setTimeout(() => {
  83. if (loadingBox.parentNode) {
  84. loadingBox.parentNode.removeChild(loadingBox);
  85. }
  86. createControlBox();
  87. }, ANIMATION_DURATION);
  88. }, 10000);
  89. }
  90.  
  91. function createControlBox() {
  92. let box = document.createElement("div");
  93. box.id = "fakeMessageBox";
  94. box.style.position = "fixed";
  95. box.style.bottom = "20px";
  96. box.style.right = "20px";
  97. box.style.background = "linear-gradient(135deg, #2c2f33, #7289da)";
  98. box.style.color = "white";
  99. box.style.padding = "20px";
  100. box.style.borderRadius = "10px";
  101. box.style.boxShadow = "0 4px 20px rgba(0,0,0,0.3)";
  102. box.style.zIndex = "9999";
  103. box.style.width = "280px";
  104. box.style.display = "flex";
  105. box.style.flexDirection = "column";
  106. box.style.gap = "10px";
  107. box.style.fontFamily = `'Segoe UI', Tahoma, Geneva, Verdana, sans-serif`;
  108. box.style.opacity = "0";
  109. box.style.transform = "translateX(50px)";
  110. box.style.transition = `opacity ${ANIMATION_DURATION}ms ease, transform ${ANIMATION_DURATION}ms ease`;
  111.  
  112. box.innerHTML = `
  113. <div>
  114. <label style="display: block; margin-bottom: 4px;">Message ID:</label>
  115. <input type="text" id="fakeMsgId" style="width: 100%; padding: 6px; border-radius: 4px; border: none; box-sizing: border-box;">
  116. </div>
  117.  
  118. <div style="display: flex; flex-direction: column; gap: 5px;">
  119. <button id="clearMsgId" style="padding: 6px; border: none; border-radius: 4px; background: #99aab5; color: white; cursor: pointer;">Clear</button>
  120. <button id="toggleCopy" style="padding: 6px; border: none; border-radius: 4px; background: #99aab5; color: white; cursor: pointer;">Copy</button>
  121. </div>
  122.  
  123. <div>
  124. <label style="display: block; margin-bottom: 4px;">New Message:</label>
  125. <textarea id="fakeMsgHtml" style="width: 100%; padding: 6px; border-radius: 4px; border: none; box-sizing: border-box; resize: vertical;" rows="3"></textarea>
  126. </div>
  127.  
  128. <div>
  129. <label style="display: block; margin-bottom: 4px;">Image URL (optional):</label>
  130. <input type="text" id="fakeMsgImage" style="width: 100%; padding: 6px; border-radius: 4px; border: none; box-sizing: border-box;">
  131. </div>
  132.  
  133. <div style="display: flex; gap: 5px;">
  134. <button id="applyFakeChange" style="flex: 1; padding: 6px; border: none; border-radius: 4px; background: #7289da; color: white; cursor: pointer;">Apply</button>
  135. <button id="resetFakeChange" style="flex: 1; padding: 6px; border: none; border-radius: 4px; background: #7289da; color: white; cursor: pointer;">Reset</button>
  136. <button id="hideBox" style="flex: 1; padding: 6px; border: none; border-radius: 4px; background: #7289da; color: white; cursor: pointer;">Hide</button>
  137. <button id="helpBtn" style="flex: 1; padding: 6px; border: none; border-radius: 4px; background: #7289da; color: white; cursor: pointer;">Help</button>
  138. </div>
  139.  
  140. <div id="notification" style="display: none; color: lime; text-align: center;">Message updated!</div>
  141. <small style="display: block; text-align: center; margin-top: 5px;">By Bacon But Pro</small>
  142. `;
  143. document.body.appendChild(box);
  144.  
  145. requestAnimationFrame(() => {
  146. box.style.opacity = "1";
  147. box.style.transform = "translateX(0)";
  148. });
  149.  
  150. let toggleButton = document.createElement("button");
  151. toggleButton.id = "toggleBoxButton";
  152. toggleButton.innerText = "Show";
  153. toggleButton.style.position = "fixed";
  154. toggleButton.style.bottom = "20px";
  155. toggleButton.style.right = "20px";
  156. toggleButton.style.background = "#7289da";
  157. toggleButton.style.color = "white";
  158. toggleButton.style.padding = "8px 12px";
  159. toggleButton.style.border = "none";
  160. toggleButton.style.borderRadius = "4px";
  161. toggleButton.style.boxShadow = "0 2px 10px rgba(0,0,0,0.2)";
  162. toggleButton.style.zIndex = "9998";
  163. toggleButton.style.display = "none";
  164. toggleButton.style.cursor = "pointer";
  165. document.body.appendChild(toggleButton);
  166.  
  167. helpBox = createHelpBox();
  168.  
  169. document.getElementById("applyFakeChange").addEventListener("click", () => {
  170. let msgId = document.getElementById("fakeMsgId").value.trim();
  171. let newHtml = document.getElementById("fakeMsgHtml").value;
  172. let imageUrl = document.getElementById("fakeMsgImage").value.trim();
  173. if (msgId && (newHtml !== "" || imageUrl !== "")) {
  174. fakeEditMessage(msgId, newHtml, imageUrl);
  175. showNotification("Message updated!");
  176. }
  177. });
  178.  
  179. document.getElementById("resetFakeChange").addEventListener("click", () => {
  180. let msgId = document.getElementById("fakeMsgId").value.trim();
  181. if (msgId) {
  182. resetMessage(msgId);
  183. }
  184. });
  185.  
  186. document.getElementById("toggleCopy").addEventListener("click", () => {
  187. clickToCopyEnabled = !clickToCopyEnabled;
  188. alert(`Copy Mode: ${clickToCopyEnabled ? 'ON' : 'OFF'}`);
  189. });
  190.  
  191. document.getElementById("hideBox").addEventListener("click", () => {
  192. toggleControlBox();
  193. });
  194.  
  195. document.getElementById("clearMsgId").addEventListener("click", () => {
  196. document.getElementById("fakeMsgId").value = "";
  197. });
  198.  
  199. document.getElementById("helpBtn").addEventListener("click", () => {
  200. if (helpBox.style.display === "none") {
  201. helpBox.style.display = "block";
  202. } else {
  203. helpBox.style.display = "none";
  204. }
  205. });
  206.  
  207. toggleButton.addEventListener("click", () => {
  208. toggleControlBox();
  209. });
  210.  
  211. document.addEventListener("keydown", (event) => {
  212. if (event.key === "F2") {
  213. toggleControlBox();
  214. }
  215. });
  216.  
  217. document.addEventListener("click", (event) => {
  218. if (!clickToCopyEnabled) return;
  219. let messageElement = event.target.closest("[id^='message-content-']");
  220. if (messageElement) {
  221. let messageId = messageElement.id.replace("message-content-", "");
  222. document.getElementById("fakeMsgId").value = messageId;
  223. showNotification("Message ID copied!");
  224. }
  225. });
  226. }
  227.  
  228. function createHelpBox() {
  229. let box = document.createElement("div");
  230. box.id = "fakeMessageHelpBox";
  231. box.style.position = "fixed";
  232. box.style.bottom = "20px";
  233. box.style.right = "320px";
  234. box.style.background = "#2c2f33";
  235. box.style.color = "white";
  236. box.style.padding = "15px";
  237. box.style.borderRadius = "10px";
  238. box.style.boxShadow = "0 4px 20px rgba(0,0,0,0.3)";
  239. box.style.zIndex = "9999";
  240. box.style.width = "250px";
  241. box.style.fontFamily = `'Segoe UI', Tahoma, Geneva, Verdana, sans-serif`;
  242. box.style.display = "none";
  243.  
  244. box.innerHTML = `
  245. <h3 style="margin-top: 0;">Help</h3>
  246. <p style="font-size: 14px; line-height: 1.4;">
  247. This script lets you locally modify the appearance of a Discord message.<br><br>
  248. <strong>Message ID</strong>: Enable "Copy" mode and click a message to grab its ID.<br>
  249. <strong>New Message</strong>: Enter your custom text, links, or mentions in the format
  250. <code>&lt;@123456789|DisplayName&gt;</code>.<br>
  251. <strong>Image URL</strong>: An optional link to an image below your custom text.
  252. </p>
  253. <p style="font-size: 14px; line-height: 1.4;">
  254. <strong>Example:</strong><br>
  255. <code>&lt;@123456789|User&gt; Check out https://google.com</code>
  256. </p>
  257. `;
  258.  
  259. document.body.appendChild(box);
  260. return box;
  261. }
  262.  
  263. function toggleControlBox() {
  264. let box = document.getElementById("fakeMessageBox");
  265. let toggleButton = document.getElementById("toggleBoxButton");
  266. if (!box) return;
  267.  
  268. if (boxVisible) {
  269. box.style.transition = `opacity ${ANIMATION_DURATION}ms ease, transform ${ANIMATION_DURATION}ms ease`;
  270. box.style.opacity = "0";
  271. box.style.transform = "translateX(50px)";
  272. setTimeout(() => {
  273. box.style.display = "none";
  274. toggleButton.style.display = "block";
  275. boxVisible = false;
  276. }, ANIMATION_DURATION);
  277. } else {
  278. box.style.display = "flex";
  279. box.style.opacity = "0";
  280. box.style.transform = "translateX(50px)";
  281. void box.offsetWidth;
  282. box.style.transition = `opacity ${ANIMATION_DURATION}ms ease, transform ${ANIMATION_DURATION}ms ease`;
  283. box.style.opacity = "1";
  284. box.style.transform = "translateX(0)";
  285. toggleButton.style.display = "none";
  286. boxVisible = true;
  287. }
  288. }
  289.  
  290. function fakeEditMessage(messageId, newHtml, imageUrl) {
  291. let messageElement = document.querySelector(`#message-content-${messageId}`);
  292. if (messageElement) {
  293. if (!originalMessages[messageId]) {
  294. originalMessages[messageId] = messageElement.innerHTML;
  295. }
  296. let processedHtml = processContent(newHtml);
  297. let finalContent = "";
  298. if (processedHtml) {
  299. finalContent = `<div>${processedHtml}</div>`;
  300. }
  301. if (imageUrl) {
  302. finalContent += `<div style="margin-top: 5px;"><img src="${imageUrl}" style="max-width: 200px; border-radius: 5px;"></div>`;
  303. }
  304. messageElement.innerHTML = finalContent;
  305. } else {
  306. alert("Message not found. Make sure it's visible on screen.");
  307. }
  308. }
  309.  
  310. function resetMessage(messageId) {
  311. let messageElement = document.querySelector(`#message-content-${messageId}`);
  312. if (messageElement && originalMessages[messageId]) {
  313. messageElement.innerHTML = originalMessages[messageId];
  314. delete originalMessages[messageId];
  315. } else {
  316. alert("Original message not stored or message not found.");
  317. }
  318. }
  319.  
  320. function processLinks(text) {
  321. if (!text) return "";
  322. return text.replace(/(https:\/\/[^\s]+)/g, function(match) {
  323. return `<a href="${match}" target="_blank" style="color: #00b0f4; text-decoration: none;">${match}</a>`;
  324. });
  325. }
  326.  
  327. function processMentions(text) {
  328. if (!text) return "";
  329. return text.replace(/<@([^>|]+)(?:\|([^>]+))?>/g, function(match, id, displayName) {
  330. if (!displayName) displayName = id;
  331. return `<span class="mention" style="color: #7289da; font-weight: bold;">@${displayName}</span>`;
  332. });
  333. }
  334.  
  335. function processContent(text) {
  336. return processMentions(processLinks(text));
  337. }
  338.  
  339. function showNotification(text) {
  340. let notif = document.getElementById("notification");
  341. notif.innerText = text;
  342. notif.style.display = "block";
  343. setTimeout(() => notif.style.display = "none", 2000);
  344. }
  345.  
  346. window.addEventListener("load", startLoading);
  347. })();