-
Notifications
You must be signed in to change notification settings - Fork 0
/
ylarequestbot.js
331 lines (288 loc) · 12.8 KB
/
ylarequestbot.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
const puppeteer = require('puppeteer-extra')
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
const fetch = require('node-fetch');
const localChrome = require('chrome-location');
const express = require('express');
const cors = require('cors')
const bodyParser = require('body-parser');
const runningTasks = new Map();
puppeteer.use(StealthPlugin());
let productLinkparameter = '';
const app = express();
app.use(cors());
app.use(bodyParser.json());
app.listen(8080, () => console.log("app is running"));
app.post('/api/start', (req, res) => {
let { link } = req.body;
link = link.trim();
if (!link) {
return res.status(400).json({ error: 'Link are required fields.' });
}
res.json({ "message": "Form Submitted" });
productLinkparameter = link;
run();
});
app.post('/api/stop', (req, res) => {
const { id } = req.body;
// Find the task with the given ID
const task = runningTasks.get(id);
if (task) {
// Assuming 'task' is a reference to a Puppeteer Page or Browser object
task.browser.close().then(() => {
console.log(`Task ${id} has been stopped.`);
runningTasks.delete(id); // Remove task from the running tasks map
res.json({ message: 'Task stopped successfully.' });
}).catch(error => {
console.error(`Failed to stop task ${id}: `, error);
res.status(500).json({ error: 'Failed to stop task.' });
});
} else {
res.status(404).json({ error: 'Task not found.' });
}
});
async function run() {
const browser = await puppeteer.launch({
headless: false, executablePath: localChrome, args: [
'--start-maximized',
'--window-size=1920,1080',
]
});
const page = await browser.newPage();
// Store a reference to the browser using the task ID, so you can close it later
const taskId = Date.now(); // Generate a unique ID for the task
runningTasks.set(taskId, { browser, page });
console.log("Navigating to this product: " + productLinkparameter);
await page.goto(productLinkparameter);
await addToCartRequest(page, productLinkparameter);
const cartResponse = await cartRequest(page, productLinkparameter);
const checkoutPageUrl = getCheckoutPageUrl(cartResponse);
if (checkoutPageUrl) {
try {
await page.goto(checkoutPageUrl);
} catch (error) {
console.error("The launching of the checkout page was unsuccessful: ", error);
}
} else {
console.log("Checkout URL was not found or is invalid.");
}
await checkoutProduct(page, productLinkparameter);
// After the task is done, don't forget to remove it from the runningTasks map
runningTasks.delete(taskId);
}
function getCheckoutPageUrl(cartRequestResponse) {
const actionStr = 'action="';
const start = cartRequestResponse.indexOf(actionStr);
if (start === -1) {
console.log("Could not find checkout page URL.");
return "";
}
const startUrl = start + actionStr.length;
const endUrl = cartRequestResponse.indexOf('"', startUrl);
if (endUrl === -1) {
console.log("Could not find the end of the checkout page URL.");
return "";
}
const checkoutUrlSuffix = cartRequestResponse.substring(startUrl, endUrl);
return "https://www.youngla.com" + checkoutUrlSuffix;
}
async function cartRequest(page, productUrl) {
const cookies = await page.cookies();
let cookieString = "";
for (let i = 0; i < cookies.length; i++) {
let fragment = "";
if (i != (cookies.length - 1)) {
fragment = cookies[i].name + "=" + cookies[i].value + "; ";
}
else {
fragment = cookies[i].name + "=" + cookies[i].value;
}
cookieString = cookieString + fragment;
}
const cartRequestOptions = {
"headers": {
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"accept-language": "en-US,en;q=0.9",
"cache-control": "max-age=0",
"content-type": "application/x-www-form-urlencoded",
"sec-ch-ua": "\"Not_A Brand\";v=\"8\", \"Chromium\";v=\"120\", \"Google Chrome\";v=\"120\"",
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "\"macOS\"",
"sec-fetch-dest": "document",
"sec-fetch-mode": "navigate",
"sec-fetch-site": "same-origin",
"sec-fetch-user": "?1",
"upgrade-insecure-requests": "1",
"cookie": cookieString,
"Referer": productUrl,
"Referrer-Policy": "strict-origin-when-cross-origin"
},
"body": "attributes%5Bcollection_mobile_items_per_row%5D=&attributes%5Bcollection_desktop_items_per_row%5D=&updates%5B%5D=1&checkout=",
"method": "POST"
};
const cartResponse = await page.evaluate(async (options) => {
try {
const response = await fetch("https://www.youngla.com/cart", options);
if (!response.ok) throw new Error(`Cart request error! Status: ${response.status}`);
return response.headers.get("content-type")?.includes("application/json") ? response.json() : response.text();
} catch (error) {
console.error("Cart Request Error: ", error);
return null;
}
}, cartRequestOptions);
return cartResponse;
}
async function addToCartRequest(page, productUrl) {
// Extract the product variant IDs from the JSON content within the script tag
const productVariantIds = await page.evaluate(() => {
const scriptElement = document.querySelector('script[data-product-json]');
if (scriptElement) {
const productData = JSON.parse(scriptElement.innerHTML);
if (productData && productData.product && productData.product.variants) {
return productData.product.variants.map(variant => variant.id);
}
}
return [];
});
// Uncomment below to see different items and there variant IDs
// if (productVariantIds.length > 0) {
// console.log('Product Variant IDs:', productVariantIds);
// } else {
// console.log('No product variant IDs found');
// }
const productColors = await page.evaluate(() => {
const scriptElement = document.querySelector('script[data-product-json]');
if (scriptElement) {
const productData = JSON.parse(scriptElement.innerHTML);
if (productData && productData.product && productData.product.variants) {
return productData.product.variants.map(variant => variant.title);
}
}
return [];
});
// Uncomment below to see different items and there variant colors / sizes
// if (productColors.length > 0) {
// console.log('Product Color and sizes:', productColors);
// } else {
// console.log('No product of that color and size found');
// }
const sectionIdElement = await page.waitForSelector("input[name='section-id']");
const sectionID = await page.evaluate(sectionIdElement => sectionIdElement.value, sectionIdElement);
const productIdElement = await page.waitForSelector("input[name='product-id']");
const productID = await page.evaluate(productIdElement => productIdElement.value, productIdElement);
const id = productVariantIds[0];
const color = productColors[0].substring(0, productColors[0].indexOf('/')).trim();
const size = productColors[0].substring(productColors[0].indexOf('/ ') + 1).trim();
const cookies = await page.cookies();
let cookieString = "";
for (let i = 0; i < cookies.length; i++) {
let fragment = "";
if (i != (cookies.length - 1)) {
fragment = cookies[i].name + "=" + cookies[i].value + "; ";
}
else {
fragment = cookies[i].name + "=" + cookies[i].value;
}
cookieString = cookieString + fragment;
}
const body = JSON.stringify({
"form_type": "product",
"utf8": "✓",
"option-0": color,
"option-1": size,
"id": id.toString(),
"product-id": productID.toString(),
"section-id": sectionID
});
const addRequestOptions = {
"headers": {
"accept": "*/*",
"accept-language": "en-US,en;q=0.9",
"content-type": "application/json",
"sec-ch-ua": "\"Chromium\";v=\"122\", \" Not A;Brand\";v=\"99\", \"Google Chrome\";v=\"122\"",
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "\"Mac OS X\"",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin",
"x-requested-with": "XMLHttpRequest",
"cookie": cookieString,
"Referer": productUrl,
"Referrer-Policy": "strict-origin-when-cross-origin"
},
"body": body,
"method": "POST"
};
const addRequestResponse = await page.evaluate(async (options) => {
try {
const response = await fetch("https://www.youngla.com/cart/add.js", options);
return response.ok ? response.json() : Promise.reject(`Error: ${response.statusText}`);
} catch (error) {
return `Failed to add item to cart: ${error}`;
}
}, addRequestOptions);
//console.log('Add to Cart Response:', addRequestResponse);
return;
}
async function checkoutProduct(page) {
// Enter your Info here and uncommment anything if needed
await page.evaluate(() => {
document.getElementById('checkout_email').value = "thonmaker344@gmail.com"
document.getElementById('checkout_shipping_address_first_name').value = "Sedrick"
document.getElementById('checkout_shipping_address_last_name').value = "Will"
document.getElementById('checkout_shipping_address_address1').value = "940 Blanda Valleys Apt. 478"
//document.getElementById('checkout_shipping_address_address2').value = "AddressLine2"
document.getElementById('checkout_shipping_address_city').value = "Lindshire"
document.getElementById('checkout_shipping_address_province').value = "MO"; // Select State (XX form) Ex. IN
document.getElementById('checkout_shipping_address_zip').value = "63013";
document.getElementById('checkout_shipping_address_phone').value = "2029182132";
})
// apply discount code
await page.waitForTimeout(1000);
await page.evaluate(() => {
document.getElementById('checkout_reduction_code').value = 'youngla15'
document.querySelectorAll('button[id="checkout_submit"]')[0].click()
})
await page.waitForTimeout(1000);
await page.evaluate(() => document.getElementById('continue_button').click());
await page.waitForTimeout(1000);
await page.evaluate(() => document.getElementById('btn-proceed-address').click());
// continue to estimate shipping date
await page.waitForSelector("#continue_button")
await page.evaluate(() => document.getElementById('continue_button').click());
await payment(page, productLinkparameter);
}
async function payment(page, productLinkparameter) {
// Enter your card info here
await page.waitForSelector("iframe[title='Field container for: Card number']")
await page.waitForTimeout(1000)
let iframe = await page.$("iframe[title='Field container for: Card number']")
let iframeElement = await iframe.contentFrame()
await iframeElement.type("input[id='number']", '5529960000869293')
iframe = await page.$("iframe[title='Field container for: Name on card']")
iframeElement = await iframe.contentFrame()
await iframeElement.type("input[id='name']", 'Aiden Robinson')
iframe = await page.$("iframe[title='Field container for: Expiration date (MM / YY)']")
iframeElement = await iframe.contentFrame()
await iframeElement.type("input[id='expiry']", '07/25')
iframe = await page.$("iframe[title='Field container for: Security code']")
iframeElement = await iframe.contentFrame()
await iframeElement.type("input[id='verification_value']", '909')
await page.waitForTimeout(1000)
await page.evaluate(() => document.getElementById('continue_button').click()); // last step
console.log("All set your order for " + productLinkparameter + " was placed!!")
}
//run();
// const linksToRun = [
// "https://www.youngla.com/products/4075",
// "https://www.youngla.com/products/401-essential-jacked-tees-23",
// "https://www.youngla.com/products/233-loose-printed-joggers",
// "https://www.youngla.com/products/465-compression-tee"
// ];
// const runPromises = linksToRun.map(productUrl => run(productUrl));
// Promise.all(runPromises)
// .then(() => {
// console.log("All instances completed successfully.");
// })
// .catch(error => {
// console.error("An error occurred:", error);
// });