mirror of
https://github.com/TheNetsky/Microsoft-Rewards-Script.git
synced 2026-01-18 05:53:57 +00:00
1.0
This commit is contained in:
54
src/functions/DailySet.ts
Normal file
54
src/functions/DailySet.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { Page } from 'puppeteer'
|
||||
import { DashboardData } from '../interface/DashboardData'
|
||||
import { doPoll } from './activities/Poll'
|
||||
import { getFormattedDate } from '../util/Utils'
|
||||
import { doQuiz } from './activities/Quiz'
|
||||
import { log } from '../util/Logger'
|
||||
import { doUrlReward } from './activities/UrlReward'
|
||||
|
||||
|
||||
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')
|
||||
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
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
log('DAILY-SET', 'Daily set items have been completed')
|
||||
}
|
||||
117
src/functions/Login.ts
Normal file
117
src/functions/Login.ts
Normal file
@@ -0,0 +1,117 @@
|
||||
import { Page } from 'puppeteer'
|
||||
import readline from 'readline'
|
||||
|
||||
const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout
|
||||
})
|
||||
|
||||
import { wait } from '../util/Utils'
|
||||
import { tryDismissAllMessages, tryDismissBingCookieBanner } from '../BrowserUtil'
|
||||
import { log } from '../util/Logger'
|
||||
|
||||
export async function login(page: Page, email: string, password: string) {
|
||||
|
||||
try {
|
||||
// Navigate to the Bing login page
|
||||
await page.goto('https://login.live.com/')
|
||||
|
||||
const isLoggedIn = await page.waitForSelector('html[data-role-name="MeePortal"]', { timeout: 5000 }).then(() => true).catch(() => false)
|
||||
|
||||
if (!isLoggedIn) {
|
||||
await page.waitForSelector('#loginHeader', { visible: true, timeout: 10_000 })
|
||||
|
||||
await execLogin(page, email, password)
|
||||
log('LOGIN', 'Logged into Microsoft successfully')
|
||||
} else {
|
||||
log('LOGIN', 'Already logged in')
|
||||
}
|
||||
|
||||
// Check if logged in to bing
|
||||
await checkBingLogin(page)
|
||||
|
||||
// We're done logging in
|
||||
log('LOGIN', 'Logged in successfully')
|
||||
|
||||
} catch (error) {
|
||||
log('LOGIN', 'An error occurred:' + error, 'error')
|
||||
}
|
||||
}
|
||||
|
||||
async function execLogin(page: Page, email: string, password: string) {
|
||||
await page.type('#i0116', email)
|
||||
await page.click('#idSIButton9')
|
||||
log('LOGIN', 'Email entered successfully')
|
||||
|
||||
try {
|
||||
await page.waitForSelector('#i0118', { visible: true, timeout: 2000 })
|
||||
await wait(2000)
|
||||
|
||||
await page.type('#i0118', password)
|
||||
await page.click('#idSIButton9')
|
||||
|
||||
} catch (error) {
|
||||
log('LOGIN', '2FA code required')
|
||||
|
||||
const code = await new Promise<string>((resolve) => {
|
||||
rl.question('Enter 2FA code:\n', (input) => {
|
||||
rl.close()
|
||||
resolve(input)
|
||||
})
|
||||
})
|
||||
|
||||
await page.type('input[name="otc"]', code)
|
||||
await page.keyboard.press('Enter')
|
||||
|
||||
} finally {
|
||||
log('LOGIN', 'Password entered successfully')
|
||||
}
|
||||
|
||||
const currentURL = new URL(page.url())
|
||||
|
||||
while (currentURL.pathname !== '/' || currentURL.hostname !== 'account.microsoft.com') {
|
||||
await tryDismissAllMessages(page)
|
||||
currentURL.href = page.url()
|
||||
}
|
||||
|
||||
// Wait for login to complete
|
||||
await page.waitForSelector('html[data-role-name="MeePortal"]', { timeout: 10_000 })
|
||||
}
|
||||
|
||||
async function checkBingLogin(page: Page): Promise<void> {
|
||||
try {
|
||||
log('LOGIN-BING', 'Verifying Bing login')
|
||||
await page.goto('https://www.bing.com/fd/auth/signin?action=interactive&provider=windows_live_id&return_url=https%3A%2F%2Fwww.bing.com%2F')
|
||||
|
||||
const maxIterations = 5
|
||||
|
||||
for (let iteration = 1; iteration <= maxIterations; iteration++) {
|
||||
const currentUrl = new URL(page.url())
|
||||
|
||||
if (currentUrl.hostname === 'www.bing.com' && currentUrl.pathname === '/') {
|
||||
await wait(3000)
|
||||
await tryDismissBingCookieBanner(page)
|
||||
|
||||
const loggedIn = await checkBingLoginStatus(page)
|
||||
if (loggedIn) {
|
||||
log('LOGIN-BING', 'Bing login verification passed!')
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
await wait(1000)
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
log('LOGIN-BING', 'An error occurred:' + error, 'error')
|
||||
}
|
||||
}
|
||||
|
||||
async function checkBingLoginStatus(page: Page): Promise<boolean> {
|
||||
try {
|
||||
await page.waitForSelector('#id_n', { timeout: 5000 })
|
||||
return true
|
||||
} catch (error) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
51
src/functions/MorePromotions.ts
Normal file
51
src/functions/MorePromotions.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import { Page } from 'puppeteer'
|
||||
import { DashboardData } from '../interface/DashboardData'
|
||||
import { doPoll } from './activities/Poll'
|
||||
import { doQuiz } from './activities/Quiz'
|
||||
import { log } from '../util/Logger'
|
||||
import { doUrlReward } from './activities/UrlReward'
|
||||
|
||||
|
||||
export async function doMorePromotions(page: Page, data: DashboardData) {
|
||||
const morePromotions = data.morePromotions
|
||||
|
||||
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) {
|
||||
|
||||
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
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
31
src/functions/activities/Poll.ts
Normal file
31
src/functions/activities/Poll.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { Page } from 'puppeteer'
|
||||
import { MorePromotion, PromotionalItem } from '../../interface/DashboardData'
|
||||
import { getLatestTab } from '../../BrowserUtil'
|
||||
import { log } from '../../util/Logger'
|
||||
import { wait } from '../../util/Utils'
|
||||
|
||||
export async function doPoll(page: Page, data: PromotionalItem | MorePromotion) {
|
||||
log('POLL', '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)
|
||||
|
||||
const pollPage = await getLatestTab(page)
|
||||
|
||||
const buttonId = `#btoption${Math.floor(Math.random() * 2)}`
|
||||
|
||||
await pollPage.waitForSelector(buttonId)
|
||||
await pollPage.click(buttonId)
|
||||
|
||||
await wait(2000)
|
||||
await pollPage.close()
|
||||
|
||||
log('POLL', 'Completed the poll successfully')
|
||||
} catch (error) {
|
||||
log('POLL', 'An error occurred:' + error, 'error')
|
||||
}
|
||||
}
|
||||
119
src/functions/activities/Quiz.ts
Normal file
119
src/functions/activities/Quiz.ts
Normal file
@@ -0,0 +1,119 @@
|
||||
import { Page } from 'puppeteer'
|
||||
import { MorePromotion, PromotionalItem } from '../../interface/DashboardData'
|
||||
import { getQuizData } from '../../BrowserFunc'
|
||||
import { wait } from '../../util/Utils'
|
||||
import { getLatestTab } from '../../BrowserUtil'
|
||||
import { log } from '../../util/Logger'
|
||||
|
||||
export async function doQuiz(page: Page, data: PromotionalItem | MorePromotion) {
|
||||
log('QUIZ', 'Trying to complete quiz')
|
||||
|
||||
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)
|
||||
|
||||
const quizPage = await getLatestTab(page)
|
||||
|
||||
// Check if the quiz has been started or not
|
||||
const quizNotStarted = await quizPage.waitForSelector('#rqStartQuiz', { visible: true, timeout: 3000 }).then(() => true).catch(() => false)
|
||||
if (quizNotStarted) {
|
||||
await quizPage.click('#rqStartQuiz')
|
||||
} else {
|
||||
log('QUIZ', 'Quiz has already been started, trying to finish it')
|
||||
}
|
||||
|
||||
await wait(2000)
|
||||
|
||||
const quizData = await getQuizData(quizPage)
|
||||
|
||||
const questionsRemaining = quizData.maxQuestions - quizData.CorrectlyAnsweredQuestionCount // Amount of questions remaining
|
||||
|
||||
// All questions
|
||||
for (let question = 0; question < questionsRemaining; question++) {
|
||||
|
||||
if (quizData.numberOfOptions === 8) {
|
||||
const answers: string[] = []
|
||||
|
||||
for (let i = 0; i < quizData.numberOfOptions; i++) {
|
||||
const answerSelector = await quizPage.waitForSelector(`#rqAnswerOption${i}`)
|
||||
const answerAttribute = await answerSelector?.evaluate(el => el.getAttribute('iscorrectoption'))
|
||||
await wait(500)
|
||||
|
||||
if (answerAttribute && answerAttribute.toLowerCase() === 'true') {
|
||||
answers.push(`#rqAnswerOption${i}`)
|
||||
}
|
||||
}
|
||||
|
||||
for (const answer of answers) {
|
||||
// Click the answer on page
|
||||
await quizPage.click(answer)
|
||||
await wait(1500)
|
||||
|
||||
const refreshSuccess = await waitForQuizRefresh(quizPage)
|
||||
if (!refreshSuccess) {
|
||||
await quizPage.close()
|
||||
log('QUIZ', 'An error occurred, refresh was unsuccessful', 'error')
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Other type quiz
|
||||
} else if ([2, 3, 4].includes(quizData.numberOfOptions)) {
|
||||
const correctOption = quizData.correctAnswer
|
||||
|
||||
for (let i = 0; i < quizData.numberOfOptions; i++) {
|
||||
|
||||
const answerSelector = await quizPage.waitForSelector(`#rqAnswerOption${i}`)
|
||||
const dataOption = await answerSelector?.evaluate(el => el.getAttribute('data-option'))
|
||||
|
||||
if (dataOption === correctOption) {
|
||||
// Click the answer on page
|
||||
await quizPage.click(`#rqAnswerOption${i}`)
|
||||
await wait(1500)
|
||||
|
||||
const refreshSuccess = await waitForQuizRefresh(quizPage)
|
||||
if (!refreshSuccess) {
|
||||
await quizPage.close()
|
||||
log('QUIZ', 'An error occurred, refresh was unsuccessful', 'error')
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Done with
|
||||
await quizPage.close()
|
||||
log('QUIZ', 'Completed the quiz successfully')
|
||||
} catch (error) {
|
||||
const quizPage = await getLatestTab(page)
|
||||
await quizPage.close()
|
||||
log('QUIZ', 'An error occurred:' + error, 'error')
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async function waitForQuizRefresh(page: Page) {
|
||||
try {
|
||||
await page.waitForSelector('#rqHeaderCredits', { timeout: 5000 })
|
||||
return true
|
||||
} catch (error) {
|
||||
log('QUIZ-REFRESH', 'An error occurred:' + error, 'error')
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
async function checkQuizCompleted(page: Page) {
|
||||
try {
|
||||
await page.waitForSelector('#quizCompleteContainer', { timeout: 1000 })
|
||||
return true
|
||||
} catch (error) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
checkQuizCompleted
|
||||
233
src/functions/activities/Search.ts
Normal file
233
src/functions/activities/Search.ts
Normal file
@@ -0,0 +1,233 @@
|
||||
import { Page } from 'puppeteer'
|
||||
import axios from 'axios'
|
||||
|
||||
import { log } from '../../util/Logger'
|
||||
import { shuffleArray, wait } from '../../util/Utils'
|
||||
import { getSearchPoints } from '../../BrowserFunc'
|
||||
|
||||
import { DashboardData, DashboardImpression } from '../../interface/DashboardData'
|
||||
import { GoogleTrends } from '../../interface/GoogleDailyTrends'
|
||||
|
||||
export async function doSearch(page: Page, data: DashboardData, mobile: boolean) {
|
||||
const locale = await page.evaluate(() => {
|
||||
return navigator.language
|
||||
})
|
||||
|
||||
log('SEARCH-BING', 'Starting bing searches')
|
||||
|
||||
const mobileData = data.userStatus.counters.mobileSearch[0] as DashboardImpression // Mobile searches
|
||||
const edgeData = data.userStatus.counters.pcSearch[1] as DashboardImpression // Edge searches
|
||||
const genericData = data.userStatus.counters.pcSearch[0] as DashboardImpression // Normal searches
|
||||
|
||||
let missingPoints = mobile ?
|
||||
(mobileData.pointProgressMax - mobileData.pointProgress) :
|
||||
(edgeData.pointProgressMax - edgeData.pointProgress) + (genericData.pointProgressMax - genericData.pointProgress)
|
||||
|
||||
if (missingPoints == 0) {
|
||||
log('SEARCH-BING', `Bing searches for ${mobile ? 'MOBILE' : 'DESKTOP'} have already been completed`)
|
||||
return
|
||||
}
|
||||
|
||||
// Generate search queries
|
||||
const googleSearchQueries = shuffleArray(await getGoogleTrends(locale, missingPoints))
|
||||
|
||||
// Open a new tab
|
||||
const browser = page.browser()
|
||||
const searchPage = await browser.newPage()
|
||||
|
||||
// Go to bing
|
||||
await searchPage.goto('https://bing.com')
|
||||
|
||||
let maxLoop = 0 // If the loop hits 20 this when not gaining any points, we're assuming it's stuck.
|
||||
|
||||
// Loop over Google search queries
|
||||
for (let i = 0; i < googleSearchQueries.length; i++) {
|
||||
const query = googleSearchQueries[i] as string
|
||||
|
||||
log('SEARCH-BING', `${missingPoints} Points Remaining | Query: ${query} | Mobile: ${mobile}`)
|
||||
|
||||
const newData = await bingSearch(page, searchPage, query)
|
||||
|
||||
const newMobileData = newData.mobileSearch[0] as DashboardImpression // Mobile searches
|
||||
const newEdgeData = newData.pcSearch[1] as DashboardImpression // Edge searches
|
||||
const newGenericData = newData.pcSearch[0] as DashboardImpression // Normal searches
|
||||
|
||||
const newMissingPoints = mobile ?
|
||||
(newMobileData.pointProgressMax - newMobileData.pointProgress) :
|
||||
(newEdgeData.pointProgressMax - newEdgeData.pointProgress) + (newGenericData.pointProgressMax - newGenericData.pointProgress)
|
||||
|
||||
// If the new point amount is the same as before
|
||||
if (newMissingPoints == missingPoints) {
|
||||
maxLoop++ // Add to max loop
|
||||
} else { // There has been a change in points
|
||||
maxLoop = 0 // Reset the loop
|
||||
}
|
||||
|
||||
missingPoints = newMissingPoints
|
||||
|
||||
if (missingPoints == 0) {
|
||||
break
|
||||
}
|
||||
|
||||
if (maxLoop > 20) {
|
||||
log('SEARCH-BING', 'Search didn\'t gain point for 20 iterations aborting searches', 'warn')
|
||||
maxLoop = 0 // Reset to 0 so we can retry with related searches below
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// If we still got remaining search queries, generate extra ones
|
||||
if (missingPoints > 0) {
|
||||
log('SEARCH-BING', `Search completed but we're missing ${missingPoints} points, generating extra searches`)
|
||||
|
||||
let i = 0
|
||||
while (missingPoints > 0) {
|
||||
const query = googleSearchQueries[i++] as string
|
||||
|
||||
// Get related search terms to the Google search queries
|
||||
const relatedTerms = await getRelatedTerms(query)
|
||||
if (relatedTerms.length > 3) {
|
||||
// Search for the first 2 related terms
|
||||
for (const term of relatedTerms.slice(1, 3)) {
|
||||
log('SEARCH-BING-EXTRA', `${missingPoints} Points Remaining | Query: ${term} | Mobile: ${mobile}`)
|
||||
const newData = await bingSearch(page, searchPage, query)
|
||||
|
||||
const newMobileData = newData.mobileSearch[0] as DashboardImpression // Mobile searches
|
||||
const newEdgeData = newData.pcSearch[1] as DashboardImpression // Edge searches
|
||||
const newGenericData = newData.pcSearch[0] as DashboardImpression // Normal searches
|
||||
|
||||
const newMissingPoints = mobile ?
|
||||
(newMobileData.pointProgressMax - newMobileData.pointProgress) :
|
||||
(newEdgeData.pointProgressMax - newEdgeData.pointProgress) + (newGenericData.pointProgressMax - newGenericData.pointProgress)
|
||||
|
||||
// If the new point amount is the same as before
|
||||
if (newMissingPoints == missingPoints) {
|
||||
maxLoop++ // Add to max loop
|
||||
} else { // There has been a change in points
|
||||
maxLoop = 0 // Reset the loop
|
||||
}
|
||||
|
||||
missingPoints = newMissingPoints
|
||||
|
||||
// If we satisfied the searches
|
||||
if (missingPoints == 0) {
|
||||
break
|
||||
}
|
||||
|
||||
// Try 5 more times
|
||||
if (maxLoop > 5) {
|
||||
log('SEARCH-BING-EXTRA', 'Search didn\'t gain point for 5 iterations aborting searches', 'warn')
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log('SEARCH-BING', 'Completed searches')
|
||||
}
|
||||
|
||||
async function bingSearch(page: Page, searchPage: Page, query: string) {
|
||||
// Try a max of 5 times
|
||||
for (let i = 0; i < 5; i++) {
|
||||
try {
|
||||
const searchBar = '#sb_form_q'
|
||||
await searchPage.waitForSelector(searchBar, { timeout: 3000 })
|
||||
await searchPage.click(searchBar) // Focus on the textarea
|
||||
await wait(500)
|
||||
await searchPage.keyboard.down('Control')
|
||||
await searchPage.keyboard.press('A')
|
||||
await searchPage.keyboard.press('Backspace') // Delete the selected text
|
||||
await searchPage.keyboard.up('Control')
|
||||
await searchPage.keyboard.type(query)
|
||||
await searchPage.keyboard.press('Enter')
|
||||
|
||||
await wait(Math.floor(Math.random() * (20_000 - 10_000) + 1) + 10_000)
|
||||
|
||||
return await getSearchPoints(page)
|
||||
|
||||
} catch (error) {
|
||||
if (i === 5) {
|
||||
log('SEARCH-BING', 'Failed after 5 retries... An error occurred:' + error, 'error')
|
||||
return await getSearchPoints(page)
|
||||
}
|
||||
|
||||
log('SEARCH-BING', 'Search failed, retrying...', 'warn')
|
||||
await wait(4000)
|
||||
}
|
||||
}
|
||||
|
||||
log('SEARCH-BING', 'Search failed after 5 retries, ending', 'error')
|
||||
return await getSearchPoints(page)
|
||||
}
|
||||
|
||||
async function getGoogleTrends(locale: string, queryCount: number): Promise<string[]> {
|
||||
const queryTerms: string[] = []
|
||||
let i = 0
|
||||
|
||||
while (queryCount > queryTerms.length) {
|
||||
i += 1
|
||||
const date = new Date()
|
||||
date.setDate(date.getDate() - i)
|
||||
const formattedDate = formatDate(date)
|
||||
|
||||
try {
|
||||
const request = {
|
||||
url: `https://trends.google.com/trends/api/dailytrends?geo=US&hl=en&ed=${formattedDate}&ns=15`,
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}
|
||||
|
||||
const response = await axios(request)
|
||||
|
||||
const data: GoogleTrends = JSON.parse((await response.data).slice(5))
|
||||
|
||||
for (const topic of data.default.trendingSearchesDays[0]?.trendingSearches ?? []) {
|
||||
queryTerms.push(topic.title.query.toLowerCase())
|
||||
|
||||
for (const relatedTopic of topic.relatedQueries) {
|
||||
queryTerms.push(relatedTopic.query.toLowerCase())
|
||||
}
|
||||
}
|
||||
|
||||
// Deduplicate the search terms
|
||||
const uniqueSearchTerms = Array.from(new Set(queryTerms))
|
||||
queryTerms.length = 0
|
||||
queryTerms.push(...uniqueSearchTerms)
|
||||
|
||||
} catch (error) {
|
||||
log('SEARCH-GOOGLE-TRENDS', 'An error occurred:' + error, 'error')
|
||||
}
|
||||
}
|
||||
|
||||
return queryTerms.slice(0, queryCount)
|
||||
}
|
||||
|
||||
async function getRelatedTerms(term: string): Promise<string[]> {
|
||||
try {
|
||||
const request = {
|
||||
url: `https://api.bing.com/osjson.aspx?query=${term}`,
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}
|
||||
|
||||
const response = await axios(request)
|
||||
|
||||
return response.data[1] as string[]
|
||||
} catch (error) {
|
||||
log('SEARCH-BING-RELTATED', 'An error occurred:' + error, 'error')
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
function formatDate(date: Date): string {
|
||||
const year = date.getFullYear()
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0')
|
||||
const day = String(date.getDate()).padStart(2, '0')
|
||||
|
||||
return `${year}${month}${day}`
|
||||
}
|
||||
26
src/functions/activities/UrlReward.ts
Normal file
26
src/functions/activities/UrlReward.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { Page } from 'puppeteer'
|
||||
import { getLatestTab } from '../../BrowserUtil'
|
||||
import { log } from '../../util/Logger'
|
||||
import { PromotionalItem, MorePromotion } from '../../interface/DashboardData'
|
||||
|
||||
|
||||
export async function doUrlReward(page: Page, data: PromotionalItem | MorePromotion) {
|
||||
log('URL-REWARD', 'Trying to complete UrlReward')
|
||||
|
||||
try {
|
||||
const selector = `[data-bi-id="${data.offerId}"]`
|
||||
|
||||
// Wait for page to load and click to load the url reward in a new tab
|
||||
await page.waitForSelector(selector, { timeout: 5000 })
|
||||
await page.click(selector)
|
||||
|
||||
// After waiting, close the page
|
||||
const visitPage = await getLatestTab(page)
|
||||
await visitPage.close()
|
||||
|
||||
log('URL-REWARD', 'Completed the UrlReward successfully')
|
||||
} catch (error) {
|
||||
log('URL-REWARD', 'An error occurred:' + error, 'error')
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user