diff --git a/package.json b/package.json index ada66c8..a154d6c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "microsoft-rewards-script", - "version": "1.0.0", + "version": "1.0.1", "description": "Automatically do tasks for Microsoft Rewards but in TS", "main": "index.js", "scripts": { diff --git a/src/Browser.ts b/src/Browser.ts index 7261479..d460d99 100644 --- a/src/Browser.ts +++ b/src/Browser.ts @@ -4,13 +4,15 @@ import StealthPlugin from 'puppeteer-extra-plugin-stealth' import { getUserAgent } from './util/UserAgent' import { loadSesion } from './BrowserFunc' +import { headless } from './config.json' + puppeteer.use(StealthPlugin()) -export async function Browser(email: string, headless = false) { +export async function Browser(email: string) { const userAgent = await getUserAgent(false) const browser = await puppeteer.launch({ - headless: headless, // Set to true for a headless browser + headless: headless, userDataDir: await loadSesion(email), args: [ '--no-sandbox', @@ -22,11 +24,11 @@ export async function Browser(email: string, headless = false) { return browser } -export async function mobileBrowser(email: string, headless = false) { +export async function mobileBrowser(email: string) { const userAgent = await getUserAgent(true) const browser = await puppeteer.launch({ - headless: headless, // Set to true for a headless browser, + headless: headless, userDataDir: await loadSesion(email), args: [ '--no-sandbox', diff --git a/src/BrowserFunc.ts b/src/BrowserFunc.ts index c30b9cf..03c35c8 100644 --- a/src/BrowserFunc.ts +++ b/src/BrowserFunc.ts @@ -3,7 +3,7 @@ import fs from 'fs' import path from 'path' import { baseURL, sessionPath } from './config.json' -import { wait } from './util/Utils' +import { getFormattedDate, wait } from './util/Utils' import { tryDismissAllMessages, tryDismissCookieBanner } from './BrowserUtil' import { log } from './util/Logger' @@ -13,7 +13,7 @@ import { QuizData } from './interface/QuizData' export async function goHome(page: Page): Promise { try { - const targetUrl = new URL(baseURL) + const dashboardURL = new URL(baseURL) await page.goto(baseURL) @@ -32,9 +32,9 @@ export async function goHome(page: Page): Promise { // Continue if element is not found } - const currentUrl = new URL(page.url()) + const currentURL = new URL(page.url()) - if (currentUrl.hostname !== targetUrl.hostname) { + if (currentURL.hostname !== dashboardURL.hostname) { await tryDismissAllMessages(page) await wait(2000) @@ -42,7 +42,7 @@ export async function goHome(page: Page): Promise { } await wait(5000) - log('MAIN', 'Visited homepage successfully') + log('GO-HOME', 'Visited homepage successfully') } } catch (error) { @@ -51,6 +51,16 @@ export async function goHome(page: Page): Promise { } export async function getDashboardData(page: Page): Promise { + const dashboardURL = new URL(baseURL) + const currentURL = new URL(page.url()) + + // Should never happen since tasks are opened in a new tab! + if (currentURL.hostname !== dashboardURL.hostname) { + log('DASHBOARD-DATA', 'Provided page did not equal dashboard page, redirecting to dashboard page') + await goHome(page) + } + + // Reload the page to get new data await page.reload({ waitUntil: 'networkidle2' }) const scriptContent = await page.evaluate(() => { @@ -60,7 +70,7 @@ export async function getDashboardData(page: Page): Promise { if (targetScript) { return targetScript.innerText } else { - throw new Error('Script containing dashboard data not found') + throw log('GET-DASHBOARD-DATA', 'Script containing dashboard data not found', 'error') } }) @@ -73,19 +83,13 @@ export async function getDashboardData(page: Page): Promise { if (match && match[1]) { return JSON.parse(match[1]) } else { - throw new Error('Dashboard data not found in the script') + throw log('GET-DASHBOARD-DATA', 'Dashboard data not found within script', 'error') } }, scriptContent) return dashboardData } -export async function getSearchPoints(page: Page): Promise { - const dashboardData = await getDashboardData(page) - - return dashboardData.userStatus.counters -} - export async function getQuizData(page: Page): Promise { const scriptContent = await page.evaluate(() => { const scripts = Array.from(document.querySelectorAll('script')) @@ -94,7 +98,7 @@ export async function getQuizData(page: Page): Promise { if (targetScript) { return targetScript.innerText } else { - throw new Error('Script containing quiz data not found') + throw log('GET-QUIZ-DATA', 'Script containing quiz data not found', 'error') } }) @@ -106,13 +110,48 @@ export async function getQuizData(page: Page): Promise { if (match && match[1]) { return JSON.parse(match[1]) } else { - throw new Error('Dashboard data not found in the script') + throw log('GET-QUIZ-DATA', 'Quiz data not found within script', 'error') } }, scriptContent) return quizData } +export async function getSearchPoints(page: Page): Promise { + const dashboardData = await getDashboardData(page) // Always fetch newest data + + return dashboardData.userStatus.counters +} + +export async function getEarnablePoints(data: DashboardData, page: null | Page = null): Promise { + // Fetch new data if page is provided + if (page) { + data = await getDashboardData(page) + } + + // These only include the points from tasks that the script can complete! + let totalEarnablePoints = 0 + + // Desktop Search Points + data.userStatus.counters.pcSearch.forEach(x => totalEarnablePoints += (x.pointProgressMax - x.pointProgress)) + + // Mobile Search Points + data.userStatus.counters.mobileSearch.forEach(x => totalEarnablePoints += (x.pointProgressMax - x.pointProgress)) + + // Daily Set + data.dailySetPromotions[getFormattedDate()]?.forEach(x => totalEarnablePoints += (x.pointProgressMax - x.pointProgress)) + + // More Promotions + data.morePromotions.forEach(x => { + // Only count points from supported activities + if (['quiz', 'urlreward'].includes(x.activityType)) { + totalEarnablePoints += (x.pointProgressMax - x.pointProgress) + } + }) + + return totalEarnablePoints +} + export async function loadSesion(email: string): Promise { const sessionDir = path.join(__dirname, sessionPath, email) diff --git a/src/config.json b/src/config.json index 1b7c003..ecbb7a7 100644 --- a/src/config.json +++ b/src/config.json @@ -1,4 +1,10 @@ { - "baseURL" : "https://rewards.bing.com", - "sessionPath": "sessions" + "baseURL": "https://rewards.bing.com", + "sessionPath": "sessions", + "headless": false, + "runOnZeroPoints": false, + "searches": { + "doMobile": true, + "doDesktop": true + } } \ No newline at end of file diff --git a/src/functions/activities/Quiz.ts b/src/functions/activities/Quiz.ts index c262656..a03e2b1 100644 --- a/src/functions/activities/Quiz.ts +++ b/src/functions/activities/Quiz.ts @@ -47,10 +47,12 @@ export async function doQuiz(page: Page, data: PromotionalItem | MorePromotion) } } + // Click the answers for (const answer of answers) { + await wait(2000) + // Click the answer on page await quizPage.click(answer) - await wait(1500) const refreshSuccess = await waitForQuizRefresh(quizPage) if (!refreshSuccess) { @@ -72,7 +74,7 @@ export async function doQuiz(page: Page, data: PromotionalItem | MorePromotion) if (dataOption === correctOption) { // Click the answer on page await quizPage.click(`#rqAnswerOption${i}`) - await wait(1500) + await wait(2000) const refreshSuccess = await waitForQuizRefresh(quizPage) if (!refreshSuccess) { @@ -88,6 +90,7 @@ export async function doQuiz(page: Page, data: PromotionalItem | MorePromotion) } // Done with + await wait(2000) await quizPage.close() log('QUIZ', 'Completed the quiz successfully') } catch (error) { diff --git a/src/functions/activities/Search.ts b/src/functions/activities/Search.ts index 352d50d..fb62454 100644 --- a/src/functions/activities/Search.ts +++ b/src/functions/activities/Search.ts @@ -2,7 +2,7 @@ import { Page } from 'puppeteer' import axios from 'axios' import { log } from '../../util/Logger' -import { shuffleArray, wait } from '../../util/Utils' +import { wait } from '../../util/Utils' import { getSearchPoints } from '../../BrowserFunc' import { DashboardData, DashboardImpression } from '../../interface/DashboardData' @@ -29,7 +29,8 @@ export async function doSearch(page: Page, data: DashboardData, mobile: boolean) } // Generate search queries - const googleSearchQueries = shuffleArray(await getGoogleTrends(locale, missingPoints)) + const googleSearchQueries = await getGoogleTrends(locale, missingPoints) + //const googleSearchQueries = shuffleArray(await getGoogleTrends(locale, missingPoints)) // Open a new tab const browser = page.browser() @@ -162,7 +163,7 @@ async function bingSearch(page: Page, searchPage: Page, query: string) { } async function getGoogleTrends(locale: string, queryCount: number): Promise { - const queryTerms: string[] = [] + let queryTerms: string[] = [] let i = 0 while (queryCount > queryTerms.length) { @@ -193,10 +194,7 @@ async function getGoogleTrends(locale: string, queryCount: number): Promise