Advertisement
AkitoApocalypse

Untitled

Feb 25th, 2021
1,266
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ==UserScript==
  2. // @name         Best Buy (Saved Items)
  3. // @namespace    akito
  4. // @version      1.0.0
  5. // @description  Auto-presses drops when button changes to Add
  6. // @author       akito#9528 on Discord
  7. // @match        https://www.bestbuy.com/site/customer/lists/manage/saveditems
  8. // @run-at       document-start
  9. // @grant        none
  10. // ==/UserScript==
  11.  
  12.  
  13. // Version Changelog
  14. // 1.0.0 - Initial Release for saved items script
  15.  
  16. const title = "Best Buy (Saved Items) by akito#9528"
  17. const whitelist = ["3060", "3070", "3080", "3090", "6800", "6900", "5600x", "5800x", "5900x", "5950x"];
  18. // keyword whitelist, edit this if you want
  19.  
  20. async function addObserver(cartButton, description, banner) {
  21.     let flipped = cartButton.innerText.includes("Please"); // check whether ever included "Please"
  22.     const MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
  23.     let observer = new MutationObserver(function(mutations, observer) {
  24.         if(cartButton.innerText.includes("Add") && flipped) {
  25.             // Not sure whether I should open the cart or do something else lol
  26.             cartButton.click(); // click button when please changes to add
  27.             window.open("https://www.bestbuy.com/checkout/r/fast-track");
  28.  
  29.             // play sound for notification purposes
  30.             const audio = new Audio("https://proxy.notificationsounds.com/notification-sounds/definite-555/download/file-sounds-1085-definite.mp3");
  31.             audio.play();
  32.  
  33.             banner.innerHTML = `${title} | Successfully added [${description}] to cart!`;
  34.  
  35.             observer.disconnect();
  36.         } else if(cartButton.innerText.includes("Please") && flipped === false) {
  37.             flipped = true; // flip when please detected
  38.         }
  39.     });
  40.     observer.observe(cartButton, {
  41.         attributes: true,
  42.         characterData: true,
  43.         childList: true,
  44.         subtree: true,
  45.         attributeOldValue: true,
  46.         characterDataOldValue: true
  47.     });
  48. }
  49.  
  50. // Filters products and sends to addObserver
  51. async function automate(banner) {
  52.     const savedButtons = document.getElementsByClassName("add-to-cart-button");
  53.     const savedDescs = document.getElementsByClassName("img-responsive");
  54.  
  55.     // Filter button descriptions to only those that are in the whitelist [O(n^2) sigh]
  56.     // Length mismatch because of stray buttons being added but just ignore them.
  57.     banner.innerHTML = `${title} | Filtering items: ${savedButtons.length} buttons and ${savedDescs.length} descriptions found`;
  58.     await new Promise(r => setTimeout(r, 1000)); // wait so people can actually read this
  59.     banner.innerHTML = `${title} | Adding individual mutation observers ...`;
  60.  
  61.     let numValid = 0; // number of products with mutation observers attached
  62.     for(let productIndex = 0; productIndex < savedDescs.length; productIndex++) {
  63.         // check whether product contains whitelist keyword
  64.         let validProduct = false;
  65.         const description = savedDescs[productIndex].getAttribute("alt");
  66.         for(const keyword of whitelist) {
  67.             if(description.includes(keyword)) {
  68.                 validProduct = true;
  69.                 numValid++;
  70.                 break;
  71.             }
  72.         } // then skip product if not whitelisted
  73.         if(validProduct === false) {
  74.             continue;
  75.         }
  76.  
  77.         // actual attachment of mutation observers
  78.         addObserver(savedButtons[productIndex], description, banner);
  79.     }
  80.  
  81.     banner.innerHTML = `${title} | Finished, ${numValid} of ${savedDescs.length} products had observers attached.`;
  82. }
  83.  
  84. // main function body
  85. (function() {
  86.     'use strict'; // necessary?
  87.  
  88.     // initialize bottom status banner
  89.     let banner = document.createElement("div");
  90.     banner.style.position = "fixed"; banner.style.bottom = "0px"; banner.style.zIndex = 100;
  91.     banner.style.width = "100%"; banner.style.padding = "4px"; banner.style.textAlign = "center";
  92.     banner.style.backgroundImage = "linear-gradient(to right, coral, crimson, coral, crimson)";
  93.     banner.innerHTML = `${title} | <button id="begin">[ Press after scrolling and all products loaded ]</button>`;
  94.  
  95.     // Mutation Observer to detect HTML changes to the "Add to Cart" / "Please Wait" button
  96.     // The script waits until the button switches from "Please Wait" back to "Add to Cart" (keep in mind you have to press the first Add button)
  97.     // At that point, it clicks the button to add the item to the cart, plays a fancy notification sound, and opens a new window with the cart.
  98.     // [ Note: untested on actual drops, only manually tested by manually changing the HTML ]
  99.     document.addEventListener("DOMContentLoaded", function(event) {
  100.         document.body.append(banner);
  101.         document.getElementById("begin").onclick = function() { automate(banner); };
  102.     }); // wait for document body to load
  103. }());
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement