This commit is contained in:
TheNetsky
2023-10-08 13:55:36 +02:00
parent e982e6e25f
commit 03ba5129c6
16 changed files with 419 additions and 345 deletions

View File

@@ -1,69 +0,0 @@
import { Page } from 'puppeteer'
import { doPoll } from './activities/Poll'
import { doQuiz } from './activities/Quiz'
import { doUrlReward } from './activities/UrlReward'
import { doThisOrThat } from './activities/ThisOrThat'
import { getFormattedDate, wait } from '../util/Utils'
import { log } from '../util/Logger'
import { DashboardData } from '../interface/DashboardData'
export async function doDailySet(page: Page, data: DashboardData) {
const todayData = data.dailySetPromotions[getFormattedDate()]
const activitiesUncompleted = todayData?.filter(x => !x.complete) ?? []
if (!activitiesUncompleted.length) {
log('DAILY-SET', 'All daily set items have already been completed')
return
}
for (const activity of activitiesUncompleted) {
log('DAILY-SET', 'Started doing daily set items')
// If activity does not give points, skip
if (activity.pointProgressMax <= 0) {
continue
}
switch (activity.promotionType) {
// Quiz (Poll/Quiz)
case 'quiz':
switch (activity.pointProgressMax) {
// Poll (Usually 10 points)
case 10:
log('ACTIVITY', 'Found daily activity type: Poll')
await doPoll(page, activity)
break
// This Or That Quiz (Usually 50 points)
case 50:
log('ACTIVITY', 'Found daily activity type: ThisOrThat')
await doThisOrThat(page, activity)
break
// Quizzes are usually 30-40 points
default:
log('ACTIVITY', 'Found daily activity type: Quiz')
await doQuiz(page, activity)
break
}
break
// UrlReward (Visit)
case 'urlreward':
log('ACTIVITY', 'Found daily activity type: UrlReward')
await doUrlReward(page, activity)
break
default:
break
}
await wait(1500)
}
log('DAILY-SET', 'Daily set items have been completed')
}

View File

@@ -1,70 +0,0 @@
import { Page } from 'puppeteer'
import { doPoll } from './activities/Poll'
import { doQuiz } from './activities/Quiz'
import { doUrlReward } from './activities/UrlReward'
import { doThisOrThat } from './activities/ThisOrThat'
import { wait } from '../util/Utils'
import { log } from '../util/Logger'
import { DashboardData, MorePromotion } from '../interface/DashboardData'
export async function doMorePromotions(page: Page, data: DashboardData) {
const morePromotions = data.morePromotions
// Check if there is a promotional item
if (data.promotionalItem) { // Convert and add the promotional item to the array
morePromotions.push(data.promotionalItem as unknown as MorePromotion)
}
const activitiesUncompleted = morePromotions?.filter(x => !x.complete) ?? []
if (!activitiesUncompleted.length) {
log('MORE-PROMOTIONS', 'All more promotion items have already been completed')
return
}
for (const activity of activitiesUncompleted) {
// If activity does not give points, skip
if (activity.pointProgressMax <= 0) {
continue
}
switch (activity.promotionType) {
// Quiz (Poll/Quiz)
case 'quiz':
switch (activity.pointProgressMax) {
// Poll (Usually 10 points)
case 10:
log('ACTIVITY', 'Found promotion activity type: Poll')
await doPoll(page, activity)
break
// This Or That Quiz (Usually 50 points)
case 50:
log('ACTIVITY', 'Found daily activity type: ThisOrThat')
await doThisOrThat(page, activity)
break
// Quizzes are usually 30-40 points
default:
log('ACTIVITY', 'Found promotion activity type: Quiz')
await doQuiz(page, activity)
break
}
break
// UrlReward (Visit)
case 'urlreward':
log('ACTIVITY', 'Found promotion activity type: UrlReward')
await doUrlReward(page, activity)
break
default:
break
}
await wait(1500)
}
}

View File

