Discord Message Logger

logs deleted discord messages

Vous devrez installer une extension telle que Tampermonkey, Greasemonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Userscripts pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension de gestionnaire de script utilisateur pour installer ce script.

(J'ai déjà un gestionnaire de scripts utilisateur, laissez-moi l'installer !)

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

(J'ai déjà un gestionnaire de style utilisateur, laissez-moi l'installer!)

// ==UserScript==
// @name        Discord Message Logger
// @namespace   -
// @match         https://discordapp.com/activ*
// @match         https://discordapp.com/channel*
// @match         https://discord.com/activ*
// @match         https://discord.com/channel*
// @match         https://discord.com/channels/*
// @include       https://discord.com/*
// @grant         none
// @version       1.0
// @author        Koyd
// @description   logs deleted discord messages
// @run-at        document-start
// @compatible    chrome
// @compatible    firefox
// @compatible    opera
// @compatible    edge
// @compatible    safari
// @license       MIT
// ==/UserScript==

var allObservers = [];
var currentParent = null;

function disconnectAllObservers() {
    allObservers.forEach(function(observer) {
        observer.disconnect();
    });
    // Clear the array after disconnecting all observers
    allObservers = [];
}


function formatLoggedNode(node) {
    var text = "";

    var mediaContentNode = node.querySelector('.container_dbadf5');

    if (mediaContentNode) {
        // Convert all of it into plain text
        var mediaContentText = mediaContentNode.innerHTML;

        // Use regex to find links like 'https://cdn.discordapp.com/attachments*'
        var linkRegex = /https:\/\/cdn\.discordapp\.com\/attachments\/[^'"\s]*/g;
        var matches = mediaContentText.match(linkRegex);

        // Append the links to the text variable
        if (matches) {
            text += matches.join("\n");
        }

        // Delete the mediaContentNode from the main node
        mediaContentNode.remove();
    }

    var messageContentNode = node.querySelector('.contents_f41bb2')
    var textContentNode = messageContentNode.querySelector('.markup_a7e664.messageContent__21e69');
    textContentNode.style.color = 'red';

    var spanElement = textContentNode.querySelector('span');

    if (spanElement) {
        textContentNode.querySelector('span').innerHTML += "\n" + text;
    } else {
        // If span doesn't exist, create one and append text
        textContentNode.innerHTML = '<span>' + text + '</span>' + textContentNode.innerHTML;
    }

    return node;
};


function setupMutationObserver(parent) {
    var observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            if (mutation.removedNodes.length > 0) {
                Array.from(mutation.removedNodes).forEach(function(node) {
                    if (node.classList && node.classList.contains('messageListItem__6a4fb')) {
                        // Check if the removed node has the specified class
                        var messageContentNode = node.querySelector('.contents_f41bb2')

                        var subTextNode = messageContentNode.querySelector('.markup_a7e664.messageContent__21e69');
                        
                         // Check if "isSending__6e109" class doesn't exist in the subnode
                        if (subTextNode && subTextNode.classList.contains('isSending__6e109')) {
                            return;
                        }

                        // Get the deleted message ID
                        var deletedIdMatch = node.id.match(/chat-messages-\d+-(\d+)/);
                        var deletedMessageId = deletedIdMatch ? parseInt(deletedIdMatch[1]) : null;

                        // Find the smallest index whose ID is greater than the deleted one
                        var minIndex = Array.from(parent.children).reduce(function(minIndex, child) {
                            var childIdMatch = child.id.match(/chat-messages-\d+-(\d+)/);
                            var childMessageId = childIdMatch ? parseInt(childIdMatch[1]) : null;

                            if (!isNaN(childMessageId) && childMessageId > deletedMessageId) {
                                return Math.min(minIndex, Array.from(parent.children).indexOf(child));
                            }

                            return minIndex;
                        }, Number.MAX_SAFE_INTEGER);

                        // Modify the node
                        node = formatLoggedNode(node);

                        // Append the modified node back to the parent at the calculated index
                        if (minIndex < Number.MAX_SAFE_INTEGER) {
                            parent.insertBefore(node, parent.children[minIndex]);
                        } else {
                            parent.insertBefore(node, parent.children[parent.children.length - 1]);
                        }
                    }
                });
            }
        });

      allObservers.push(observer)
    });


    // Configuration of the observer:
    var config = { childList: true };

    // Pass in the target node, as well as the observer options
    observer.observe(parent, config);
}

setInterval(function () {
    // Check if the URL is in the form https://discord.com/channels*
    if (!/^https:\/\/discord\.com\/channels/.test(window.location.href)) {
        // If not, disconnect observers and return
        disconnectAllObservers();
        currentParent = null;
        return;
    }

    var parent = document.querySelector('[data-list-id="chat-messages"]');

    if (!parent) {
        currentParent = null; // Set currentParent to null if the parent doesn't exist
        return;
    }

    if (parent !== currentParent) {
        // Disconnect observers only if the parent node has changed
        disconnectAllObservers();
        setupMutationObserver(parent);
        currentParent = parent; // Update the current parent
    }
}, 1000); // Check every 1000 milliseconds (1 second)