Have we ever talked before? - MAL

This script allows you to quickly know if you have already received Private/Direct Messages or profile comments from specific users simply by opening the user's profile page or by hovering on the user's image/User Name on any page on MAL.

目前为 2021-03-19 提交的版本。查看 最新版本

// ==UserScript==
// @name         Have we ever talked before? - MAL
// @namespace    MALCuriosity
// @version      0.3
// @description  This script allows you to quickly know if you have already received Private/Direct Messages or profile comments from specific users simply by opening the user's profile page or by hovering on the user's image/User Name on any page on MAL.
// @author       hacker09
// @match        https://myanimelist.net/*
// @icon         https://www.google.com/s2/favicons?domain=myanimelist.net
// @run-at       document-end
// @grant        GM_listValues
// @grant        window.close
// @grant        GM_setValue
// @grant        GM_getValue
// ==/UserScript==

(function() {
  'use strict';
  var newDocument, ProfileID; //Creates a new global variable
  var HoveredUserName = ''; //Creates a new global variable
  var ScriptUserName = GM_getValue('ScriptUserName'); //Saves the User Name to the variable ScriptUserName

  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); //Saves 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] !== ScriptUserName && HoveredUserName === '') //If the opened page is some profile and if the profile username is not of the account owner profile, and if the variable HoveredUserName is equal nothing
    { //Starts the if condition

      if (document.getElementsByName('profileMemId').length !== 0) //If the element that has the user id exists
      { //Starts the if condition
        ProfileID = document.getElementsByName('profileMemId')[0].value; //Saves the user id to the variable ProfileID
      } //Finishes the if condition
      else //If the element that has the user id DOESN'T exist
      { //Starts the else condition
        ProfileID = document.querySelector("a.header-right.mt4.mr0").href.split('id=')[1]; //Saves the user id to the variable ProfileID
      } //Finishes the else condition

    } //Finishes the if condition
    else //If the opened page is NOT a profile page
    { //Starts the else condition
      const response1 = await (await fetch('https://api.jikan.moe/v3/user/' + HoveredUserName + '/profile')).json(); //Fetch
      ProfileID = response1.user_id; //Saves the user id to the variable ProfileID
    } //Finishes the else condition

    const response = await fetch('https://myanimelist.net/comtocom.php?id1=' + ProfileID + '&id2=' + GM_getValue("ScriptUserID")); //Fetch
    const html = await response.text(); //Gets the fetch response
    newDocument = new DOMParser().parseFromString(html, 'text/html'); //Parses the fetch response
  } //Finishes the async function

  Array.from(document.querySelectorAll("a[href*='/profile/']")).forEach(Element => Element.onmouseover = async function() { //Get all the a profile link elements and add an advent listener to the link element
    if (this.href.split('/')[4].match(this.innerText) !== null) //If the hovered profile url username is the same as the link element text username
    { //Starts the if condition

      HoveredUserName = this.href.split('/')[4]; //Save the hovered username to a variable
      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
        this.title = "NO! There's no comments between you and this user!"; //Add the text "There's no comments between you and this user" to the username/image
      } //Finishes the if condition
      else //If the text "No comments found" is NOT found
      { //Starts the else condition
        this.title = "YES! There are comments between you and this user!"; //Add the text "YES! There are comments between you and this user!" to the username/image
      } //Finishes the else condition

      if (GM_listValues().includes(HoveredUserName)) //If the actual HoveredUserName is on the user PMed list
      { //Starts the if condition
        this.title = this.title + "\nYES! There are PMs between you and this user!"; //Add the text "YES! There are PMs between you and this user!" to the username/image
      } //Finishes the if condition
      else //If the actual HoveredUserName is NOT on the user PMed list
      { //Starts the else condition
        this.title = this.title + "\nNO! There's no PMs between you and this user!"; //Add the text "There's no PMs between you and this user" 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] === 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
    (async () => { //Creates an async function
      if (GM_getValue('ScriptUserID') === undefined && location.href.split('/')[4] === 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/v3/user/' + location.href.split('/')[4] + '/profile')).json(); //Fetch
        GM_setValue('ScriptUserID', response1.user_id); //saves 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 is NOT = '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

          for (var i = array.length; i--;) { //For every single PMed MAL User Name
            GM_setValue(array[i], 'PMed MAL User Name'); //Get and save the actual PMed MAL User Name
          } //Finishes the for condition

          if (location.href !== 'https://myanimelist.net/mymessages.php') //If the opened url is NOT = 'https://myanimelist.net/mymessages.php'
          { //Starts the if condition
            window.top.close(); //Close the actual 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 async function

  } //Finishes the if condition

  if (location.href.split('/')[3] === 'profile' && location.href.split('/')[4] !== ScriptUserName) //If the opened page is some profile and if the profile username is not of the account owner profile
  { //Starts the if condition
    (async () => { //Creates an async function
      var 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: 20%;"); //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 = "NO!"; //Add the text NO! to the button
      } //Finishes the if condition
      else //If the text "No comments found" is NOT found
      { //Starts the else condition
        HasCommented.innerHTML = "YES!"; //Add the text YES! to the button
        HasCommented.onclick = function() { //Detects the mouse click on the 'YES!' button
          window.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 advent 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 advent listener
      }, 3000); //Finishes the setTimeout function

      var HasPMed = document.createElement("a"); //Creates an a element
      HasPMed.setAttribute("style", "cursor: pointer;margin-right: 30%;"); //Set the css for the button

      if (GM_listValues().includes(location.href.split('/')[4]) === true) //If the actual opened profile User Name is on the user PMed list
      { //Starts the if condition
        HasPMed.innerHTML = "YES!"; //Add the text YES! to the button
      } //Finishes the if condition
      else //If the actual opened profile User Name is NOT on the user PMed list
      { //Starts the else condition
        HasPMed.innerHTML = "NO!"; //Add the text NO! to the button
      } //Finishes the else condition

      document.querySelector("#comment").parentElement.appendChild(HasPMed); //Shows the button
    })(); //Finishes the async function
  } //Finishes the if condition
})();

QingJ © 2025

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