@@ -1,72 +0,0 @@
import { Page } from 'puppeteer'
import { doPoll } from './activities/Poll'
import { doQuiz } from './activities/Quiz'
import { doUrlReward } from './activities/UrlReward'
import { doThisOrThat } from './activities/ThisOrThat'
import { wait } from '../util/Utils'
import { log } from '../util/Logger'
import { DashboardData } from '../interface/DashboardData'
export async function doPunchCard(page: Page, data: DashboardData) {
const punchCardsUncompleted = data.punchCards?.filter(x => !x.parentPromotion.complete) ?? [] // filter out the uncompleted punch cards
if (!punchCardsUncompleted.length) {
log('PUNCH-CARD', 'All punch cards have already been completed')
return
}
// Todo
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const activitiesUncompleted: any = ''
for (const activity of activitiesUncompleted) {
log('PUNCH-CARD', 'Started doing daily set items')
// If activity does not give points, skip
if (activity.pointProgressMax <= 0) {
continue
}
switch (activity.promotionType) {
// Quiz (Poll/Quiz)
case 'quiz':
switch (activity.pointProgressMax) {
// Poll (Usually 10 points)
case 10:
log('ACTIVITY', 'Found daily activity type: Poll')
await doPoll(page, activity)
break
// This Or That Quiz (Usually 50 points)
case 50:
log('ACTIVITY', 'Found daily activity type: ThisOrThat')
await doThisOrThat(page, activity)
break
// Quizzes are usually 30-40 points
default:
log('ACTIVITY', 'Found daily activity type: Quiz')
await doQuiz(page, activity)
break
}
break
// UrlReward (Visit)
case 'urlreward':
log('ACTIVITY', 'Found daily activity type: UrlReward')
await doUrlReward(page, activity)
break
default:
break
}
await wait(1500)
}
log('PUNCH-CARD', 'Punch card items have been completed')
}

211
src/functions/Workers.ts Normal file
View File

@@ -0,0 +1,211 @@
import { Page } from 'puppeteer'
import { doPoll } from './activities/Poll'
import { doQuiz } from './activities/Quiz'
import { doUrlReward } from './activities/UrlReward'
import { doThisOrThat } from './activities/ThisOrThat'
import { doABC } from './activities/ABC'
import { getFormattedDate, wait } from '../util/Utils'
import { log } from '../util/Logger'
import { DashboardData, MorePromotion } from '../interface/DashboardData'
// Daily Set
export async function doDailySet(page: Page, data: DashboardData) {
const todayData = data.dailySetPromotions[getFormattedDate()]
const activitiesUncompleted = todayData?.filter(x => !x.complete) ?? []
if (!activitiesUncompleted.length) {
log('DAILY-SET', 'All daily set items have already been completed')
return
}
for (const activity of activitiesUncompleted) {
log('DAILY-SET', 'Started doing daily set items')
// If activity does not give points, skip
if (activity.pointProgressMax <= 0) {
continue
}
switch (activity.promotionType) {
// Quiz (Poll, Quiz or ABC)
case 'quiz':
switch (activity.pointProgressMax) {
// Poll or ABC (Usually 10 points)
case 10:
// Normal poll
if (activity.destinationUrl.toLowerCase().includes('pollscenarioid')) {
log('ACTIVITY', 'Found daily activity type: Poll')
await doPoll(page, activity)
} else { // ABC
log('ACTIVITY', 'Found daily activity type: ABC')
await doABC(page, activity)
}
break
// This Or That Quiz (Usually 50 points)
case 50:
log('ACTIVITY', 'Found daily activity type: ThisOrThat')
await doThisOrThat(page, activity)
break
// Quizzes are usually 30-40 points
default:
log('ACTIVITY', 'Found daily activity type: Quiz')
await doQuiz(page, activity)
break
}
break
// UrlReward (Visit)
case 'urlreward':
log('ACTIVITY', 'Found daily activity type: UrlReward')
await doUrlReward(page, activity)
break
default:
break
}
await wait(1500)
}
log('DAILY-SET', 'Daily set items have been completed')
}
// Punch Card
export async function doPunchCard(page: Page, data: DashboardData) {
const punchCardsUncompleted = data.punchCards?.filter(x => !x.parentPromotion.complete) ?? [] // Only return uncompleted punch cards
if (!punchCardsUncompleted.length) {
log('PUNCH-CARD', 'All punch cards have already been completed')
return
}
for (const promotion of punchCardsUncompleted) {
const activities = promotion.childPromotions.filter(x => !x.complete) // Only return uncompleted activities
for (const activity of activities) {
log('PUNCH-CARD', 'Started doing daily set items')
// If activity does not give points, skip
if (activity.pointProgressMax <= 0) {
continue
}
switch (activity.promotionType) {
// Quiz (Poll, Quiz or ABC)
case 'quiz':
switch (activity.pointProgressMax) {
// Poll or ABC (Usually 10 points)
case 10:
// Normal poll
if (activity.destinationUrl.toLowerCase().includes('pollscenarioid')) {
log('ACTIVITY', 'Found daily activity type: Poll')
await doPoll(page, activity)
} else { // ABC
log('ACTIVITY', 'Found daily activity type: ABC')
await doABC(page, activity)
}
break
// This Or That Quiz (Usually 50 points)
case 50:
log('ACTIVITY', 'Found daily activity type: ThisOrThat')
await doThisOrThat(page, activity)
break
// Quizzes are usually 30-40 points
default:
log('ACTIVITY', 'Found daily activity type: Quiz')
await doQuiz(page, activity)
break
}
break
// UrlReward (Visit)
case 'urlreward':
log('ACTIVITY', 'Found daily activity type: UrlReward')
await doUrlReward(page, activity)
break
default:
break
}
await wait(1500)
}
}
log('PUNCH-CARD', 'Punch card items have been completed')
}
// More Promotions
export async function doMorePromotions(page: Page, data: DashboardData) {
const morePromotions = data.morePromotions
// Check if there is a promotional item
if (data.promotionalItem) { // Convert and add the promotional item to the array
morePromotions.push(data.promotionalItem as unknown as MorePromotion)
}
const activitiesUncompleted = morePromotions?.filter(x => !x.complete) ?? []
if (!activitiesUncompleted.length) {
log('MORE-PROMOTIONS', 'All more promotion items have already been completed')
return
}
for (const activity of activitiesUncompleted) {
// If activity does not give points, skip
if (activity.pointProgressMax <= 0) {
continue
}
switch (activity.promotionType) {
// Quiz (Poll, Quiz or ABC)
case 'quiz':
switch (activity.pointProgressMax) {
// Poll or ABC (Usually 10 points)
case 10:
// Normal poll
if (activity.destinationUrl.toLowerCase().includes('pollscenarioid')) {
log('ACTIVITY', 'Found daily activity type: Poll')
await doPoll(page, activity)
} else { // ABC
log('ACTIVITY', 'Found daily activity type: ABC')
await doABC(page, activity)
}
break
// This Or That Quiz (Usually 50 points)
case 50:
log('ACTIVITY', 'Found daily activity type: ThisOrThat')
await doThisOrThat(page, activity)
break
// Quizzes are usually 30-40 points
default:
log('ACTIVITY', 'Found promotion activity type: Quiz')
await doQuiz(page, activity)
break
}
break
// UrlReward (Visit)
case 'urlreward':
log('ACTIVITY', 'Found promotion activity type: UrlReward')
await doUrlReward(page, activity)
break
default:
break
}
await wait(1500)
}
}

