-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathepic-games.js
189 lines (159 loc) · 7.07 KB
/
epic-games.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
const puppeteer = require('puppeteer') // Webscraping
const fs = require('fs') // For reading files
const { Webhook, MessageBuilder } = require('discord-webhook-node') // For discord
const colors = require('colors')
const date = require('date-and-time')
const config = require('./config.js')
if(config.enableWebhooks && config.webhooks.length == 0){ // send a warning msg if config.js isnt configured properly then quit
warn(`It seems like you dont have webhook configured! Please view config.js!`)
process.exit(this);
}
// Main function to get data from web & webhook sender
async function main(){
log("Opening Chrome")
const browser = process.platform === 'win32' ? await puppeteer.launch({headless:config.headless}) : await puppeteer.launch({args: ['--no-sandbox'],headless: true})
const page = await browser.newPage();
// CHECKS FOR UPDATES
log("Checking version with github version")
await page.goto('https://raw.githubusercontent.com/smashie420/Epic-Games-Today-Free-Day/master/version')
await page.waitForSelector('pre')
var versionNum = await page.$('pre')
let githubVersion = await page.evaluate(el => el.textContent, versionNum)
// Checks if the file 'version' exists
!fs.existsSync('version') ? fs.writeFileSync("version", githubVersion, 'utf8') : ""
if( parseFloat(githubVersion) > parseFloat(fs.readFileSync('version', 'utf-8'))){
warn(`${colors.red("OUT OF DATE!")} Get the lastest version here https://github.com/smashie420/Epic-Games-Today-Free-Day`)
}
// EPIC WEBSCRAPING
log("Going to Epic Games")
await page.goto('https://www.epicgames.com/store/en-US/free-games', {waitUntil:'load'});
await page.waitForSelector("div#dieselReactWrapper")
await autoScroll(page);
let data = await page.evaluate(()=>{
// Refrences to the cards below
// https://i.imgur.com/KcwVwRa.jpeg
let finalArr = []
// Scans each free card and scrapes data
var cards = document.querySelectorAll("[data-component='FreeOfferCard']")
for (var i = 0; i < cards.length; i++) {
// Finds 'free now' on the webpage and gets individual cards
cards[i].scrollIntoView();
gameName = cards[i].querySelectorAll("div > span")[1].innerText
gameDate = cards[i].querySelectorAll("div > span")[2].innerText
gameStatus = cards[i].querySelectorAll("div > span")[0].innerText
gameImage = cards[i].querySelector("img").src
gameLink = cards[i].querySelector('a').href
if (gameStatus != "FREE NOW"){
continue
}
finalArr.push({
name:gameName,
date: gameDate,
status: gameStatus,
image: gameImage,
link: gameLink
})
}
return finalArr
})
log("Got all data! Closing chrome!")
await browser.close()
// Add logic to check if game has been sent before or is in past games
data.forEach((gameData)=>{
// Checks if file exists, if not make one with an empty json array
if(!fs.existsSync('gamesSent.json')) {fs.writeFileSync('gamesSent.json', "[]")}
// Read JSON and convert to array
let pastGames = JSON.parse(fs.readFileSync("gamesSent.json"));
if(pastGames.find(gameName => gameName == gameData.name)){ // Checks if game is in gameSent.json if so dont send webhook
log(`${gameData.name} has already been sent!`)
return
}
pastGames.push(gameData.name)
fs.writeFileSync('gamesSent.json', JSON.stringify(pastGames)) // Appends the array with the updated list
log(`Found game! ${gameData.name}`)
// Webhook stuff
if(!config.enableWebhooks) return;
let webhooks = config.webhooks
webhooks.forEach(hook => {
log(`Sending '${gameData.name}' to https://discord.com/api/webhooks/...${hook.slice(-6)}`)
sendWebHook(hook, gameData)
});
})
if(!config.runOnce) getNextRun();
}
// Loop program
if(config.runOnce){
main();
}else{
main();
setInterval(async()=>{
main();
},1000 * config.delay)
}
// GENERAL UTILITY
async function writeLog(text){
if(fs.existsSync("game-logs.txt")){
fs.appendFile('game-logs.txt', "\n"+text, function (err) {
if (err) throw (err)
})
}else{
fs.writeFile('game-logs.txt', text, function (err) {
if (err) throw (err)
})
}
}
function log(msg){
let date_ob = new Date();
// YYYY-MM-DD HH:MM:SS format
let formattedTime = date_ob.getFullYear() + "-" + (date_ob.getMonth() + 1) + "-" + ('0'+date_ob.getDate()).slice(-2) + " " + ('0' + date_ob.getHours()).slice(-2) + ":" + ('0' + date_ob.getMinutes()).slice(-2) + ":" + ('0'+date_ob.getSeconds()).slice(-2) + " "
console.log(`${colors.cyan('[EPIC FREE GAMES]')} ${colors.magenta(formattedTime)} ${msg}`)
writeLog(`[EPIC FREE GAMES] ${formattedTime} ${msg}`)
}
function getNextRun(){
const timeNow = new Date();
const nextRun = date.addSeconds(timeNow,config.delay);
log(`Scheduled to run again at: ${nextRun}`)
}
function warn(msg){
console.log(`${colors.cyan('[EPIC FREE GAMES]')} ${colors.bgRed("WARNING!")} ${colors.yellow(msg)}`)
}
// Webhook Sender
function sendWebHook(hookUrl, gameData){
const hook = new Webhook(hookUrl);
hook.setUsername('Epic Games');
hook.setAvatar('https://d3bzyjrsc4233l.cloudfront.net/company_office/epicgames_logo.png');
const embed = new MessageBuilder()
.setTitle('Todays Free Game')
.setURL(`${gameData.link}`)
.setColor('#000000')
.setImage(gameData.image)
.addField('Name', `\`${gameData.name}\``, true)
.addField('Status', `\`${gameData.status}\``, true)
.addField('Date', `\`${gameData.date}\``, true)
.setFooter('Made by smashguns#6175', 'https://cdn.discordapp.com/attachments/718712847286403116/1091174736853205122/200x200_Highres_logo.png')
.setTimestamp();
hook.send(embed).catch(error =>{
if(error){
console.error(error)
}
})
}
// Puppeteer AutoScroller https://stackoverflow.com/questions/51529332/puppeteer-scroll-down-until-you-cant-anymore
// This is necessary, not scrolling will cause the embed to sometimes fail since the image returns base64
async function autoScroll(page){
await page.evaluate(async () => {
await new Promise((resolve) => {
var totalHeight = 0;
var distance = 500;
var timer = setInterval(() => {
var scrollHeight = document.body.scrollHeight;
window.scrollBy(0, distance);
totalHeight += distance;
if(totalHeight >= scrollHeight - window.innerHeight){
clearInterval(timer);
resolve();
}
}, 100);
});
});
}