Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 31 additions & 10 deletions src/browser/ReactFunc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,12 +291,28 @@ export default class ReactFunc {
// Never try future-dated offers, lol
const reportable = !!hash && !isCompleted && !isLocked && (date === null || date <= today)

const isExploreOnBing = offerId.toLowerCase().includes('exploreonbing')
const points = (obj.points as number) ?? (obj.pointProgressMax as number) ?? (isExploreOnBing ? 10 : 0)
let title = (obj.title as string) ?? ''
let description = (obj.description as string) ?? ''
if (isExploreOnBing && !title) {
if (offerId.includes('airline')) { title = 'Take off soon'; description = 'Search on Bing to book affordable flights' }
else if (offerId.includes('airport')) { title = 'Park with ease'; description = 'Search on Bing to reserve airport parking' }
else if (offerId.includes('flower')) { title = 'Send a smile'; description = 'Search on Bing for fast and fresh flower delivery options' }
else if (offerId.includes('streaming')) { title = 'Stream your favorites'; description = 'Search on Bing to find the best streaming platforms and bundles' }
else if (offerId.includes('credit')) { title = 'Know your score'; description = 'Search on Bing to check your credit report and raise your score' }
else if (offerId.includes('health')) { title = 'Feeling symptoms?'; description = 'Search on Bing for a health condition to learn about the symptoms' }
else if (offerId.includes('recipe')) { title = 'Learn a new recipe'; description = 'Search on Bing for new recipes' }
else if (offerId.includes('videogames')) { title = 'Explore videogames'; description = 'Search on Bing to explore videogames' }
else { title = offerId }
}

const candidate: ParsedOffer = {
offerId,
hash,
title: (obj.title as string) ?? '',
description: (obj.description as string) ?? '',
points: (obj.points as number) ?? (obj.pointProgressMax as number) ?? 0,
title,
description,
points,
promotionSubtype: (obj.promotionSubtype as string | null) ?? null,
destination: (obj.destination as string) ?? (obj.destinationUrl as string) ?? '',
isCompleted,
Expand Down Expand Up @@ -720,26 +736,31 @@ export default class ReactFunc {
const { id, at } = anchors[k]!
if (!this.isParentQuestId(id)) continue

const next = anchors[k + 1]?.at ?? combined.length
const region = combined.slice(at, Math.min(next, at + 3000))
let next = combined.length
for (let j = k + 1; j < anchors.length; j++) {
if (anchors[j]!.id !== id && this.isParentQuestId(anchors[j]!.id)) {
next = anchors[j]!.at
break
}
}
const region = combined.slice(at, Math.min(next, at + 4000))

const title =
region.match(/"alt":"((?:[^"\\]|\\.)*)"/)?.[1] ??
region.match(/"title":"((?:[^"\\]|\\.)*)"/)?.[1] ??
''

const pointsMatch = region.match(/\["\+","([\d,]+)"\]/)
const pointsMatch = region.match(/\["(?:|\+)","([\d,]+)"\]/)
const points = pointsMatch ? Number(pointsMatch[1]!.replace(/,/g, '')) : 0
const taskM = region.match(/(\d+)\s*\/\s*(\d+)\s*tasks/)
const taskM = region.match(/(\d+)\s*(?:\/|\b(?:von|of|sur|de|z|iz|із|з)\b)\s*(\d+)/i)
const complete = !!taskM && Number(taskM[1]) >= Number(taskM[2]!) && Number(taskM[2]) > 0

// First wins for title/points
const prev = byId.get(id)
byId.set(id, {
offerId: id,
title: prev?.title || title,
pointProgressMax: prev?.pointProgressMax || points,
complete: prev?.complete || complete
pointProgressMax: Math.max(prev?.pointProgressMax || 0, points),
complete: (prev && prev.complete) || complete
})
}

Expand Down
6 changes: 3 additions & 3 deletions src/functions/activities/api/UrlReward.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ export class UrlReward extends BaseActivity {
}
],
{
url: URLs.rewards.dashboard,
referer: URLs.rewards.dashboard,
routerStateTree: this.bot.browser.react.routerStateTree('dashboard')
url: URLs.rewards.earn,
referer: URLs.rewards.earn,
routerStateTree: this.bot.browser.react.routerStateTree('earn')
}
)

Expand Down
22 changes: 20 additions & 2 deletions src/functions/activities/rewards/DailySet.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,31 @@
import { BaseActivity } from '../BaseActivity'
import type { DashboardData } from '../../../interface/DashboardData'
import type { BasePromotion, DashboardData } from '../../../interface/DashboardData'
import { PromotionActivityRunner } from './PromotionActivityRunner'