View File

@@ -0,0 +1,54 @@
import { Page } from 'puppeteer'
import { refreshCheerio } from '../../browser/BrowserFunc'
import { getLatestTab } from '../../browser/BrowserUtil'
import { log } from '../../util/Logger'
import { randomNumber, wait } from '../../util/Utils'
import { MorePromotion, PromotionalItem } from '../../interface/DashboardData'
export async function doABC(page: Page, data: PromotionalItem | MorePromotion) {
log('ABC', 'Trying to complete poll')
try {
const selector = `[data-bi-id="${data.offerId}"]`
// Wait for page to load and click to load the quiz in a new tab
await page.waitForSelector(selector, { timeout: 5000 })
await page.click(selector)
let abcPage = await getLatestTab(page)
await wait(2000)
let $ = await refreshCheerio(abcPage)
while (!$('span.rw_icon').length) {
await abcPage.waitForSelector('.wk_OptionClickClass', { visible: true, timeout: 5000 })
const answers = $('.wk_OptionClickClass')
const answer = answers[randomNumber(0, 2)]?.attribs['id']
await abcPage.waitForSelector(`#${answer}`, { visible: true, timeout: 5000 })
await wait(2000)
await abcPage.click(`#${answer}`) // Click answer
await wait(4000)
await abcPage.waitForSelector('div.wk_button', { visible: true, timeout: 5000 })
await abcPage.click('div.wk_button') // Click next question button
abcPage = await getLatestTab(abcPage)
$ = await refreshCheerio(abcPage)
await wait(1000)
}
await wait(4000)
await abcPage.close()
log('ABC', 'Completed the ABC successfully')
} catch (error) {
const abcPage = await getLatestTab(page)
await abcPage.close()
log('ABC', 'An error occurred:' + error, 'error')
}
}

View File

