Advertisement
AkitoApocalypse

Untitled

Feb 25th, 2021 (edited)
2,275
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ==UserScript==
  2. // @name         Best Buy Queue Automation
  3. // @namespace    akito
  4. // @version      1.5.0
  5. // @description  Auto-presses drops when button changes to Add
  6. // @author       akito
  7. // @match        https://www.bestbuy.com/*skuId=*
  8. // @match        https://www.bestbuy.com/site/combo/*
  9. // @run-at       document-start
  10. // @grant        none
  11. // ==/UserScript==
  12.  
  13. // Version Changelog
  14. // 1.0.0 - Initial Version
  15. // 1.1.1 - I honestly forgot what I changed here
  16. // 1.2.0 - Fixed observer to correctly receive element stimulus from JS
  17. // 1.3.0 - Added this useless bottom banner thing
  18. // 1.3.1 - Little more verbose output for what exactly script is doing
  19. // 1.4.0 - Changed workings to check for aria-described-by for overlay?
  20. // 1.5.0 - Changed workings to check rendered button color, hopefully works now
  21.  
  22. const title = "Best Buy (Product Details) Automation by akito#9528";
  23.  
  24. // Quick dirty function which checks the rendered button color for availability.
  25. function buttonAvailable(button) {
  26.     return window.getComputedStyle(button, null).getPropertyValue("background-color") === "rgb(255, 224, 0)";
  27. }
  28.  
  29. // main function body
  30. (function() {
  31.     'use strict'; // necessary?
  32.  
  33.     // initialize bottom status banner
  34.     let banner = document.createElement("div");
  35.     banner.style.position = "fixed"; banner.style.bottom = "0px"; banner.style.zIndex = 100;
  36.     banner.style.width = "100%"; banner.style.padding = "4px"; banner.style.textAlign = "center";
  37.     banner.style.backgroundImage = "linear-gradient(to right, coral, crimson, coral, crimson)";
  38.     banner.innerHTML = `${title} | Initializing script`;
  39.  
  40.     // Mutation Observer to detect HTML changes to the "Add to Cart" / "Please Wait" button
  41.     // The script waits until the button color changes from grey (Please Wait) back to yellow (Add to Cart).
  42.     // At that point, it clicks the button, plays a fancy notification sound, and opens a new window with express checkout.
  43.     // > Note: untested on actual drops, only manually tested by manually changing the HTML
  44.     // > Note: only tested on changing of element's classes, unsure if changes within a class cause mutation
  45.     document.addEventListener("DOMContentLoaded", async function() {
  46.         document.body.append(banner); // add banner to DOM
  47.  
  48.         // check current product status (available, sold out, waiting)
  49.         const cartButton = document.getElementsByClassName("add-to-cart-button")[0];
  50.         const soldOut = cartButton.classList.contains("btn-disabled"); // disabled button
  51.         let initAvailable = buttonAvailable(cartButton);
  52.         banner.innerHTML = soldOut ? `${title} | Product currently sold out, script non-functioning`
  53.             : initAvailable ? `${title} | Add button clickable, please click to initialize product queue`
  54.             : `${title} | Existing product queue detected, waiting for button availability change`;
  55.         if(soldOut) { // don't run script on sold out products
  56.             return;
  57.         }
  58.  
  59.         // actual mutation observer which checks for element changes
  60.         let currentAvailable;
  61.         const MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
  62.         let observer = new MutationObserver(async function(mutations, observer) {
  63.             await new Promise(r => setTimeout(r, 500)); // wait for animation to settle
  64.  
  65.             // check whether the mutation modified the button color at all
  66.             currentAvailable = buttonAvailable(cartButton);
  67.             if(initAvailable === true && currentAvailable === false) {
  68.                 // button clicked to enter queue (yellow => grey)
  69.                 banner.innerHTML = `${title} | Queue entry detected, waiting for button availability change`;
  70.  
  71.                 initAvailable = false;
  72.             } else if(initAvailable === false && currentAvailable === true) { // product now available from queue
  73.                 // product avialable (grey => yellow)
  74.                 banner.innerHTML = `${title} | Availability change detected, button clicked and window opened! Good luck!`;
  75.  
  76.                 // click button, play audio, and open window
  77.                 cartButton.click();
  78.                 window.open("https://www.bestbuy.com/checkout/r/fast-track");
  79.                 const audio = new Audio("https://proxy.notificationsounds.com/notification-sounds/definite-555/download/file-sounds-1085-definite.mp3");
  80.                 audio.play();
  81.  
  82.                 observer.disconnect();
  83.             }
  84.         });
  85.         observer.observe(cartButton, {
  86.             attributes: true,
  87.             characterData: true,
  88.             childList: true,
  89.             subtree: true,
  90.             attributeOldValue: true,
  91.             characterDataOldValue: true
  92.         });
  93.     });
  94. }());
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement