This commit is contained in:
TheNetsky
2023-10-19 22:09:05 +02:00
parent 2366a3dd7f
commit e195f973cd
15 changed files with 81 additions and 34 deletions

View File

@@ -1,10 +1,22 @@
[
{
"email": "email_1",
"password": "password_1"
"password": "password_1",
"proxy": {
"url": "",
"port": 0,
"username": "",
"password": ""
}
},
{
"email": "email_2",
"password": "password_2"
"password": "password_2",
"proxy": {
"url": "",
"port": 0,
"username": "",
"password": ""
}
}
]

View File

@@ -1,16 +1,18 @@
import puppeteer from 'puppeteer-extra'
import StealthPlugin from 'puppeteer-extra-plugin-stealth'
import stealthPlugin from 'puppeteer-extra-plugin-stealth'
import { getUserAgent } from '../util/UserAgent'
import { loadSesion } from './BrowserFunc'
import { AccountProxy } from '../interface/Account'
import { headless } from '../config.json'
puppeteer.use(StealthPlugin())
puppeteer.use(stealthPlugin())
class Browser {
async createBrowser(email: string, isMobile: boolean) {
async createBrowser(email: string, proxy: AccountProxy, isMobile: boolean) {
const userAgent = await getUserAgent(isMobile)
const browser = await puppeteer.launch({
@@ -21,7 +23,8 @@ class Browser {
'--mute-audio',
'--disable-setuid-sandbox',
`--user-agent=${userAgent.userAgent}`,
isMobile ? '--window-size=568,1024' : ''
isMobile ? '--window-size=568,1024' : '',
proxy.url ? `--proxy-server=${proxy.url}:${proxy.port}` : ''
]
})

View File

@@ -1,7 +1,7 @@
import { Page } from 'puppeteer'
import fs from 'fs'
import path from 'path'
import { load } from 'cheerio'
import { CheerioAPI, load } from 'cheerio'
import { tryDismissAllMessages, tryDismissCookieBanner } from './BrowserUtil'
import { getFormattedDate, wait } from './../util/Utils'
@@ -200,7 +200,7 @@ export async function loadSesion(email: string): Promise<string> {
}
}
export async function waitForQuizRefresh(page: Page) {
export async function waitForQuizRefresh(page: Page): Promise<boolean> {
try {
await page.waitForSelector('#rqHeaderCredits', { visible: true, timeout: 5000 })
await wait(2000)
@@ -212,7 +212,7 @@ export async function waitForQuizRefresh(page: Page) {
}
}
export async function checkQuizCompleted(page: Page) {
export async function checkQuizCompleted(page: Page): Promise<boolean> {
try {
await page.waitForSelector('#quizCompleteContainer', { visible: true, timeout: 1000 })
await wait(2000)
@@ -223,14 +223,14 @@ export async function checkQuizCompleted(page: Page) {
}
}
export async function refreshCheerio(page: Page) {
export async function refreshCheerio(page: Page): Promise<CheerioAPI> {
const html = await page.content()
const $ = load(html)
return $
}
export async function getPunchCardActivity(page: Page, activity: PromotionalItem | MorePromotion) {
export async function getPunchCardActivity(page: Page, activity: PromotionalItem | MorePromotion): Promise<string> {
let selector = ''
try {
const html = await page.content()

View File

@@ -62,7 +62,7 @@ export async function tryDismissBingCookieBanner(page: Page): Promise<void> {
}
}
export async function getLatestTab(page: Page) {
export async function getLatestTab(page: Page): Promise<Page> {
try {
await wait(500)

View File

@@ -2,7 +2,7 @@
"baseURL": "https://rewards.bing.com",
"sessionPath": "sessions",
"headless": false,
"runOnZeroPoints": false,
"runOnZeroPoints": true,
"clusters": 1,
"workers": {
"doDailySet": true,
@@ -12,6 +12,7 @@
"doMobileSearch": true
},
"searchSettings": {
"useGeoLocaleQueries": false,
"scrollRandomResults": true,
"clickRandomResults": true
},

View File

@@ -157,13 +157,14 @@ async function solveActivities(page: Page, activities: PromotionalItem[] | MoreP
await doUrlReward(activityPage)
break
// Misc
// Misc, Usually UrlReward Type
default:
log('ACTIVITY', `Found activity type: "Misc" title: "${activity.title}"`)
await doUrlReward(activityPage)
break
}
// Cooldown
await wait(1500)
} catch (error) {
log('ACTIVITY', 'An error occurred:' + error, 'error')

View File

@@ -13,10 +13,6 @@ import { GoogleTrends } from '../../interface/GoogleDailyTrends'
import { GoogleSearch } from '../../interface/Search'
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 ? data.userStatus.counters.mobileSearch[0] : null // Mobile searches
@@ -33,7 +29,7 @@ export async function doSearch(page: Page, data: DashboardData, mobile: boolean)
}
// Generate search queries
let googleSearchQueries = await getGoogleTrends(locale, missingPoints) as GoogleSearch[]
let googleSearchQueries = await getGoogleTrends(data.userProfile.attributes.country, missingPoints)
googleSearchQueries = shuffleArray(googleSearchQueries)
// Deduplicate the search terms
@@ -185,10 +181,14 @@ async function bingSearch(page: Page, searchPage: Page, query: string) {
return await getSearchPoints(page)
}
async function getGoogleTrends(locale: string, queryCount: number): Promise<GoogleSearch[]> {
async function getGoogleTrends(geoLocale: string, queryCount: number): Promise<GoogleSearch[]> {
const queryTerms: GoogleSearch[] = []
let i = 0
geoLocale = (searchSettings.useGeoLocaleQueries && geoLocale.length === 2) ? geoLocale.toUpperCase() : 'US'
log('SEARCH-GOOGLE-TRENDS', `Generating search queries, can take a while! | GeoLocale: ${geoLocale}`)
while (queryCount > queryTerms.length) {
i += 1
const date = new Date()
@@ -197,7 +197,7 @@ async function getGoogleTrends(locale: string, queryCount: number): Promise<Goog
try {
const request = {
url: `https://trends.google.com/trends/api/dailytrends?geo=US&hl=en&ed=${formattedDate}&ns=15`,
url: `https://trends.google.com/trends/api/dailytrends?geo=${geoLocale}&hl=en&ed=${formattedDate}&ns=15`,
method: 'GET',
headers: {
'Content-Type': 'application/json'
@@ -283,13 +283,11 @@ async function clickRandomLink(page: Page) {
// Check if the URL is different from the original one, don't loop more than 5 times.
let i = 0
while (lastTabURL.href !== searchListingURL.href && i < 5) {
// 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())
// If "goBack" didn't return to search listing (due to redirects)
if (lastTabURL.hostname !== searchListingURL.hostname) {

View File

@@ -2,9 +2,9 @@ import { Page } from 'puppeteer'
import { wait } from '../../util/Utils'
import { log } from '../../util/Logger'
import { getQuizData } from '../../browser/BrowserFunc'
export async function doThisOrThat(page: Page) {
return // Todo
log('THIS-OR-THAT', 'Trying to complete ThisOrThat')
try {
@@ -22,7 +22,9 @@ export async function doThisOrThat(page: Page) {
await wait(2000)
// Solving
const quizData = await getQuizData(page)
quizData // correctAnswer property is always null?
log('THIS-OR-THAT', 'Completed the ThisOrthat successfully')
} catch (error) {
await page.close()

View File

@@ -2,6 +2,7 @@ import cluster from 'cluster'
import Browser from './browser/Browser'
import { getDashboardData, getEarnablePoints, goHome } from './browser/BrowserFunc'
import { log } from './util/Logger'
import { loadAccounts } from './util/Account'
import { chunkArray } from './util/Utils'
@@ -102,8 +103,18 @@ class MicrosoftRewardsBot {
// Desktop
async Desktop(account: Account) {
const browser = await this.browserFactory.createBrowser(account.email, false)
const browser = await this.browserFactory.createBrowser(account.email, account.proxy, false)
const page = await browser.newPage()
let pages = await browser.pages()
// If for some reason the browser initializes with more than 2 pages, close these
while (pages.length > 2) {
await pages[0]?.close()
pages = await browser.pages()
}
// Log into proxy
await page.authenticate({ username: account.proxy.username, password: account.proxy.password })
log('MAIN', 'Starting DESKTOP browser')
@@ -156,8 +167,17 @@ class MicrosoftRewardsBot {
// Mobile
async Mobile(account: Account) {
const browser = await this.browserFactory.createBrowser(account.email, true)
const browser = await this.browserFactory.createBrowser(account.email, account.proxy, true)
const page = await browser.newPage()
let pages = await browser.pages()
// If for some reason the browser initializes with more than 2 pages, close these
while (pages.length > 2) {
await pages[0]?.close()
pages = await browser.pages()
}
// Log into proxy
await page.authenticate({ username: account.proxy.username, password: account.proxy.password })
log('MAIN', 'Starting MOBILE browser')

View File

@@ -1,4 +1,12 @@
export interface Account {
email: string;
password: string;
proxy: AccountProxy;
}
export interface AccountProxy {
url: string;
port: number;
password: string;
username: string;
}

View File

@@ -1,7 +1,9 @@
import * as fs from 'fs'
import path from 'path'
export async function loadAccounts() {
import { Account } from '../interface/Account'
export async function loadAccounts(): Promise<Account[]> {
try {
let file = 'accounts.json'

View File

@@ -81,7 +81,7 @@ export async function getEdgeVersions() {
export function getSystemComponents(mobile: boolean): string {
const osId: string = mobile ? 'Linux' : 'Windows NT 10.0'
const uaPlatform: string = mobile ? 'Android 10' : 'Win64; x64'
const uaPlatform: string = mobile ? 'Android 13' : 'Win64; x64'
if (mobile) {
return `${uaPlatform}; ${osId}; K`
@@ -90,7 +90,6 @@ export function getSystemComponents(mobile: boolean): string {
return `${uaPlatform}; ${osId}`
}
export async function getAppComponents(mobile: boolean) {
const versions = await getEdgeVersions()
const edgeVersion = mobile ? versions.android : versions.windows as string

View File

@@ -4,7 +4,7 @@ export async function wait(ms: number): Promise<void> {
})
}
export function getFormattedDate(ms = Date.now()) {
export function getFormattedDate(ms = Date.now()): string {
const today = new Date(ms)
const month = String(today.getMonth() + 1).padStart(2, '0') // January is 0
const day = String(today.getDate()).padStart(2, '0')
@@ -21,7 +21,7 @@ export function shuffleArray<T>(array: T[]): T[] {
return shuffledArray
}
export function randomNumber(min: number, max: number) {
export function randomNumber(min: number, max: number): number {
return Math.floor(Math.random() * (max - min + 1)) + min
}