Shrooms

Untitled

Nov 14th, 2019
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. const rp = require("request-promise")
  2.  
  3. const getPookyUrl = (region) => {
  4. let usPooky = "https://pooky.dev:1337/gen?token=h20-44a81-s28dn-8ad9s"
  5. let euPooky = "https://pooky.dev:1337/gen?token=h20-44a81-s28dn-8ad9s&region=eu"
  6. return region === 'SupremeUS' ? usPooky : euPooky
  7. }
  8.  
  9. const iPhone6 = {
  10. 'name': 'iPhone 6',
  11. 'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1',
  12. 'viewport': {
  13. 'width': 375,
  14. 'height': 667,
  15. 'deviceScaleFactor': 2,
  16. 'isMobile': true,
  17. 'hasTouch': true,
  18. 'isLandscape': false
  19. }
  20. };
  21.  
  22. function sleep(ms) {
  23. return new Promise(resolve => {
  24. setTimeout(resolve, ms)
  25. })
  26. }
  27.  
  28.  
  29. const encodeVariants = (variants) => {
  30. let varObj = {}
  31. variants.forEach(v => varObj[v] = 1)
  32. return encodeURIComponent(JSON.stringify(varObj).replace(/'/g, '"'))
  33. }
  34.  
  35. const getCheckoutData = (region, variants) => {
  36. const usCheckoutData = {
  37. 'store_credit_id': '',
  38. 'from_mobile': '1',
  39. 'cookie-sub': encodeVariants(variants),
  40. 'same_as_billing_address': '1',
  41. 'scerkhaj': 'CKCRSUJHXH',
  42. 'order[bn]': "Daniel Young",
  43. 'order[billing_name]': "",
  44. 'order[email]': "[email protected]",
  45. 'order[tel]': "2155123271",
  46. 'order[billing_address]': "3561 Meadowlark Drive",
  47. 'order[billing_address_2]': "",
  48. 'order[billing_zip]': "19006",
  49. 'order[billing_city]': "Huntingdon Valley",
  50. 'order[billing_state]': "Pennsylvania",
  51. 'order[billing_country]': "United States",
  52. 'riearmxa': "4478874829206427",
  53. 'credit_card[month]': "02",
  54. 'credit_card[year]': "2020",
  55. 'rand': '',
  56. 'credit_card[meknk]': "717",
  57. 'order[terms]': 0,
  58. 'order[terms]': 1,
  59. 'g-recaptcha-response': "03AOLTBLRb_A0LF2utI5YYdYjkrIM2FZgxO4dLjQpwsGVSMuGAwdkK03VN-2Sq5r1G3BG6xFQeoxU-6ZWcwfsJaE-qrU4fFtlU2oyMb37_NtgPPUbsGE4rJxDRv3hKNZez1BTIQehk2taTXhFe9vtk0-9ro41486uTgk_9SxRSDMbpuU8ckeju1tXWzfNVetDOLEH66U7mROk3NpZYYUj8-A6wu7J9HAC1PGiVDlfDVAH8RmQQXEyYRQWSMfbsdeTN9OlypInmcRWHN59iXi9SieCdzH6Q1W35tOurTPzvU8LKHfjEUwN9b2wsMnato0zQlgui0sGTkCGPeXbQNTYcCiiZKwbjWuhckUGd_3OMfKPRpnctCrPAdxQ55aogYjjtHQCmj7-E4Y10dZIdZFQoEypqXWqwCC343w"
  60. }
  61.  
  62. return region === 'SupremeUS' ? usCheckoutData : euCheckoutData
  63. }
  64.  
  65. class SupremeClient {
  66.  
  67. constructor(task) {
  68. this.task = task
  69.  
  70.  
  71. //keep track
  72. this.pookyString;
  73.  
  74. //TODO: implement stop
  75. this.stopped = false;
  76. this.canStart = true;
  77.  
  78. this.rp = rp.defaults({ jar: true, json: true });
  79.  
  80. }
  81.  
  82.  
  83. async start() {
  84. console.log("Starting task")
  85. this.stopped = false;
  86. this.canStart = false;
  87.  
  88. }
  89.  
  90.  
  91. async stop() {
  92. console.log(`Stopping task`)
  93.  
  94. this.canStart = true;
  95. this.stopped = true;
  96. }
  97.  
  98. async getItem() {
  99. if (!this.stopped) {
  100. const category = this.task.category;
  101. const keywords = this.task.keywords;
  102.  
  103. console.log("keywords:", keywords)
  104.  
  105. const time = (new Date()).getTime();
  106. let options = {
  107. url: `https://www.supremenewyork.com/shop.json?_=${time}`,
  108. method: 'get',
  109. headers: {
  110. 'User-Agent': iPhone6.userAgent
  111. }
  112. };
  113.  
  114. console.log(options)
  115.  
  116. try {
  117. let response = await this.rp(options)
  118.  
  119. const parsedProducts = response['products_and_categories']
  120.  
  121. var parsedNewProducts = []
  122.  
  123. //TODO: modify depending on values in html.
  124. if (category === 'All') {
  125. for (let category of Object.values(parsedProducts)) {
  126. for (let product of category) {
  127. parsedNewProducts.push(product)
  128. }
  129. }
  130. } else {
  131. if (category === 'New')
  132. parsedNewProducts = parsedProducts['new'];
  133. else
  134. parsedNewProducts = parsedProducts[category];
  135. }
  136.  
  137. const positiveKeywords = keywords.split(',').filter(keyword => keyword.includes('+')).map(keyword => keyword.replace('+', '').trim());
  138. const negativeKeywords = keywords.split(',').filter(keyword => keyword.includes('-')).map(keyword => keyword.replace('-', '').trim());
  139. console.log(positiveKeywords, negativeKeywords)
  140. for (let product of parsedNewProducts) {
  141. let productTitle = product.name.replace(/[\u{0080}-\u{FFFF}]/gu, "")
  142. let productId = product.id
  143. var posNum = 0
  144. var negNum = 0
  145. for (let posKw of positiveKeywords) {
  146. if (productTitle.toLowerCase().includes(posKw.toLowerCase().trim())) {
  147. posNum++
  148. }
  149. }
  150. for (let negKw of negativeKeywords) {
  151. if (productTitle.toLowerCase().includes(negKw.toLowerCase().trim())) {
  152. negNum++
  153. }
  154. }
  155. if (posNum === positiveKeywords.length && negNum === 0) {
  156. // productTitle , productId
  157. //TODO: add error handling if no product is found
  158. console.log("found product", productTitle, productId)
  159. return await this.getSizes(productId)
  160. }
  161. }
  162. } catch (err) {
  163. console.log(`Error getting item: ${err.message}`)
  164. await this.getItem()
  165. }
  166. }
  167.  
  168. }
  169.  
  170. async getSizes(productId) {
  171. if (!this.stopped) {
  172. console.log("Finding Size")
  173. let productColorPref = this.task.color;
  174. let productSizePref = this.task.size;
  175. let options = {
  176. url: `https://www.supremenewyork.com/shop/${productId}.json`,
  177. method: 'get',
  178. headers: {
  179. 'User-Agent': iPhone6.userAgent
  180. }
  181. };
  182.  
  183. try {
  184. let response = await this.rp(options)
  185. const styles = response["styles"]
  186.  
  187.  
  188.  
  189. console.log(styles)
  190.  
  191. let colorId;
  192. let sizeId;
  193.  
  194. for (let style of styles) {
  195. if (style["name"].toLowerCase() === productColorPref.toLowerCase()) {
  196. colorId = style["id"]
  197. for (let size of style["sizes"]) {
  198. if (productSizePref === "None") {
  199. sizeId = size['id']
  200. } else if (size["name"].toLowerCase() === productSizePref.toLowerCase()) {
  201. sizeId = size["id"];
  202.  
  203. break;
  204. }
  205. }
  206.  
  207. break;
  208. }
  209. }
  210.  
  211. //TODO: change to status message, maybe add retry?
  212. if (!colorId || !sizeId) {
  213. console.log(colorId, sizeId)
  214. return undefined;
  215. } else {
  216. console.log("got colorid and sizeid", colorId, sizeId)
  217. return await this.atc(colorId, sizeId, productId)
  218. }
  219.  
  220. } catch (err) {
  221. this.sendStatus("Error Getting Sizes")
  222. await getSizes(productId)
  223. console.log(`Error getting sizes: ${err}`)
  224. }
  225.  
  226. }
  227.  
  228. }
  229.  
  230. async atc(colorId, sizeId, productId, formStyle, formSize) {
  231. if (!this.stopped) {
  232. console.log("Adding To Cart")
  233.  
  234. let parsedPooky, msBefore
  235. if (this.task.pooky === "on") {
  236. msBefore = Date.now()
  237. parsedPooky = await this.getPooky(false)
  238.  
  239. if (!parsedPooky) {
  240. console.log("Could not get pooky cookies... stopping.")
  241. return this.stopped = true;
  242. }
  243. }
  244.  
  245.  
  246. //TODO: check region, proxy support
  247. let options = {
  248. url: `https://www.supremenewyork.com/shop/${productId}/add.json`,
  249. method: 'POST',
  250. headers: {
  251. 'Host': 'www.supremenewyork.com',
  252. 'Accept': 'application/json',
  253. "Content-Type": "application/x-www-form-urlencoded",
  254. 'X-Requested-With': 'XMLHttpRequest',
  255. 'Pragma': 'no-cache',
  256. 'Cache-Control': 'no-cache',
  257. 'Accept-Language': 'en-us',
  258. 'Origin': 'https://www.supremenewyork.com',
  259. 'User-Agent': "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1",
  260. 'Referer': 'https://www.supremenewyork.com/mobile',
  261. 'Connection': 'keep-alive',
  262. },
  263. form: {
  264. "qty": "1"
  265. },
  266. proxy: this.task.proxy
  267. };
  268.  
  269. if (this.task.site === "SupremeUS") {
  270. options["form"]["s"] = sizeId
  271. options["form"]["st"] = colorId
  272. } else {
  273. options["form"]["size"] = sizeId
  274. options["form"]["style"] = colorId
  275. }
  276.  
  277. if (this.task.pooky === "on") {
  278. options["headers"]["cookie"] = `lastid=${msBefore}; ${parsedPooky}`
  279. }
  280. console.log(options["form"])
  281. try {
  282. let response = await this.rp(options)
  283.  
  284. console.log("atc response:", response)
  285.  
  286. //TODO: check
  287. if (response[0].in_stock === true) {
  288. console.log("Added to cart")
  289. return await this.checkout(sizeId)
  290. } else {
  291. console.log("Error")
  292. sleep(1000)
  293. return this.atc(colorId, sizeId, productId)
  294. }
  295.  
  296. } catch (err) {
  297. console.log(`Error adding to cart: ${err.message}`)
  298. }
  299. }
  300. }
  301.  
  302. async checkout(variant) {
  303. if (!this.stopped) {
  304. let parsedPooky, msBefore
  305. if (this.task.pooky === "on") {
  306. msBefore = Date.now()
  307. parsedPooky = await this.getPooky(true)
  308.  
  309. if (!parsedPooky) {
  310. console.log("Could not get pooky cookies... stopping.")
  311. return this.stopped = true;
  312. }
  313. }
  314.  
  315. //TODO: use promise.all or something to get captcha and pooky at same time..
  316.  
  317.  
  318. let options = {
  319. url: `https://www.supremenewyork.com/checkout.json`,
  320. method: 'post',
  321. headers: {
  322. 'Accept': 'application/json',
  323. 'accept-encoding': 'gzip, deflate, br',
  324. 'Accept-Language': 'en-US,en;q=0.9',
  325. 'Origin': 'https://www.supremenewyork.com',
  326. 'Referer': 'https://www.supremenewyork.com/mobile/',
  327. "Content-Type": "application/x-www-form-urlencoded",
  328. 'User-Agent': "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1",
  329. 'X-Requested-With': 'XMLHttpRequest',
  330. 'sec-fetch-mode': 'cors',
  331. 'sec-fetch-site': 'same-origin'
  332. },
  333. formData: getCheckoutData(this.task.site, [variant]),
  334. // proxy: this.task.proxy,
  335. resolveWithFullResponse: true
  336. };
  337.  
  338. if (this.task.pooky === "on") {
  339. options["headers"]["cookie"] = `lastid=${msBefore}; ${parsedPooky}`
  340. }
  341.  
  342.  
  343. try {
  344.  
  345. console.log("Checking Out")
  346. await sleep(3)
  347. let response = await this.rp(options)
  348.  
  349. console.log(response.body)
  350.  
  351. if (response.status === 'failed') {
  352. console.log('Failed to checkout')
  353. } else if (response.status === 'outOfStock') {
  354. console.log("Item OOS")
  355. } else if (response.status === 'queued') {
  356. console.log('Queued...')
  357. console.log(response.slug)
  358. }
  359.  
  360.  
  361. } catch (err) {
  362. console.log(`Error checking out: ${err.message}`)
  363. return this.stopped = true;
  364. }
  365. }
  366. }
  367.  
  368. /*async checkSlug(slug) {
  369. try {
  370. const res = await this.rp(`https://www.supremenewyork.com/checkout/${slug}/status.json`)
  371. if (res.data.status === 'queued') {
  372. console.log('In queue.. Checking again in 1s')
  373. await sleep(1000)
  374. return this.checkStatus(slug)
  375. } else if (res.data.status === 'failed') {
  376. console.log(res.data)
  377. console.log('Failed to checkout')
  378.  
  379. } else if (res.data.status === "success") {
  380. console.log("Checkout Success")
  381. }
  382. } catch (err) {
  383. console.log("Error checking slug", err.message)
  384. }
  385. }*/
  386.  
  387. async getPooky(isCheckout) {
  388. let pookyUrl = (isCheckout) ? `${getPookyUrl(this.task.site)}&pookyuuid=${this.pookyString}` : getPookyUrl(this.task.site);
  389.  
  390. let options = {
  391. url: pookyUrl,
  392. method: 'get'
  393. };
  394.  
  395. console.log(options)
  396.  
  397. try {
  398. let response = await this.rp(options)
  399. console.log("pooky response", response)
  400. if (response["status"] === "successful") {
  401. if (!isCheckout)
  402. this.pookyString = response["cookie"][0].split("=")[1]
  403.  
  404. let pookyString = "";
  405. for (let cookie of response["cookie"]) {
  406. pookyString += `${cookie}; `
  407. }
  408. console.log("RETURNING POOKY STRING", pookyString)
  409. return pookyString;
  410. } else {
  411. return undefined;
  412. }
  413.  
  414. } catch (err) {
  415. console.log("Error getting pooky ", err.message)
  416. }
  417. }
  418.  
  419. }
  420.  
  421.  
  422. var array = {"category": "Accessories", "keywords": "+hanes,+socks", "color": "Red", "size": "N/A", "pooky": "on", "site": "SupremeUS", "timer": ""}
  423. var Supreme = new SupremeClient(array)
  424. Supreme.getItem()
Add Comment
Please, Sign In to add comment