您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Quickly know if you have ever received Private Messages or profile comments from specific users by opening the user's profile page or by hovering over the user image/name on any page on MAL.
// ==UserScript== // @name Have we ever talked before? - MAL // @namespace MALCuriosity // @version 13 // @description Quickly know if you have ever received Private Messages or profile comments from specific users by opening the user's profile page or by hovering over the user image/name on any page on MAL. // @author hacker09 // @match https://myanimelist.net/* // @icon https://t3.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&url=http://myanimelist.net&size=64 // @run-at document-end // @grant GM_setValue // @grant GM_getValue // @grant window.close // @grant GM_listValues // @grant GM.xmlHttpRequest // ==/UserScript== (async function() { 'use strict'; var newDocument, ProfileID; //Creates a new global variable var HoveredUserName = ''; //Creates a new global variable if (GM_getValue('ScriptUserName') === undefined) //If the variable ScriptUserName doesn't exist yet { //Starts the if condition GM_setValue('ScriptUserName', document.querySelector("a.header-profile-link").innerText); //Save the User Name to the variable ScriptUserName } //Finishes the if condition async function GetComments() //Creates a function to get the user id and Starts the function { //Starts the function if (location.href.split('/')[3] === 'profile' && location.href.split('/')[4] !== GM_getValue('ScriptUserName') && HoveredUserName === '') //If the opened page is a profile and if the profile username isn't of the account owner profile, and if the variable HoveredUserName is equal nothing { //Starts the if condition ProfileID = document.querySelector("input[name*=profileMemId]") !== null ? document.querySelector("input[name*=profileMemId]").value : document.querySelector(".mr0").href.match(/\d+/g)[0]; //Save the user id to the variable ProfileID } //Finishes the if condition else //If the opened page isn't a profile page { //Starts the else condition const response1 = await (await fetch('https://api.jikan.moe/v4/users/' + HoveredUserName)).json(); //Fetch ProfileID = response1.data.mal_id; //Saves the user ID to the variable ProfileID } //Finishes the else condition const response = await (await fetch('https://myanimelist.net/comtocom.php?id1=' + ProfileID + '&id2=' + GM_getValue("ScriptUserID"))).text(); //Fetch newDocument = new DOMParser().parseFromString(response, 'text/html'); //Parses the fetch response } //Finishes the async function document.querySelectorAll("a[href*='/profile/']").forEach(Element => Element.addEventListener("mouseover", async function() { //Get all the profile link elements and add an event listener to the link element if (this.title.match('comments') === null) //If the element doesn't have the word comments on its title attribute { //Starts the if condition HoveredUserName = this.href.split('/')[4]; //Save the hovered username to a variable this.title = "Hover again to see the updated comments and PMs message."; //Add the text "comments" to the username/image, so that even if the element is hovered again too fast the fetch request won't happen again await GetComments(); //Starts the function if (newDocument.body.innerText.search("No comments found") > -1) //If the text "No comments found" exists { //Starts the if condition this.title = "❌ There are no comments between you and this user!"; //Add a text to the username/image } //Finishes the if condition else //If the text "No comments found" doesn't exist { //Starts the else condition this.title = "✅ There are comments between you and this user!"; //Add a text to the username/image } //Finishes the else condition if (GM_listValues().includes(HoveredUserName)) //If the current HoveredUserName is on the user PMed list { //Starts the if condition this.title = this.title + "\n✅ There are PMs between you and this user!"; //Add a text to the username/image } //Finishes the if condition else //If the current HoveredUserName isn't on the user PMed list { //Starts the else condition this.title = this.title + "\n❌ There are no PMs between you and this user!"; //Add a text to the username/image } //Finishes the else condition } //Finishes the if condition })); //Finishes the forEach if (location.href === 'https://myanimelist.net/mymessages.php' || (GM_getValue('ScriptUserID') === undefined && location.href.split('/')[4] === GM_getValue('ScriptUserName'))) //If the opened profile username is the account owner profile and if the variable ScriptUserID doesn't exist yet or if the opened URL is = 'https://myanimelist.net/mymessages.php' { //Starts the if condition var array = []; //Creates a new global array var nextpagenum = 0; //Creates a new variable if (GM_getValue('ScriptUserID') === undefined && location.href.split('/')[4] === GM_getValue('ScriptUserName')) //If the opened profile username is the account owner profile and if the variable ScriptUserID doesn't exist yet { //Starts the if condition const response1 = await (await fetch('https://api.jikan.moe/v4/users/' + location.href.split('/')[4])).json(); //Fetch GM_setValue('ScriptUserID', response1.data.mal_id); //Save the user id to the variable ScriptUserID } //Finishes the if condition while (true) { //While the fetched page contains User Names const url = 'https://myanimelist.net/mymessages.php?go=&show=' + nextpagenum; //Creates a variable to fetch the PM pages var response = await (await fetch(url)).text(); //Fetches the PM pages and converts the fetched pages to text const newDocument = new DOMParser().parseFromString(response, 'text/html'); //Parses the fetch response nextpagenum += 20; //Increase the next page number by 20 if (location.href === 'https://myanimelist.net/mymessages.php') //If the opened URL is = 'https://myanimelist.net/mymessages.php' { //Starts the if condition var DisplayedTotalPMs = 999999999; //Creates a new variable to make the script fetch only the 1-page } //Finishes the if condition else //If the opened URL isn't = 'https://myanimelist.net/mymessages.php' { //Starts the else condition DisplayedTotalPMs = parseInt(newDocument.querySelector("div.di-ib").innerText.match(/\d+/g)[2]); //Creates a new variable } //Finishes the else condition for (const UserNames of newDocument.querySelectorAll("div.mym.mym_user")) { //For every single User Name that sent a PM to the user array.push(UserNames.innerText); //Get and save the all mal User Names that sent PMs to the script user } //Finishes the for condition if (DisplayedTotalPMs >= parseInt(newDocument.querySelector("div.di-ib").innerText.match(/\d+/g)[0])) { //If the fetched page displayed messages total number is greater or equal the User total inbox messages number array = [...new Set(array)]; //Remove the duplicated usernames of the array array = array.filter(d => !GM_listValues().includes(d)); //Remove the duplicated usernames of the array comparing the usernames that the array has and tampermonkey is missing array.forEach(name => GM_setValue(name, 'PMed MAL User Name')) //Get and save the current PMed MAL User Name if (location.href !== 'https://myanimelist.net/mymessages.php') //If the opened URL isn't = 'https://myanimelist.net/mymessages.php' { //Starts the if condition close(); //Close the current tab } //Finishes the if condition return; //Make the while condition false and stop fetching } //Finishes the if condition await new Promise(resolve => setTimeout(resolve, 600)); //Timeout to start the next fetch request } //Finishes the while condition } //Finishes the if condition if (location.href.match(/https:\/\/myanimelist\.net\/profile\/[^\/]+(\/)?$/) !== null && location.href.split('/')[4] !== GM_getValue('ScriptUserName')) //If the opened page is a profile page and the profile username isn't of the script user profile { //Starts the if condition const HasCommented = document.createElement("a"); //Creates an a element HasCommented.setAttribute("id", "HasCommented"); //Adds the id HasCommented to the a element HasCommented.setAttribute("style", "cursor: pointer; margin-right: 15%;"); //Set the CSS for the button await GetComments(); //Starts the function if (newDocument.body.innerText.search("No comments found") > -1) //If the text "No comments found" is found { //Starts the if condition HasCommented.innerHTML = "❌"; //Add the text ❌ to the button } //Finishes the if condition else //If the text "No comments found" isn't found { //Starts the else condition HasCommented.innerHTML = "✅"; //Add a text to the button HasCommented.onclick = function() { //Detects the mouse click on the '✅' button open(`https://myanimelist.net/comtocom.php?id1=${ProfileID}&id2=${GM_getValue("ScriptUserID")}`, '_self'); //Open the user comments page on the same tab }; //Finishes the onclick event listener } //Finishes the else condition document.querySelector("#comment").parentElement.appendChild(HasCommented); //Shows the button setTimeout(function() { //Starts the setTimeout function document.querySelector("div.mt8 > input").parentElement.appendChild(document.querySelector("#HasCommented").cloneNode(true)); //Clone and append the HasCommented button document.querySelectorAll("#HasCommented")[1].onclick = function() { //Detects the mouse click on the second HasCommented button document.querySelector("#HasCommented").click(); //Click on the first HasCommented element }; //Finishes the onclick event listener }, 3000); //Finishes the setTimeout function const HasPMed = document.createElement("a"); //Creates an a element HasPMed.setAttribute("style", "cursor: pointer; margin-right: 47%;"); //Set the css for the button HasPMed.innerHTML = GM_listValues().includes(location.href.split('/')[4]) === true ? "✅" : "❌"; //If the current opened profile User Name is on the user PMed list Add a text to the button document.querySelector("#comment").parentElement.appendChild(HasPMed); //Shows the button } //Finishes the if condition })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址