@@ -22,10 +22,11 @@ export async function doPoll(page: Page, data: PromotionalItem | MorePromotion)
await pollPage.waitForNetworkIdle({ timeout: 5000 })
await pollPage.waitForSelector(buttonId, { visible: true, timeout: 5000 })
await wait(2000)
await pollPage.click(buttonId)
await wait(2000)
await wait(4000)
await pollPage.close()
log('POLL', 'Completed the poll successfully')

View File

@@ -19,6 +19,7 @@ export async function doQuiz(page: Page, data: PromotionalItem | MorePromotion)
const quizPage = await getLatestTab(page)
await quizPage.waitForNetworkIdle({ timeout: 5000 })
await wait(2000)
// Check if the quiz has been started or not
const quizNotStarted = await quizPage.waitForSelector('#rqStartQuiz', { visible: true, timeout: 3000 }).then(() => true).catch(() => false)

View File

@@ -263,41 +263,57 @@ async function randomScroll(page: Page) {
async function clickRandomLink(page: Page, mobile: boolean) {
try {
const searchListingURL = new URL(page.url()) // Get page info before clicking
mobile
await page.click('#b_results .b_algo h2').catch(() => { }) // Since we don't really care if it did it or not
await wait(3000)
const newTab = await getLatestTab(page) // Will get current tab if no new one is created
let lastTab = await getLatestTab(page) // Will get current tab if no new one is created
await lastTab.waitForNetworkIdle() // Wait for page to load
// Check if the tab is closed or not
if (!newTab.isClosed()) {
const newTabURL = new URL(newTab.url()) // Get new tab info
if (!lastTab.isClosed()) {
let lastTabURL = new URL(lastTab.url()) // Get new tab info
// Check if the URL is different from the original one
if (newTabURL.href !== searchListingURL.href) {
// Mobile is always same tab
if (mobile) {
await page.goBack()
while (lastTabURL.href !== searchListingURL.href) {
// If hostname is still bing, (Bing images/news etc)
if (lastTabURL.hostname == searchListingURL.hostname) {
await lastTab.goBack()
lastTab = await getLatestTab(page) // Get last opened tab
lastTabURL = new URL(lastTab.url())
const currentURL = new URL(page.url())
// If "goBack" didn't return to search listing (due to redirects)
if (currentURL.hostname !== searchListingURL.hostname) {
await page.goto(searchListingURL.href)
if (lastTabURL.hostname !== searchListingURL.hostname) {
await lastTab.goto(searchListingURL.href)
}
// Still on bing, go back (news/images pages on bing search)
} else if (newTabURL.hostname == searchListingURL.hostname) {
await page.goBack()
break
} else { // No longer on bing, likely opened a new tab, close this tab
lastTab = await getLatestTab(page) // Get last opened tab
lastTabURL = new URL(lastTab.url())
const currentURL = new URL(page.url())
// If "goBack" didn't return to search listing (due to redirects)
if (currentURL.hostname !== searchListingURL.hostname) {
await page.goto(searchListingURL.href)
const tabs = await (page.browser()).pages() // Get all tabs open
// If the browser has more than 3 tabs open, it has opened a new one, we need to close this one.
if (tabs.length > 3) {
await lastTab.close()
} else {
await lastTab.goBack()
lastTab = await getLatestTab(page) // Get last opened tab
lastTabURL = new URL(lastTab.url())
// If "goBack" didn't return to search listing (due to redirects)
if (lastTabURL.hostname !== searchListingURL.hostname) {
await lastTab.goto(searchListingURL.href)
}
}
// No longer on bing, likely opened a new tab, close this tab
} else {
await newTab.close()
break
}
}
}

View File

@@ -19,6 +19,7 @@ export async function doThisOrThat(page: Page, data: PromotionalItem | MorePromo
const thisorthatPage = await getLatestTab(page)
await thisorthatPage.waitForNetworkIdle({ timeout: 5000 })
await wait(2000)
// Check if the quiz has been started or not
const quizNotStarted = await thisorthatPage.waitForSelector('#rqStartQuiz', { visible: true, timeout: 3000 }).then(() => true).catch(() => false)

View File

@@ -17,7 +17,7 @@ export async function doUrlReward(page: Page, data: PromotionalItem | MorePromot
// After waiting, close the page
const visitPage = await getLatestTab(page)
await visitPage.waitForNetworkIdle({ timeout: 5000 })
await visitPage.waitForNetworkIdle({ timeout: 10_000 })
await visitPage.close()
log('URL-REWARD', 'Completed the UrlReward successfully')