export class DailySet extends BaseActivity {
public async run(data: DashboardData): Promise<void> {
const today = this.bot.utils.getFormattedDate()
const pending =
let pending: BasePromotion[] =
data.dashboard.dailySetPromotions[today]?.filter(item => !item.complete && item.pointProgressMax > 0) ?? []

if (!pending.length && this.bot.reactSnapshot?.offers) {
const reactDailySet = this.bot.reactSnapshot.offers.filter(
o => o.offerId.toLowerCase().includes('dailyset') && !o.isCompleted && o.points > 0 && o.reportable
)
if (reactDailySet.length) {
pending = reactDailySet.map(o => ({
offerId: o.offerId,
title: o.title || o.offerId,
complete: o.isCompleted,
pointProgressMax: o.points,
promotionType: 'urlreward',
destinationUrl: o.destination,
hash: o.hash,
activityType: o.activityType ?? 11
} as unknown as BasePromotion))
}
}

if (!pending.length) {
this.bot.logger.info(this.bot.isMobile, 'DAILY-SET', 'All "Daily Set" items have already been completed')
return
Expand Down
16 changes: 16 additions & 0 deletions src/functions/activities/rewards/MorePromotions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,22 @@ export class MorePromotions extends BaseActivity {
.map(promotion => [promotion.offerId, promotion as BasePromotion] as const)
).values()
]
const existingIds = new Set(promotions.map(p => p.offerId))
for (const offer of this.bot.reactSnapshot?.reportable ?? []) {
if (offer.offerId.toLowerCase().includes('dailyset') || existingIds.has(offer.offerId)) continue
promotions.push({
offerId: offer.offerId,
title: offer.title || offer.offerId,
complete: offer.isCompleted,
pointProgressMax: offer.points,
promotionType: 'urlreward',
destinationUrl: offer.destination,
hash: offer.hash,
activityType: offer.activityType ?? 11,
priority: 1
} as unknown as BasePromotion)
existingIds.add(offer.offerId)
}

const pending = promotions.filter(promotion => this.isActionable(promotion))
if (!pending.length) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export class PromotionActivityRunner extends BaseActivity {
return
}

const isSearchOnBing = name.includes('exploreonbing')
const isSearchOnBing = name.includes('exploreonbing') || offerId.toLowerCase().includes('exploreonbing')
if (isSearchOnBing && !this.bot.config.activities.searchOnBing) {
this.logDisabled('SearchOnBing', offerId)
return
Expand Down
2 changes: 1 addition & 1 deletion src/functions/activities/search/SearchOnBingShared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ function extractSearchTerm(description: string): string {
return description
.trim()
.replace(
/^\s*(?:search(?:\s+on\s+bing|\s+bing|\s+the\s+web)?\s+for|look\s+up|find|explore|discover)\b[\s:]+/i,
/^\s*(?:search(?:\s+on\s+bing|\s+bing|\s+the\s+web)?\s+(?:for|to)|look\s+up|find|explore|discover)\b[\s:]+/i,
''
)
.replace(/^["'“”‘’]+|["'“”‘’]+$/g, '')
Expand Down
63 changes: 63 additions & 0 deletions src/functions/bing-search-activity-queries.json
Original file line number Diff line number Diff line change
Expand Up @@ -1003,5 +1003,68 @@
"cheap airport parking near me",
"long stay airport parking"
]
},
{
"title": "Take off soon",
"queries": [
"cheap flights to london",
"book affordable flights",
"airline tickets deals",
"cheap airline tickets"
]
},
{
"title": "Send a smile",
"queries": [
"flower delivery near me",
"fresh flower delivery",
"send flowers online",
"fast flower delivery"
]
},
{
"title": "Stream your favorites",
"queries": [
"best streaming platforms",
"streaming services comparison",
"top streaming services",
"streaming bundles"
]
},
{
"title": "Know your score",
"queries": [
"free credit report",
"check credit score free",
"how to raise credit score",
"credit score check"
]
},
{
"title": "Feeling symptoms?",
"queries": [
"health condition symptoms",
"common cold symptoms",
"flu symptoms checker",
"health symptoms"
]
},
{
"title": "Learn a new recipe",
"queries": [
"easy dinner recipes",
"healthy lunch recipes",
"quick dessert recipes",
"new recipes"
]
},
{
"title": "Explore videogames",
"queries": [
"best new video games",
"top video games 2026",
"popular video games",
"explore video games"
]
}
]