-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtask.js
More file actions
319 lines (278 loc) · 10.9 KB
/
Copy pathtask.js
File metadata and controls
319 lines (278 loc) · 10.9 KB
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
const { workerData, parentPort } = require('worker_threads');
const puppeteer = require('puppeteer-extra');
const { createCursor } = require("ghost-cursor");
const stealthPlugin = require('puppeteer-extra-plugin-stealth');
puppeteer.use(stealthPlugin());
const fs = require('fs/promises');
//discord.js
const { Client, GatewayIntentBits, EmbedBuilder} = require('discord.js');
const { get } = require('http');
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
client.login(process.env.DISCORD_BOT_TOKEN);
//Closes browsers before terminating the task with facebook-delete command
parentPort.on('message', async (message) => {
if(message.action === 'closeBrowsers') {
await endTask();
}
});
let logChannel;
let mainChannel;
client.on('ready', async () => {
try {
mainChannel = client.channels.cache.get(workerData.channel);
if(mainChannel == null){
mainChannel = await client.channels.fetch(workerData.channel);
}
logChannel = client.channels.cache.get('1091532766522376243');
if(logChannel == null){
logChannel = await client.channels.fetch('1091532766522376243');
}
} catch (error) {
errorMessage('Error fetching channel', error);
}
//Start up
await start();
});
// Add cleanup logic on uncaught exception
process.on('uncaughtException', async (err) => {
await logChannel.send('Uncaught Exception in ' + workerData.name + ': ' + err);
});
// Add cleanup logic on unhandled promise rejection
process.on('unhandledRejection', async (reason, promise) => {
await logChannel.send('Unhandled Rejection in ' + workerData.name + ':' + reason);
});
//error message send function
const errorMessage = (message, error) => {
try {
console.log(workerData.name + ': ' + message + ': ' + error);
logChannel.send(workerData.name + ': ' + message + ': ' + error);//.stack
} catch (error) {
logChannel.send('error with error message??? Who tf knows...' + error)
}
}
const endTask = async () => {
try {
await logChannel.send("Close Browsers");
if(mainBrowser != null){
await mainPage.close();
await mainBrowser.close();
mainBrowser = null;
}
parentPort.postMessage("Success");
} catch (error) {
errorMessage("Error closing browser: ", error);
}
}
//randomize time till post check
const getRandomInterval = () => { //!Come back to this and change times
try {
const minNumber = 300000; //5 mins
const maxNumber = 600000; //10 mins
const power = 1.5;
const random = Math.random();
const range = maxNumber - minNumber;
const number = minNumber + Math.pow(random, power) * range;
return Math.round(number);
} catch (error) {
errorMessage('error getting random interval', error);
}
}
const getProxy = async () => {
}
//send content of the page to discord
const logPageContent = async (page) => {
try{
//html
const htmlContent = await page.content();
const { Readable } = require('stream');
const htmlStream = Readable.from([htmlContent]);
await logChannel.send({
files: [
{
attachment: htmlStream,
name: 'website.html',
},
],
});
//png
await page.screenshot({ path: 'screenshot.png' });
await logChannel.send({
files: ['screenshot.png'],
});
await fs.unlink('screenshot.png');
}catch(error){
errorMessage('error login content: ', error);
}
}
let platforms = ['Macintosh; Intel Mac OS X 10_15_7', 'X11; Linux x86_64', 'Windows NT 10.0; Win64; x64']
let startError = false; //stops script on error
let mainBrowser;
let mainPage;
let listingStorage;
let isInitiation = true;
let proxy;
const start = async () => {
try{
proxy = await getProxy();
//initialize the static isp proxy page
mainBrowser = await puppeteer.launch({
headless: 'new',
args: ['--no-sandbox', `--proxy-server=${proxy}`],
timeout: 60000
});
let pages = await mainBrowser.pages();
mainPage = pages[0];
//change the viewport
mainPage.setViewport({ width: 1366, height: 768 });
//change http headers
let UAPlatform = platforms[Math.floor(Math.random() * 2)];
mainPage.setUserAgent(`Mozilla/5.0 (${UAPlatform}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36`);
mainPage.setExtraHTTPHeaders({
'Sec-Ch-Ua': 'Not.A/Brand";v="8", "Chromium";v="121", "Google Chrome";v="121',
'SEC-CH-UA-ARCH': '"x86"',
'Sec-Ch-Ua-Full-Version': "121.0.6167.185",
'SEC-CH-UA-MOBILE': '?0',
'Sec-Ch-Ua-Platform': `"${UAPlatform}"`,
'SEC-CH-UA-PLATFORM-VERSION': '15.0.0',
'Referer': 'https://www.facebook.com/login'
});
//network shit
mainPage.on('response', async response => {
try {
//detect redirection
if ([300, 301, 302, 303, 307, 308].includes(response.status())) {
const redirectURL = response.headers()['location'];
if(await redirectURL.split('?')[0] != (workerData.link).split('?')[0]){
console.log(`Redirected to: ${redirectURL}`);
logChannel.send(`${workerData.name} redirected to: ${redirectURL}`);
startError = true;
}
}
}catch (error) {
errorMessage("Error with handling network response", error);
}
});
await mainPage.setRequestInterception(true);
mainPage.on('request', async request => {
const resource = request.resourceType();
if(resource != 'document'){
request.abort();
}else{
request.continue();
}
});
//use cookie to set distance if task is for offerup
if(workerData.platform == 'Offerup'){
await mainPage.setCookies(...[{
"domain": "offerup.com",
"hostOnly": true,
"httpOnly": false,
"name": "ou.location",
"path": "/",
"sameSite": "strict",
"secure": false,
"session": true,
"storeId": null,
"value": `{%22%2C%22zipCode%22:%22${workerData.zipcode}%22%2C%22source%22:%22zipcode%22}`
}])
}
//go to the search page
try {
await mainPage.goto(workerData.link, { waitUntil: 'domcontentloaded', timeout: 50000});//networkidle2
} catch (error) {await logChannel.send("Timeout on going to link")}
if(isInitiation){
listingStorage = [await getListing(1), await getListing(2), await getListing(3), await getListing(4)];
interval();
console.log("Main Storage: " + listingStorage);
isInitiation = false;
}
}catch(error){
await logPageContent(mainPage);
errorMessage('error with start', error);
}
}
const getListing = async (num) => {
try{
if(startError == false){
if(workerData.platform == "Ebay"){
postObj = await itemPage.evaluate(() => {
(document.querySelector(`.srp-results > :nth-child(${num}) a`).href).split('?')[0]
})
}else if(workerData.platform == "Craigslist"){
postObj = await itemPage.evaluate(() => {
document.querySelector(`.cl-results-page > ol > :nth-child(${num}) a`).href
})
}else if(workerData.platform == "Offerup"){
postObj = await itemPage.evaluate(() => {
document.querySelector(`#__next > div.jss7 > div.jss9 > main > div.jss2 > div > div > div > div.jss311 > div > :nth-child(${num + 1})`).href
})
}
}
}catch (error){
errorMessage('Error with setting listing storage', error);
}
}
//the meat and cheese
function interval() {
setTimeout(async () => {
//start up a new page with fresh proxy and get listings
await start();
let newPost = await getListing(1);
let postNum = 1;
//newPost is actually new
while(!listingStorage.includes(newPost) && postNum <= 20 && newPost != null){
console.log("New Post: " + newPost + " post num: " + postNum);
//collect post data
let postObj;
try {
//Create item page
let itemPage = await mainBrowser.newPage();
await itemPage.goto(newPost, { waitUntil: 'domcontentloaded', timeout: 50000});
//set postObj
if(workerData.platform == "Ebay"){
return await mainPage.evaluate((num) => {
}, num);
}else if(workerData.platform == "Craigslist"){
return await mainPage.evaluate((num) => {
}, num);
}else if(workerData.platform == "Offerup"){
return await mainPage.evaluate((num) => {
}, num);
}
} catch (error) {
errorMessage('Error collecting post data', error);
}
//check for listing deleted and collection error
if(postObj != null){
//manage description
if(postObj?.description != null){
if(postObj?.description.length > 700){
postObj.description = (postObj?.description)?.substring(0, 700) + '...';
}
}
try{
mainChannel.send({ content: "$" + postObj.price + " - " + postObj.title, embeds: [new EmbedBuilder()
.setColor(0x0099FF)
.setTitle("$" + postObj.price + " - " + postObj.title)
.setURL(newPost)
.setAuthor({ name: workerData.name })
.setDescription(postObj.description)
.addFields({ name: postObj.date, value: postObj.shipping })
.setImage(postObj.img)
.setTimestamp(new Date())
]});
}catch(error){
errorMessage('Error with item notification', error);
}
}
//Update newPost
postNum++;
newPost = await getListing(1);
//ping the user
await mainChannel.send("New Notifications @everyone");
}
//set the main listing storage
listingStorage = [await getListing(1), await getListing(2), await getListing(3), await getListing(4)];
interval();
}, getRandomInterval());
}