Scan messages for donations and mark posts
当前为
// ==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 });
})();