Boosty Message Scanner

Scan messages for donations and mark posts

目前为 2024-08-31 提交的版本。查看 最新版本

// ==UserScript==
// @name         Boosty Message Scanner
// @version      1.8
// @description  Scan messages for donations and mark posts
// @match        https://boosty.to/*
// @namespace http://tampermonkey.net/
// ==/UserScript==

(function() {
    'use strict';

    // Function to scan messages and save donation links with amounts
    function scanMessages() {
        const messageElements = document.querySelectorAll('[class*="DialogueMessageWrapper_message_"] [class*="DonationMessageInfo_root_"]');
        let existingDonations = JSON.parse(localStorage.getItem('donationData')) || {};
        const newDonations = {};

        messageElements.forEach(element => {
            const linkElement = element.querySelector('[class*="DonationMessageInfo_link_"]');
            const donationAmountElement = element.querySelector('.DonationMessageInfo_donationInfo_igBxK');

            if (linkElement && donationAmountElement) {
                const href = linkElement.href;
                const postId = href.split('/').pop().split('?')[0]; // Ensure no query parameters are included
                const amountMatch = donationAmountElement.innerText.match(/(\d+)\s*₽/);
                const amount = amountMatch ? parseInt(amountMatch[1], 10) : 0;

                if (!existingDonations[postId]) {
                    existingDonations[postId] = 0;
                }
                if (!newDonations[postId]) {
                    newDonations[postId] = 0;
                }

                existingDonations[postId] += amount;
                newDonations[postId] += amount;
            }
        });

        localStorage.setItem('donationData', JSON.stringify(existingDonations));

        showAlert(newDonations, existingDonations);
    }

    // Function to add the scan button
    function addScanButton() {
        const container = document.querySelector('[class*="Publisher_actionsContainer_"] [class*="Publisher_actionsLeft_"]');
        if (container && !document.querySelector('.scanMessagesButton')) {
            const scanButton = document.createElement('button');
            scanButton.innerText = 'Scan Messages';
            scanButton.className = 'scanMessagesButton';
            scanButton.style.marginLeft = '10px';
            scanButton.onclick = scanMessages;
            container.appendChild(scanButton);
        }
    }

    // Function to mark posts with donations
    function markPosts() {
        const donations = JSON.parse(localStorage.getItem('donationData')) || {};

        // Mark posts in BasePostHeader_root_
        const postsBase = document.querySelectorAll('[class*="BasePostHeader_root_"] [class*="CreatedAt_headerLink_"]');
        postsBase.forEach(post => {
            const href = post.href || post.getAttribute('href');
            const postId = href ? href.split('/').pop().split('?')[0] : null; // Ensure no query parameters are included
            if (postId && donations[postId]) {
                const postHeader = post.closest('[class*="BasePostHeader_root_"]');
                if (postHeader && !postHeader.querySelector('.markedPost')) {
                    const mark = document.createElement('span');
                    mark.innerText = `☻ ${donations[postId]} ₽ ☻`;
                    mark.className = 'markedPost';
                    postHeader.querySelector('[class*="BasePostHeader_headerLeftBlock_"]').appendChild(mark);
                }
            }
        });

        // Mark posts in PostHeaderWithAuthor_root_
        const postsAuthor = document.querySelectorAll('[class*="PostHeaderWithAuthor_root_"] [class*="CreatedAt_headerLink_"]');
        postsAuthor.forEach(post => {
            const href = post.href || post.getAttribute('href');
            const postId = href ? href.split('/').pop().split('?')[0] : null; // Ensure no query parameters are included
            if (postId && donations[postId]) {
                const postHeader = post.closest('[class*="PostHeaderWithAuthor_root_"]');
                if (postHeader && !postHeader.querySelector('.markedPost')) {
                    const mark = document.createElement('span');
                    mark.innerText = `☻ ${donations[postId]} ₽ ☻`;
                    mark.className = 'markedPost';
                    postHeader.querySelector('[class*="PostHeaderWithAuthor_headerLeftBlock_"]').appendChild(mark);
                }
            }
        });
    }

    // Function to show alert with buttons
    function showAlert(newDonations, existingDonations) {
        const alertDiv = document.createElement('div');
        alertDiv.className = 'customAlert';
        alertDiv.style.position = 'fixed';
        alertDiv.style.top = '50%';
        alertDiv.style.left = '50%';
        alertDiv.style.transform = 'translate(-50%, -50%)';
        alertDiv.style.backgroundColor = '#fff';
        alertDiv.style.padding = '20px';
        alertDiv.style.boxShadow = '0px 0px 10px rgba(0,0,0,0.5)';
        alertDiv.style.zIndex = '10000';

        const message = document.createElement('p');
        const newTotal = Object.keys(newDonations).length;
        const existingTotal = Object.keys(existingDonations).length;
        message.innerText = `Found ${newTotal} new donation links. Total: ${existingTotal}`;
        alertDiv.appendChild(message);

        const newLinksButton = document.createElement('button');
        newLinksButton.innerText = 'View New Donations';
        newLinksButton.onclick = () => {
            showNewDonations(newDonations);
        };
        alertDiv.appendChild(newLinksButton);

        const totalLinksButton = document.createElement('button');
        totalLinksButton.innerText = 'Edit Total Donations';
        totalLinksButton.onclick = () => {
            showTotalDonations(existingDonations);
        };
        alertDiv.appendChild(totalLinksButton);

        const okButton = document.createElement('button');
        okButton.innerText = 'OK';
        okButton.onclick = () => {
            document.body.removeChild(alertDiv);
        };
        alertDiv.appendChild(okButton);

        document.body.appendChild(alertDiv);
    }

    // Function to show new donations
    function showNewDonations(newDonations) {
        const newDonationsDiv = document.createElement('div');
        newDonationsDiv.className = 'customNewDonations';
        newDonationsDiv.style.position = 'fixed';
        newDonationsDiv.style.top = '50%';
        newDonationsDiv.style.left = '50%';
        newDonationsDiv.style.transform = 'translate(-50%, -50%)';
        newDonationsDiv.style.backgroundColor = '#fff';
        newDonationsDiv.style.padding = '20px';
        newDonationsDiv.style.boxShadow = '0px 0px 10px rgba(0,0,0,0.5)';
        newDonationsDiv.style.zIndex = '10000';
        newDonationsDiv.style.maxHeight = '80%';
        newDonationsDiv.style.overflowY = 'auto';

        const title = document.createElement('h3');
        title.innerText = 'New Donations';
        newDonationsDiv.appendChild(title);

        const list = document.createElement('ul');
        for (const [link, amount] of Object.entries(newDonations)) {
            const listItem = document.createElement('li');
            listItem.innerText = `Post ID: ${link}, Amount: ${amount} ₽`;
            list.appendChild(listItem);
        }
        newDonationsDiv.appendChild(list);

        const closeButton = document.createElement('button');
        closeButton.innerText = 'Close';
        closeButton.onclick = () => {
            document.body.removeChild(newDonationsDiv);
        };
        newDonationsDiv.appendChild(closeButton);

        document.body.appendChild(newDonationsDiv);
    }

    // Function to show and edit total donations
    function showTotalDonations(existingDonations) {
        const totalDonationsDiv = document.createElement('div');
        totalDonationsDiv.className = 'customTotalDonations';
        totalDonationsDiv.style.position = 'fixed';
        totalDonationsDiv.style.top = '50%';
        totalDonationsDiv.style.left = '50%';
        totalDonationsDiv.style.transform = 'translate(-50%, -50%)';
        totalDonationsDiv.style.backgroundColor = '#fff';
        totalDonationsDiv.style.padding = '20px';
        totalDonationsDiv.style.boxShadow = '0px 0px 10px rgba(0,0,0,0.5)';
        totalDonationsDiv.style.zIndex = '10000';
        totalDonationsDiv.style.maxHeight = '80%';
        totalDonationsDiv.style.overflowY = 'auto';

        const title = document.createElement('h3');
        title.innerText = 'Edit Total Donations';
        totalDonationsDiv.appendChild(title);

        const textArea = document.createElement('textarea');
        textArea.value = JSON.stringify(existingDonations, null, 2);
        textArea.style.width = '100%';
        textArea.style.height = '200px';
        totalDonationsDiv.appendChild(textArea);

        const saveButton = document.createElement('button');
        saveButton.innerText = 'Save';
        saveButton.onclick = () => {
            try {
                const newTotal = JSON.parse(textArea.value);
                if (typeof newTotal === 'object' && newTotal !== null) {
                    localStorage.setItem('donationData', JSON.stringify(newTotal));
                    alert('Total Donations updated successfully.');
                } else {
                    alert('Invalid format. Please enter a valid JSON object.');
                }
            } catch (e) {
                alert('Invalid format. Please enter a valid JSON object.');
            }
        };
        totalDonationsDiv.appendChild(saveButton);

        const closeButton = document.createElement('button');
        closeButton.innerText = 'Close';
        closeButton.onclick = () => {
            document.body.removeChild(totalDonationsDiv);
        };
        totalDonationsDiv.appendChild(closeButton);

        document.body.appendChild(totalDonationsDiv);
    }

    // Initialize script
    function init() {
        if (location.pathname.includes('/app/messages')) {
            addScanButton();
        }
        markPosts();
    }

    // Run script on page load and on AJAX content load
    document.addEventListener('DOMContentLoaded', init);
    const observer = new MutationObserver(init);
    observer.observe(document.body, { childList: true, subtree: true });

})();

QingJ © 2025

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