mirror of
https://github.com/TheNetsky/Microsoft-Rewards-Script.git
synced 2026-01-11 10:56:17 +00:00
1.0.3
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "microsoft-rewards-script",
|
"name": "microsoft-rewards-script",
|
||||||
"version": "1.0.2",
|
"version": "1.0.3",
|
||||||
"description": "Automatically do tasks for Microsoft Rewards but in TS",
|
"description": "Automatically do tasks for Microsoft Rewards but in TS",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { log } from './util/Logger'
|
|||||||
import { Counters, DashboardData } from './interface/DashboardData'
|
import { Counters, DashboardData } from './interface/DashboardData'
|
||||||
import { QuizData } from './interface/QuizData'
|
import { QuizData } from './interface/QuizData'
|
||||||
|
|
||||||
export async function goHome(page: Page): Promise<void> {
|
export async function goHome(page: Page): Promise<boolean> {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const dashboardURL = new URL(baseURL)
|
const dashboardURL = new URL(baseURL)
|
||||||
@@ -23,6 +23,13 @@ export async function goHome(page: Page): Promise<void> {
|
|||||||
await wait(3000)
|
await wait(3000)
|
||||||
await tryDismissCookieBanner(page)
|
await tryDismissCookieBanner(page)
|
||||||
|
|
||||||
|
// Check if account is suspended
|
||||||
|
const isSuspended = await page.waitForSelector('#suspendedAccountHeader', { visible: true, timeout: 3000 }).then(() => true).catch(() => false)
|
||||||
|
if (isSuspended) {
|
||||||
|
log('GO-HOME', 'This account is suspended!')
|
||||||
|
throw new Error('Account has been suspended!')
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// If activities are found, exit the loop
|
// If activities are found, exit the loop
|
||||||
await page.waitForSelector('#more-activities', { timeout: 1000 })
|
await page.waitForSelector('#more-activities', { timeout: 1000 })
|
||||||
@@ -47,7 +54,10 @@ export async function goHome(page: Page): Promise<void> {
|
|||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('An error occurred:', error)
|
console.error('An error occurred:', error)
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getDashboardData(page: Page): Promise<DashboardData> {
|
export async function getDashboardData(page: Page): Promise<DashboardData> {
|
||||||
|
|||||||
@@ -5,10 +5,12 @@
|
|||||||
"runOnZeroPoints": false,
|
"runOnZeroPoints": false,
|
||||||
"searches": {
|
"searches": {
|
||||||
"doMobile": true,
|
"doMobile": true,
|
||||||
"doDesktop": true
|
"doDesktop": true,
|
||||||
|
"scrollRandomResults": true,
|
||||||
|
"clickRandomResults": true
|
||||||
},
|
},
|
||||||
"webhook": {
|
"webhook": {
|
||||||
"enabled": true,
|
"enabled": false,
|
||||||
"url": ""
|
"url": ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -84,6 +84,7 @@ export async function doQuiz(page: Page, data: PromotionalItem | MorePromotion)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
await wait(2000)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,11 +2,14 @@ import { Page } from 'puppeteer'
|
|||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
import { log } from '../../util/Logger'
|
import { log } from '../../util/Logger'
|
||||||
import { wait } from '../../util/Utils'
|
import { shuffleArray, wait } from '../../util/Utils'
|
||||||
import { getSearchPoints } from '../../BrowserFunc'
|
import { getSearchPoints } from '../../BrowserFunc'
|
||||||
|
|
||||||
|
import { searches } from '../../config.json'
|
||||||
|
|
||||||
import { DashboardData, DashboardImpression } from '../../interface/DashboardData'
|
import { DashboardData, DashboardImpression } from '../../interface/DashboardData'
|
||||||
import { GoogleTrends } from '../../interface/GoogleDailyTrends'
|
import { GoogleTrends } from '../../interface/GoogleDailyTrends'
|
||||||
|
import { GoogleSearch } from '../../interface/Search'
|
||||||
|
|
||||||
export async function doSearch(page: Page, data: DashboardData, mobile: boolean) {
|
export async function doSearch(page: Page, data: DashboardData, mobile: boolean) {
|
||||||
const locale = await page.evaluate(() => {
|
const locale = await page.evaluate(() => {
|
||||||
@@ -29,8 +32,11 @@ export async function doSearch(page: Page, data: DashboardData, mobile: boolean)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate search queries
|
// Generate search queries
|
||||||
const googleSearchQueries = await getGoogleTrends(locale, missingPoints)
|
let googleSearchQueries = await getGoogleTrends(locale, missingPoints) as GoogleSearch[]
|
||||||
//const googleSearchQueries = shuffleArray(await getGoogleTrends(locale, missingPoints))
|
googleSearchQueries = shuffleArray(googleSearchQueries)
|
||||||
|
|
||||||
|
// Deduplicate the search terms
|
||||||
|
googleSearchQueries = [...new Set(googleSearchQueries)]
|
||||||
|
|
||||||
// Open a new tab
|
// Open a new tab
|
||||||
const browser = page.browser()
|
const browser = page.browser()
|
||||||
@@ -41,9 +47,12 @@ export async function doSearch(page: Page, data: DashboardData, mobile: boolean)
|
|||||||
|
|
||||||
let maxLoop = 0 // If the loop hits 20 this when not gaining any points, we're assuming it's stuck.
|
let maxLoop = 0 // If the loop hits 20 this when not gaining any points, we're assuming it's stuck.
|
||||||
|
|
||||||
|
const queries: string[] = []
|
||||||
|
googleSearchQueries.forEach(x => queries.push(x.topic, ...x.related))
|
||||||
|
|
||||||
// Loop over Google search queries
|
// Loop over Google search queries
|
||||||
for (let i = 0; i < googleSearchQueries.length; i++) {
|
for (let i = 0; i < queries.length; i++) {
|
||||||
const query = googleSearchQueries[i] as string
|
const query = queries[i] as string
|
||||||
|
|
||||||
log('SEARCH-BING', `${missingPoints} Points Remaining | Query: ${query} | Mobile: ${mobile}`)
|
log('SEARCH-BING', `${missingPoints} Points Remaining | Query: ${query} | Mobile: ${mobile}`)
|
||||||
|
|
||||||
@@ -83,15 +92,15 @@ export async function doSearch(page: Page, data: DashboardData, mobile: boolean)
|
|||||||
|
|
||||||
let i = 0
|
let i = 0
|
||||||
while (missingPoints > 0) {
|
while (missingPoints > 0) {
|
||||||
const query = googleSearchQueries[i++] as string
|
const query = googleSearchQueries[i++] as GoogleSearch
|
||||||
|
|
||||||
// Get related search terms to the Google search queries
|
// Get related search terms to the Google search queries
|
||||||
const relatedTerms = await getRelatedTerms(query)
|
const relatedTerms = await getRelatedTerms(query?.topic)
|
||||||
if (relatedTerms.length > 3) {
|
if (relatedTerms.length > 3) {
|
||||||
// Search for the first 2 related terms
|
// Search for the first 2 related terms
|
||||||
for (const term of relatedTerms.slice(1, 3)) {
|
for (const term of relatedTerms.slice(1, 3)) {
|
||||||
log('SEARCH-BING-EXTRA', `${missingPoints} Points Remaining | Query: ${term} | Mobile: ${mobile}`)
|
log('SEARCH-BING-EXTRA', `${missingPoints} Points Remaining | Query: ${term} | Mobile: ${mobile}`)
|
||||||
const newData = await bingSearch(page, searchPage, query)
|
const newData = await bingSearch(page, searchPage, query.topic)
|
||||||
|
|
||||||
const newMobileData = newData.mobileSearch[0] as DashboardImpression // Mobile searches
|
const newMobileData = newData.mobileSearch[0] as DashboardImpression // Mobile searches
|
||||||
const newEdgeData = newData.pcSearch[1] as DashboardImpression // Edge searches
|
const newEdgeData = newData.pcSearch[1] as DashboardImpression // Edge searches
|
||||||
@@ -138,11 +147,21 @@ async function bingSearch(page: Page, searchPage: Page, query: string) {
|
|||||||
await wait(500)
|
await wait(500)
|
||||||
await searchPage.keyboard.down('Control')
|
await searchPage.keyboard.down('Control')
|
||||||
await searchPage.keyboard.press('A')
|
await searchPage.keyboard.press('A')
|
||||||
await searchPage.keyboard.press('Backspace') // Delete the selected text
|
await searchPage.keyboard.press('Backspace')
|
||||||
await searchPage.keyboard.up('Control')
|
await searchPage.keyboard.up('Control')
|
||||||
await searchPage.keyboard.type(query)
|
await searchPage.keyboard.type(query)
|
||||||
await searchPage.keyboard.press('Enter')
|
await searchPage.keyboard.press('Enter')
|
||||||
|
|
||||||
|
if (searches.scrollRandomResults) {
|
||||||
|
await wait(2000)
|
||||||
|
await randomScroll(searchPage)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (searches.clickRandomResults) {
|
||||||
|
await wait(2000)
|
||||||
|
await clickRandomLink(searchPage)
|
||||||
|
}
|
||||||
|
|
||||||
await wait(Math.floor(Math.random() * (20_000 - 10_000) + 1) + 10_000)
|
await wait(Math.floor(Math.random() * (20_000 - 10_000) + 1) + 10_000)
|
||||||
|
|
||||||
return await getSearchPoints(page)
|
return await getSearchPoints(page)
|
||||||
@@ -162,8 +181,8 @@ async function bingSearch(page: Page, searchPage: Page, query: string) {
|
|||||||
return await getSearchPoints(page)
|
return await getSearchPoints(page)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getGoogleTrends(locale: string, queryCount: number): Promise<string[]> {
|
async function getGoogleTrends(locale: string, queryCount: number): Promise<GoogleSearch[]> {
|
||||||
let queryTerms: string[] = []
|
const queryTerms: GoogleSearch[] = []
|
||||||
let i = 0
|
let i = 0
|
||||||
|
|
||||||
while (queryCount > queryTerms.length) {
|
while (queryCount > queryTerms.length) {
|
||||||
@@ -186,21 +205,18 @@ async function getGoogleTrends(locale: string, queryCount: number): Promise<stri
|
|||||||
const data: GoogleTrends = JSON.parse((await response.data).slice(5))
|
const data: GoogleTrends = JSON.parse((await response.data).slice(5))
|
||||||
|
|
||||||
for (const topic of data.default.trendingSearchesDays[0]?.trendingSearches ?? []) {
|
for (const topic of data.default.trendingSearchesDays[0]?.trendingSearches ?? []) {
|
||||||
queryTerms.push(topic.title.query.toLowerCase())
|
queryTerms.push({
|
||||||
|
topic: topic.title.query.toLowerCase(),
|
||||||
for (const relatedTopic of topic.relatedQueries) {
|
related: topic.relatedQueries.map(x => x.query.toLocaleLowerCase())
|
||||||
queryTerms.push(relatedTopic.query.toLowerCase())
|
})
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deduplicate the search terms
|
|
||||||
queryTerms = [...new Set(queryTerms)]
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log('SEARCH-GOOGLE-TRENDS', 'An error occurred:' + error, 'error')
|
log('SEARCH-GOOGLE-TRENDS', 'An error occurred:' + error, 'error')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return queryTerms.slice(0, queryCount)
|
return queryTerms
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getRelatedTerms(term: string): Promise<string[]> {
|
async function getRelatedTerms(term: string): Promise<string[]> {
|
||||||
@@ -228,4 +244,20 @@ function formatDate(date: Date): string {
|
|||||||
const day = String(date.getDate()).padStart(2, '0')
|
const day = String(date.getDate()).padStart(2, '0')
|
||||||
|
|
||||||
return `${year}${month}${day}`
|
return `${year}${month}${day}`
|
||||||
|
}
|
||||||
|
|
||||||
|
async function randomScroll(page: Page) {
|
||||||
|
const randomNumber = Math.random() * (50 - 5 + 1) + 5
|
||||||
|
|
||||||
|
// Press the arrow down key to scroll
|
||||||
|
for (let i = 0; i < randomNumber; i++) {
|
||||||
|
await page.keyboard.press('ArrowDown')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function clickRandomLink(page: Page) {
|
||||||
|
await page.click('#b_results h2')
|
||||||
|
|
||||||
|
await wait(3000)
|
||||||
|
await page.goBack()
|
||||||
}
|
}
|
||||||
@@ -51,7 +51,10 @@ async function Desktop(account: Account) {
|
|||||||
// Login into MS Rewards
|
// Login into MS Rewards
|
||||||
await login(page, account.email, account.password)
|
await login(page, account.email, account.password)
|
||||||
|
|
||||||
await goHome(page)
|
const wentHome = await goHome(page)
|
||||||
|
if (!wentHome) {
|
||||||
|
throw log('MAIN', 'Unable to get dashboard page', 'error')
|
||||||
|
}
|
||||||
|
|
||||||
const data = await getDashboardData(page)
|
const data = await getDashboardData(page)
|
||||||
log('MAIN-POINTS', `Current point count: ${data.userStatus.availablePoints}`)
|
log('MAIN-POINTS', `Current point count: ${data.userStatus.availablePoints}`)
|
||||||
@@ -100,7 +103,7 @@ async function Mobile(account: Account) {
|
|||||||
if (searches.doMobile) {
|
if (searches.doMobile) {
|
||||||
await doSearch(page, data, true)
|
await doSearch(page, data, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch new points
|
// Fetch new points
|
||||||
const earnablePoints = await getEarnablePoints(data, page)
|
const earnablePoints = await getEarnablePoints(data, page)
|
||||||
// If the new earnable is 0, means we got all the points, else retract
|
// If the new earnable is 0, means we got all the points, else retract
|
||||||
|
|||||||
4
src/interface/Search.ts
Normal file
4
src/interface/Search.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
export interface GoogleSearch {
|
||||||
|
topic: string;
|
||||||
|
related: string[];
|
||||||
|
}
|
||||||
@@ -13,7 +13,8 @@ export function getFormattedDate(ms = Date.now()) {
|
|||||||
return `${month}/${day}/${year}`
|
return `${month}/${day}/${year}`
|
||||||
}
|
}
|
||||||
|
|
||||||
export function shuffleArray(array: string[]): string[] {
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
export function shuffleArray(array: any[]): any[] {
|
||||||
const shuffledArray = array.slice()
|
const shuffledArray = array.slice()
|
||||||
|
|
||||||
shuffledArray.sort(() => Math.random() - 0.5)
|
shuffledArray.sort(() => Math.random() - 0.5)
|
||||||
|
|||||||
Reference in New Issue
Block a user