Skip to content

Instantly share code, notes, and snippets.

@brucebentley
Last active January 11, 2021 21:40
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brucebentley/f14297796a89e679c0bf9112ac2fed70 to your computer and use it in GitHub Desktop.
Save brucebentley/f14297796a89e679c0bf9112ac2fed70 to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name Buy A PS5
// @version 1.0.0
// @description A userscript that collapses markdown headers
// @author Bruce Bentley <brucebentley@me.com> (https://brucebentley.io)
// @copyright 2021, Bruce Bentley (https://github.com/brucebentley)
// @license MIT; https://opensource.org/licenses/MIT
// @namespace https://github.com/brucebentley
// @description
// @match https://www.target.com/*
// @match https://www.bestbuy.com/*
// @match https://www.gamestop.com/*
// @match https://www.walmart.com/*
// @match https://www.amazon.com/*
// @grant GM_setValue
// @grant GM_getValue
// ==/UserScript==
/**
* HOW THIS SCRIPT WORKS:
* Hello! I hope you're having a marvellous October.
* When you're on a product detail page (target.com/p/...), this script replicates
* the server request the page would normally perform. No hacky fake-button-clicking!
* The script polls for stock availability repeatedly, and the instant it finds it,
* it attempts to add to cart and instant-checkout.
*
* WHAT YOU SHOULD DO:
* 1. Purchase anything from target.com so your credit card details and CCV are
* saved to your account.
* 3. Log in.
* 4. You'll first need access keys. These are the keys your Target web app uses to
* authenticate with the server. Go to a random in-stock pre-order product, say,
* https://www.target.com/p/spider-man-miles-morales-playstation-4/-/A-81491473
* 5. Right click -> Inspect Element -> Network -> XHR
* 6. On the webpage, refresh. Click "Pre-order".
* 7. In Inspect Element, in the Filter text box, type "pdp_fulfilment".
* Click the item in the list. In the right column, scroll to "Query string
* parameters", and copy "key". Paste this below under PUBLIC_ACCESS_KEY.
* 8. Back in the Filter box, type "cart_items"
* 9. Again, click the cart_items list item, scroll the right column and copy "key".
* Paste it in PRIVATE_ACCESS_KEY.
* 10. Okay hard part is done! Be sure to clear your cart.
* 4. Go to the PDP (target.com/p/...) of the product you want to pre-order.
* 5. Enable the script. Refresh.
* 6. Right-click -> Inspect Element to see progress in the Console.
* Messages from the script are prefixed "TAMPERMONKEY:". Check "Preserve log" under the gear icon.
*
* NOTES:
* - This script will immediately purchase the product you're looking at the *instant*
* it's available! Don't casually browse Target.com with this script enabled!
* - Your tab needs to be visible and screensaver disabled or Chrome will slow down the script.
* - This script doesn't need the PS5 saved in your "Saved for later".
* - You don't need to refresh the page while the script runs. You'll never see the enabled
* "Pre-order now" red button. Success will send you straight to your cart.
* - You only need one tab open. Multiple tabs open might cause multiple purchases!
* - The script will attempt to stop once one purchase happens. You should then turn it off.
* - If adding to the cart has failed (because someone beat you to it), the server will
* respond "access denied". It'll also say that if you're banned. So don't make this script
* too aggressive.
*/
const PUBLIC_ACCESS_KEY = 'abc123123_PASTE_KEY_HERE';
const PRIVATE_ACCESS_KEY = 'abc123123_PASTE_KEY_HERE';
const CHECK_FOR_STOCK_SECONDS = 1;
const REPEATEDLY_ADD_TO_CART_SECONDS = 5;
const RELOAD_PAGE_MINUTES = 10;
const PRODUCT_ID = window.location.pathname.match(/A-(\d*)/)[1];
const isPDP = window.location.pathname.startsWith('/p/');
let timeoutValid = true;
let stockAvail = false;
const consoleBg1 = [ 'background: orange', 'color: white', 'display: block', 'padding: 30px 0'].join(';');
const consoleBg2 = [ 'background: #00c4ff', 'color: white', 'display: block', 'padding: 30px 0'].join(';');
const consoleBg3 = [ 'background: green', 'color: white', 'display: block', 'padding: 30px 0'].join(';');
const beep = () => {(new Audio(
"data:audio/wav;base64,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 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////VEFHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU291bmRib3kuZGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMjAwNGh0dHA6Ly93d3cuc291bmRib3kuZGUAAAAAAAAAACU="
)).play()}
setTimeout(() => {
if (document.querySelector("[data-test='accountUserName']").textContent == 'Sign in') {
alert("TAMPERMONKEY: You're not logged in. Log in first.")
}
},3000);
const superInstantCheckout = async () => {
const preCheckoutRes = await fetch("https://carts.target.com/web_checkouts/v1/pre_checkout?field_groups=ADDRESSES%2CCART%2CCART_ITEMS%2CDELIVERY_WINDOWS%2CPAYMENT_INSTRUCTIONS%2CPICKUP_INSTRUCTIONS%2CPROMOTION_CODES%2CSUMMARY&key=" + PRIVATE_ACCESS_KEY, {
"headers": {
"accept": "application/json",
"accept-language": "en-US,en;q=0.9",
"content-type": "application/json",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-site",
"x-application-name": "web"
},
"referrer": "https://www.target.com/co-review?precheckout=true",
"body": "{\"cart_type\":\"REGULAR\"}",
"method": "POST",
"mode": "cors",
"credentials": "include"
});
console.info('%c TAMPERMONKEY: At pre-checkout stage. Result:', consoleBg3, await preCheckoutRes.json());
const res = await fetch("https://carts.target.com/web_checkouts/v1/checkout?field_groups=ADDRESSES%2CCART%2CCART_ITEMS%2CDELIVERY_WINDOWS%2CPAYMENT_INSTRUCTIONS%2CPICKUP_INSTRUCTIONS%2CPROMOTION_CODES%2CSUMMARY&key=" + PRIVATE_ACCESS_KEY, {
"headers": {
"accept": "application/json",
"accept-language": "en-US,en;q=0.9",
"content-type": "application/json",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-site",
"x-application-name": "web"
},
"referrer": "https://www.target.com/co-review",
"body": "{\"cart_type\":\"REGULAR\",\"channel_id\":10}",
"method": "POST",
"mode": "cors",
"credentials": "include"
});
console.info('%c TAMPERMONKEY: Purchase attempted!!! Result:', consoleBg3, await res.json())
}
// if it's a product detail page
if (isPDP) {
// CHECK FOR STOCK
setInterval(async function() {
if (GM_getValue('brucebentleyPS5Purchased')) return console.log('TAMPERMONKEY: Purchased a PS5 in another tab. Stopped.')
const res = await fetch("https://redsky.target.com/redsky_aggregations/v1/web/pdp_fulfillment_v1?key=" + PUBLIC_ACCESS_KEY + "&tcin="+ PRODUCT_ID +"&store_id=1108&zip=11787&state=NY&latitude=40.870&longitude=-73.210&scheduled_delivery_store_id=1108&pricing_store_id=1108&fulfillment_test_mode=grocery_opu_team_member_test&is_bot=false", {
"headers": {
"accept": "application/json",
"accept-language": "en-US,en;q=0.9",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-site"
},
"referrer": "https://www.target.com/p/playstation-5-console/-/A-81114595",
"body": null,
"method": "GET",
"mode": "cors",
"credentials": "omit"
});
const resJson = await res.json()
let availStatus;
if (resJson.data && resJson.data.product && resJson.data.product.fulfillment) {
availStatus = resJson.data.product.fulfillment.shipping_options.availability_status
}
if (availStatus == 'PRE_ORDER_UNSELLABLE') {
console.log('TAMPERMONKEY: No stock available.')
stockAvail = false;
timeoutValid = true;
} else {
beep(); beep(); beep();
stockAvail = true
return console.info('%c TAMPERMONKEY: ' + availStatus, consoleBg2, ' \n', new Date(), '\n', resJson);
}
}, CHECK_FOR_STOCK_SECONDS*1000);
// ADD TO CART
setInterval(async function() {
if (!timeoutValid || !stockAvail) return;
// I don't advise having multiple competing tabs, but this will attempt to prevent dupe purchases
if (GM_getValue('brucebentleyPS5Purchased')) return console.log('TAMPERMONKEY: Purchased a PS5 in another tab. Stopped.')
// run this timeout instantly, once. It'll re-enable in the block below
timeoutValid = false;
const res = await fetch("https://carts.target.com/web_checkouts/v1/cart_items?field_groups=CART%2CCART_ITEMS%2CSUMMARY&key=" + PRIVATE_ACCESS_KEY, {
"headers": {
"accept": "application/json",
"accept-language": "en-US,en;q=0.9",
"content-type": "application/json",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-site",
"x-application-name": "web"
},
"referrer": "https://www.target.com/p/playstation-5-console/-/A-81114595",
"body": "{\"cart_type\":\"REGULAR\",\"channel_id\":\"10\",\"shopping_context\":\"DIGITAL\",\"cart_item\":{\"tcin\":\"" + PRODUCT_ID + "\",\"quantity\":1,\"item_channel_id\":\"10\"},\"fulfillment\":{\"fulfillment_test_mode\":\"grocery_opu_team_member_test\"}}",
"method": "POST",
"mode": "cors",
"credentials": "include"
});
const resJson = await res.json()
if (res.ok || resJson.cart_id) {
console.info('%c TAMPERMONKEY: Successfully added to cart! Attempting to purchase...', consoleBg3, resJson);
timeoutValid = false;
GM_setValue('brucebentleyPS5Purchased', true);
superInstantCheckout()
} else {
const err = resJson['Error']['Detail'];
return console.error('%c TAMPERMONKEY: add to cart failed. ', consoleBg1, '\n', new Date(), '\n', err, res, resJson);
}
}, 1);
// reset the add to cart timeout
// in case adding failed the first time.
// don't make this too aggressive!
setInterval(() => {
timeoutValid = true;
}, REPEATEDLY_ADD_TO_CART_SECONDS*1000);
// reload the page every so often to refresh the session cookies/not get bot-banned
setInterval(() => {
window.location.reload()
}, RELOAD_PAGE_MINUTES*60*1000);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment