Skip to content

Instantly share code, notes, and snippets.

@beporter
Last active August 18, 2023 21:43
Show Gist options
  • Star 26 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save beporter/ce76204bcba35d9edb66b395bb5e9305 to your computer and use it in GitHub Desktop.
Save beporter/ce76204bcba35d9edb66b395bb5e9305 to your computer and use it in GitHub Desktop.
Greasemonkey script to repeatedly refresh a given page, look for specific "Add to Cart" buttons, click them if present, and make a lot of noise on success.

Add Items to Cart

Greasemonkey script to repeatedly refresh a given page, look for specific "Add to Cart" buttons, click them if present, and make a lot of noise on success.

This script was concieved and created due to the Nintendo Switch shortage during the COVID-19 pandemic. Its original purpose was to monitor for the Nintendo Switch console to come back into stock and get it added to your cart as quickly as possible. Granted, you stand very little chance compared to scalpers using fully automated tools like Bird Bot.

Installation

  • Install Tampermonkey or Greasemonkey for your browser.
  • Install the script into your browser by clicking the "Raw" button in the top-right corner of the js script below.

Setup

  • Sign into your Amazon.com, BestBuy.com or Walmart.com account (or all three).
  • Make sure your payment and shipping info is up to date to save time later.
  • Add the item(s) you want to buy to a new "wishlist" or "save for later" list.
  • (This script operates on the assumption that the items are out of stock or not available. If they're available... then just buy them.)

Usage

TODO

  • Move the selectors into GM local storage to allow end users to customize settings instead of having to edit the script itself.
  • Register a browser menu button to toggle the search/refresh on/off per-site.
// ==UserScript==
// @name Add Saved Items to Cart
// @namespace https://gist.github.com/beporter/ce76204bcba35d9edb66b395bb5e9305
// @version 0.5
// @description Repeatedly refresh a given "saved items" page (Amazon, Walmart, BestBuy), look for specific "Add to Cart" buttons, click them if present, and make a lot of noise on success.
// @author https://github.com/beporter
// @match https://www.amazon.com/gp/registry/wishlist/*
// @match https://www.amazon.com/hz/wishlist/ls/*
// @match https://www.bestbuy.com/cart
// @match https://www.bestbuy.com/site/customer/lists/manage/saveditems
// @match https://www.walmart.com/lists*
// @grant none
// @run-at document-idle
// @require https://cdnjs.cloudflare.com/ajax/libs/howler/2.1.3/howler.min.js#sha256-/Q4ZPy6sMbk627wHxuaWSIXS1y7D2KnMhsm/+od7ptE=
// @downloadURL https://gist.githubusercontent.com/beporter/ce76204bcba35d9edb66b395bb5e9305/raw/add_to_cart.user.js
// ==/UserScript==
(function() {
'use strict';
const SELECTORS = [
{
site: 'Walmart',
urls: ['https://www.walmart.com/lists'],
selector: 'div.ListDetails button.RegularItemTile-add-to-cart',
loadWait: 2,
cooldown: 5, // Set to 0 to disable the refresh.
active: true,
},
{
site: 'BestBuy',
urls: ['https://www.bestbuy.com/site/customer/lists/manage/saveditems'],
selector: '#your-saved-items .add-to-cart-button button:not([disabled])',
loadWait: 5,
cooldown: 5,
active: true,
},
{
site: 'Amazon',
urls: ['https://www.amazon.com/gp/registry/wishlist/', 'https://www.amazon.com/hz/wishlist/ls/'],
selector: 'div#my-lists-tab span[data-action=add-to-cart] a[role=button]',
loadWait: 5,
cooldown: 5,
active: true,
},
];
var readySound = new window.Howl({
src: ['//freesound.org/data/previews/187/187404_635158-lq.mp3'],
autoplay: false,
loop: true,
volume: 1.0,
});
// Scan the page for the provided selector and "click" them if present.
function triggerClicks(sel) {
var anyClicked = false;
const buttons = document.querySelectorAll(sel.selector);
// No available "Add to Cart" buttons. Cool down and refresh.
if (!buttons.length) {
console.log(`${sel.site}: No active "Add to Cart" buttons.`);
return anyClicked;
}
buttons.forEach((b) => {
var clickEvent = document.createEvent('MouseEvents');
clickEvent.initEvent('click', true, true);
b.dispatchEvent(clickEvent);
console.log(`${sel.site}: Clicked "Add to Cart" button.`);
anyClicked = true;
});
return anyClicked;
}
function refreshInSecs(secs) {
console.log(`Scheduling page refresh in ${secs} secs.`);
window.setTimeout(() => {
window.location.reload(true);
}, secs * 1000);
}
function waitToClick(sel, callback) {
console.log(`Scheduling clicks for ${sel.site}.`);
window.setTimeout(() => {
callback(sel);
}, sel.loadWait * 1000);
}
function locationStartsWithAnyOfUrls(urls) {
return urls.reduce((acc, url) => {
return acc || window.location.href.startsWith(url);
}, false);
}
// function main()
SELECTORS.forEach((sel) => {
if (sel.active && locationStartsWithAnyOfUrls(sel.urls)) {
waitToClick(sel, (sel) => {
if (triggerClicks(sel)) {
readySound.play();
} else if (sel.cooldown) {
refreshInSecs(sel.cooldown);
}
});
}
});
})();
@Kryticalgg
Copy link

Works amazing except for the best buy portion of it, thank you for making this <3

@beporter
Copy link
Author

Thanks for the kind words!

It's always possible that any of these vendors will change the HTML that makes up the targeted pages at any time. If I have time soon, I'll investigate the Best Buy case and see if there's an updated batch of settings that will make this script work again. Cheers!

@ahudson25
Copy link

Has there been an update whether the BB sections is functioning properly or not? Thank you for sharing this!

@nicjansma
Copy link

Copy link

ghost commented Dec 3, 2020

Thank you @beporter for this awesome script! All original sites still appear to be working, I added support for smile.amazon and newegg:

https://gist.github.com/donjuanmon/375a4e26292217b8c564df18a6325d70

@nickv2002
Copy link

Thank you @beporter for this awesome script! All original sites still appear to be working, I added support for smile.amazon and newegg:

https://gist.github.com/donjuanmon/375a4e26292217b8c564df18a6325d70

Thanks, but your Gist doesn't seem to be publicly viewable.

@ScOrPi074
Copy link

ScOrPi074 commented Mar 30, 2021

thank you so much for that script , specially for newbies eazy to install . sorry for my dum questions but what does this mean
1: Move the selectors into GM local storage to allow end users to customize settings instead of having to edit the script itself.
2:Register a browser menu button to toggle the search/refresh on/off per-site.
3: is it possible to run it on bestbuy canada ??? thx

ive testing your bot on bestbuy usa and i add a item in stock and it wont add it automatically. amazon worked perfectly thx

@beporter
Copy link
Author

Hi @ScOrPi074, glad you like it.

In general the things you mention are notes on potential code improvements that could be made to this script.

  1. Right now if the code on any of the websites changes, this script would break and require tweaking. This should be something that people can do themselves after installing the script. The browser extension that typically runs this script (GreaseMonkey or TamperMonkey-- abbreviated "GM") has functions available to store these changes in each user's browser memory.
  2. GM also has a way to add a button to your browser's address bar. For this script, that button could be an on/off toggle for whether the script should be "active" and refreshing the page for you, or "inactive" (so that you could make changes to your wishlist without this script refreshing the page all the time.)
  3. Yes this is possible, but as explained in #1, currently requires modifying the source code for the script after installing it.

It's certainly possible that what I explained in #1 has already happened for Best Buy USA.

@TurtleFaceOSRS
Copy link

TurtleFaceOSRS commented Mar 31, 2021

Hi @beporter - is there an easy way to adapt this to other sites?

I think I almost have it, I have the page on the website refreshing but struggling to find how the Selector is determined.

@beporter
Copy link
Author

@TurtleFaceOSRS Right now the only way is:

  1. In TM or GM's built-in editor, open your local copy of this script.
  2. Add the new domain into the header as an additional // @match https://NEW_SITE/PATH_TO_WISHLIST* line.
  3. Add a new entry into the const SELECTORS array with appropriate values for NEW_SITE.

@TurtleFaceOSRS
Copy link

TurtleFaceOSRS commented Mar 31, 2021

@beporter

// @match https://www.thewhiskyexchange.com/p/3430/littlemill-1985-bot2002-connoisseurs-choice*

{ site: 'TWE', urls: ['https://www.thewhiskyexchange.com/p/3430/littlemill-1985-bot2002-connoisseurs-choice'], selector: 'product-atb__button cta-button cta-button--full-width cta-button--alpha cta-button--regular js-product__add-to-basket', loadWait: 2, cooldown: 5, // Set to 0 to disable the refresh. active: true, }

For page; https://www.thewhiskyexchange.com/p/3430/littlemill-1985-bot2002-connoisseurs-choice

The page refreshes so that part of the script is working, but it's finding the correct identifier for the bottle which I cannot nail.

<button class="product-atb__button cta-button cta-button--full-width cta-button--alpha cta-button--regular js-product__add-to-basket" onclick="_gaq.push(['_trackEvent', 'ProductPage-ATB-Default', 'click', '3430 : Littlemill 1985 / Bot.2002 / Connoisseurs Choice'])">Add to Basket</button>

@ScOrPi074
Copy link

ScOrPi074 commented Apr 1, 2021

Thanks for the support Mr @Bporter, is there any source where i can learn how to fix manually websites code changes ? or any screenshot examples. by the way amazon working perfectly , thx sir

@StarLordRammi
Copy link

StarLordRammi commented Apr 13, 2021

is it possible to add this site please?
https://www.cclonline.com/product/346125/GV-R67XTEAGLE-12GD/Graphics-Cards/Gigabyte-Radeon-RX-6700-XT-EAGLE-12GB-Graphics-Card/VGA6121/

no wishlist. just need to click Add to cart button

@Yaidier-br
Copy link

If you can help me for a store that sells at a specific time and does not have a wish list.

@hewilliam
Copy link

this is working great but i have to keep solving captcha's after a while. it would be awesome if we can put in a 2captcha.com key to bypass the captchas. none the less, this is awesome work!

@kkapuria3
Copy link

Hi !

check this for for best buy !

https://github.com/kkapuria3/BestBuy-GPU-Bot

@SgtPooki
Copy link

SgtPooki commented Nov 8, 2021

Walmart was doing an online-only Xbox series x sale (2021 NOV 05 15:00 ET). I attempted to use this script, but had to make the following changes:

  1. Add a different url since the lists page doesn't seem to have add to cart buttons anymore.
  2. Update the add to cart selector. See https://gist.github.com/SgtPooki/868d30d70b5a51922e371d6542b58d4d#file-add_to_cart-user-js-L26

@azineth
Copy link

azineth commented Dec 11, 2021

hello, le add-to-cart don't work for amazon.
the selector : selector: 'div#my-lists-tab span[data-action=add-to-cart] a[role=button]', not work !

buttons. or button. , normaly buttons.

// No available "Add to Cart" buttons. Cool down and refresh.
if (!buttons.length) {
console.log(${sel.site}: No active "Add to Cart" buttons.);
return anyClicked;
}

    buttons.forEach((b) => {
        var clickEvent = document.createEvent('MouseEvents');
        clickEvent.initEvent('click', true, true);
        b.dispatchEvent(clickEvent);
        **console.log(`${sel.site}: Clicked "Add to Cart" button.`);**
        anyClicked = true;
    });

Thank you for help !!!

@ddizzle22
Copy link

Would this be possible to get in touch to see about using this script on another site where an item is out of stock but then is loaded in and it automatically puts it to final checkout screen?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment