mirror of
https://github.com/TheNetsky/Microsoft-Rewards-Script.git
synced 2026-01-27 02:11:05 +00:00
v3 init
Based of v3.0.0b10.
This commit is contained in:
199
src/functions/Workers.ts
Normal file
199
src/functions/Workers.ts
Normal file
@@ -0,0 +1,199 @@
|
||||
import type { Page } from 'patchright'
|
||||
import type { MicrosoftRewardsBot } from '../index'
|
||||
import type { DashboardData, PunchCard, BasePromotion, FindClippyPromotion } from '../interface/DashboardData'
|
||||
import type { AppDashboardData } from '../interface/AppDashBoardData'
|
||||
|
||||
export class Workers {
|
||||
public bot: MicrosoftRewardsBot
|
||||
|
||||
constructor(bot: MicrosoftRewardsBot) {
|
||||
this.bot = bot
|
||||
}
|
||||
|
||||
public async doDailySet(data: DashboardData, page: Page) {
|
||||
const todayKey = this.bot.utils.getFormattedDate()
|
||||
const todayData = data.dailySetPromotions[todayKey]
|
||||
|
||||
const activitiesUncompleted = todayData?.filter(x => !x.complete && x.pointProgressMax > 0) ?? []
|
||||
|
||||
if (!activitiesUncompleted.length) {
|
||||
this.bot.logger.info(this.bot.isMobile, 'DAILY-SET', 'All "Daily Set" items have already been completed')
|
||||
return
|
||||
}
|
||||
|
||||
this.bot.logger.info(this.bot.isMobile, 'DAILY-SET', 'Started solving "Daily Set" items')
|
||||
|
||||
await this.solveActivities(activitiesUncompleted, page)
|
||||
|
||||
this.bot.logger.info(this.bot.isMobile, 'DAILY-SET', 'All "Daily Set" items have been completed')
|
||||
}
|
||||
|
||||
public async doMorePromotions(data: DashboardData, page: Page) {
|
||||
const morePromotions: BasePromotion[] = [
|
||||
...new Map(
|
||||
[...(data.morePromotions ?? []), ...(data.morePromotionsWithoutPromotionalItems ?? [])]
|
||||
.filter(Boolean)
|
||||
.map(p => [p.offerId, p as BasePromotion] as const)
|
||||
).values()
|
||||
]
|
||||
|
||||
const activitiesUncompleted: BasePromotion[] =
|
||||
morePromotions?.filter(
|
||||
x =>
|
||||
!x.complete &&
|
||||
x.pointProgressMax > 0 &&
|
||||
x.exclusiveLockedFeatureStatus !== 'locked' &&
|
||||
x.promotionType
|
||||
) ?? []
|
||||
|
||||
if (!activitiesUncompleted.length) {
|
||||
this.bot.logger.info(
|
||||
this.bot.isMobile,
|
||||
'MORE-PROMOTIONS',
|
||||
'All "More Promotion" items have already been completed'
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
this.bot.logger.info(
|
||||
this.bot.isMobile,
|
||||
'MORE-PROMOTIONS',
|
||||
`Started solving ${activitiesUncompleted.length} "More Promotions" items`
|
||||
)
|
||||
|
||||
await this.solveActivities(activitiesUncompleted, page)
|
||||
|
||||
this.bot.logger.info(this.bot.isMobile, 'MORE-PROMOTIONS', 'All "More Promotion" items have been completed')
|
||||
}
|
||||
|
||||
public async doAppPromotions(data: AppDashboardData) {
|
||||
const appRewards = data.response.promotions.filter(
|
||||
x =>
|
||||
x.attributes['complete']?.toLowerCase() === 'false' &&
|
||||
x.attributes['offerid'] &&
|
||||
x.attributes['type'] &&
|
||||
x.attributes['type'] === 'sapphire'
|
||||
)
|
||||
|
||||
if (!appRewards.length) {
|
||||
this.bot.logger.info(
|
||||
this.bot.isMobile,
|
||||
'APP-PROMOTIONS',
|
||||
'All "App Promotions" items have already been completed'
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
for (const reward of appRewards) {
|
||||
await this.bot.activities.doAppReward(reward)
|
||||
// A delay between completing each activity
|
||||
await this.bot.utils.wait(this.bot.utils.randomDelay(5000, 15000))
|
||||
}
|
||||
|
||||
this.bot.logger.info(this.bot.isMobile, 'APP-PROMOTIONS', 'All "App Promotions" items have been completed')
|
||||
}
|
||||
|
||||
private async solveActivities(activities: BasePromotion[], page: Page, punchCard?: PunchCard) {
|
||||
for (const activity of activities) {
|
||||
try {
|
||||
const type = activity.promotionType?.toLowerCase() ?? ''
|
||||
const name = activity.name?.toLowerCase() ?? ''
|
||||
const offerId = (activity as BasePromotion).offerId
|
||||
const destinationUrl = activity.destinationUrl?.toLowerCase() ?? ''
|
||||
|
||||
this.bot.logger.debug(
|
||||
this.bot.isMobile,
|
||||
'ACTIVITY',
|
||||
`Processing activity | title="${activity.title}" | offerId=${offerId} | type=${type} | punchCard="${punchCard?.parentPromotion?.title ?? 'none'}"`
|
||||
)
|
||||
|
||||
switch (type) {
|
||||
// Quiz-like activities (Poll / regular quiz variants)
|
||||
case 'quiz': {
|
||||
const basePromotion = activity as BasePromotion
|
||||
|
||||
// Poll (usually 10 points, pollscenarioid in URL)
|
||||
if (activity.pointProgressMax === 10 && destinationUrl.includes('pollscenarioid')) {
|
||||
this.bot.logger.info(
|
||||
this.bot.isMobile,
|
||||
'ACTIVITY',
|
||||
`Found activity type "Poll" | title="${activity.title}" | offerId=${offerId}`
|
||||
)
|
||||
|
||||
//await this.bot.activities.doPoll(basePromotion)
|
||||
break
|
||||
}
|
||||
|
||||
// All other quizzes handled via Quiz API
|
||||
this.bot.logger.info(
|
||||
this.bot.isMobile,
|
||||
'ACTIVITY',
|
||||
`Found activity type "Quiz" | title="${activity.title}" | offerId=${offerId}`
|
||||
)
|
||||
|
||||
await this.bot.activities.doQuiz(basePromotion)
|
||||
break
|
||||
}
|
||||
|
||||
// UrlReward
|
||||
case 'urlreward': {
|
||||
const basePromotion = activity as BasePromotion
|
||||
|
||||
// Search on Bing are subtypes of "urlreward"
|
||||
if (name.includes('exploreonbing')) {
|
||||
this.bot.logger.info(
|
||||
this.bot.isMobile,
|
||||
'ACTIVITY',
|
||||
`Found activity type "SearchOnBing" | title="${activity.title}" | offerId=${offerId}`
|
||||
)
|
||||
|
||||
await this.bot.activities.doSearchOnBing(basePromotion, page)
|
||||
} else {
|
||||
this.bot.logger.info(
|
||||
this.bot.isMobile,
|
||||
'ACTIVITY',
|
||||
`Found activity type "UrlReward" | title="${activity.title}" | offerId=${offerId}`
|
||||
)
|
||||
|
||||
await this.bot.activities.doUrlReward(basePromotion)
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
// Find Clippy specific promotion type
|
||||
case 'findclippy': {
|
||||
const clippyPromotion = activity as unknown as FindClippyPromotion
|
||||
|
||||
this.bot.logger.info(
|
||||
this.bot.isMobile,
|
||||
'ACTIVITY',
|
||||
`Found activity type "FindClippy" | title="${activity.title}" | offerId=${offerId}`
|
||||
)
|
||||
|
||||
await this.bot.activities.doFindClippy(clippyPromotion)
|
||||
break
|
||||
}
|
||||
|
||||
// Unsupported types
|
||||
default: {
|
||||
this.bot.logger.warn(
|
||||
this.bot.isMobile,
|
||||
'ACTIVITY',
|
||||
`Skipped activity "${activity.title}" | offerId=${offerId} | Reason: Unsupported type "${activity.promotionType}"`
|
||||
)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Cooldown
|
||||
await this.bot.utils.wait(this.bot.utils.randomDelay(5000, 15000))
|
||||
} catch (error) {
|
||||
this.bot.logger.error(
|
||||
this.bot.isMobile,
|
||||
'ACTIVITY',
|
||||
`Error while solving activity "${activity.title}" | message=${error instanceof Error ? error.message : String(error)}`
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user