mirror of
https://github.com/TheNetsky/Microsoft-Rewards-Script.git
synced 2026-01-20 06:53:59 +00:00
1.0.5
This commit is contained in:
@@ -1,11 +1,14 @@
|
||||
import { Page } from 'puppeteer'
|
||||
import { DashboardData } from '../interface/DashboardData'
|
||||
import { doPoll } from './activities/Poll'
|
||||
import { getFormattedDate, wait } from '../util/Utils'
|
||||
import { doQuiz } from './activities/Quiz'
|
||||
import { log } from '../util/Logger'
|
||||
import { doUrlReward } from './activities/UrlReward'
|
||||
|
||||
import { doPoll } from './activities/Poll'
|
||||
import { doQuiz } from './activities/Quiz'
|
||||
import { doUrlReward } from './activities/UrlReward'
|
||||
import { doThisOrThat } from './activities/ThisOrThat'
|
||||
|
||||
import { getFormattedDate, wait } from '../util/Utils'
|
||||
import { log } from '../util/Logger'
|
||||
|
||||
import { DashboardData } from '../interface/DashboardData'
|
||||
|
||||
export async function doDailySet(page: Page, data: DashboardData) {
|
||||
const todayData = data.dailySetPromotions[getFormattedDate()]
|
||||
@@ -19,6 +22,12 @@ export async function doDailySet(page: Page, data: DashboardData) {
|
||||
|
||||
for (const activity of activitiesUncompleted) {
|
||||
log('DAILY-SET', 'Started doing daily set items')
|
||||
|
||||
// If activity does not give points, skip
|
||||
if (activity.pointProgressMax <= 0) {
|
||||
continue
|
||||
}
|
||||
|
||||
switch (activity.promotionType) {
|
||||
// Quiz (Poll/Quiz)
|
||||
case 'quiz':
|
||||
@@ -30,6 +39,12 @@ export async function doDailySet(page: Page, data: DashboardData) {
|
||||
await doPoll(page, activity)
|
||||
break
|
||||
|
||||
// This Or That Quiz (Usually 50 points)
|
||||
case 50:
|
||||
log('ACTIVITY', 'Found daily activity type: ThisOrThat')
|
||||
await doThisOrThat(page, activity)
|
||||
break
|
||||
|
||||
// Quizzes are usually 30-40 points
|
||||
default:
|
||||
log('ACTIVITY', 'Found daily activity type: Quiz')
|
||||
|
||||
@@ -6,8 +6,8 @@ const rl = readline.createInterface({
|
||||
output: process.stdout
|
||||
})
|
||||
|
||||
import { wait } from '../util/Utils'
|
||||
import { tryDismissAllMessages, tryDismissBingCookieBanner } from '../BrowserUtil'
|
||||
import { wait } from '../util/Utils'
|
||||
import { log } from '../util/Logger'
|
||||
|
||||
export async function login(page: Page, email: string, password: string) {
|
||||
@@ -34,7 +34,7 @@ export async function login(page: Page, email: string, password: string) {
|
||||
log('LOGIN', 'Logged in successfully')
|
||||
|
||||
} catch (error) {
|
||||
log('LOGIN', 'An error occurred:' + error, 'error')
|
||||
log('LOGIN', 'An error occurred:' + JSON.stringify(error, null, 2), 'error')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ async function checkBingLogin(page: Page): Promise<void> {
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
log('LOGIN-BING', 'An error occurred:' + error, 'error')
|
||||
log('LOGIN-BING', 'An error occurred:' + JSON.stringify(error, null, 2), 'error')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,23 +1,30 @@
|
||||
import { Page } from 'puppeteer'
|
||||
import { DashboardData } from '../interface/DashboardData'
|
||||
|
||||
import { doPoll } from './activities/Poll'
|
||||
import { doQuiz } from './activities/Quiz'
|
||||
import { log } from '../util/Logger'
|
||||
import { doUrlReward } from './activities/UrlReward'
|
||||
import { wait } from '../util/Utils'
|
||||
import { doThisOrThat } from './activities/ThisOrThat'
|
||||
|
||||
import { wait } from '../util/Utils'
|
||||
import { log } from '../util/Logger'
|
||||
|
||||
import { DashboardData } from '../interface/DashboardData'
|
||||
|
||||
export async function doMorePromotions(page: Page, data: DashboardData) {
|
||||
const morePromotions = data.morePromotions
|
||||
|
||||
const activitiesUncompleted = morePromotions?.filter(x => !x.complete) ?? []
|
||||
|
||||
|
||||
if (!activitiesUncompleted.length) {
|
||||
log('MORE-PROMOTIONS', 'All more promotion items have already been completed')
|
||||
return
|
||||
}
|
||||
|
||||
for (const activity of activitiesUncompleted) {
|
||||
// If activity does not give points, skip
|
||||
if (activity.pointProgressMax <= 0) {
|
||||
continue
|
||||
}
|
||||
|
||||
switch (activity.promotionType) {
|
||||
// Quiz (Poll/Quiz)
|
||||
@@ -30,6 +37,12 @@ export async function doMorePromotions(page: Page, data: DashboardData) {
|
||||
await doPoll(page, activity)
|
||||
break
|
||||
|
||||
// This Or That Quiz (Usually 50 points)
|
||||
case 50:
|
||||
log('ACTIVITY', 'Found daily activity type: ThisOrThat')
|
||||
await doThisOrThat(page, activity)
|
||||
break
|
||||
|
||||
// Quizzes are usually 30-40 points
|
||||
default:
|
||||
log('ACTIVITY', 'Found promotion activity type: Quiz')
|
||||
|
||||
72
src/functions/PunchCard.ts
Normal file
72
src/functions/PunchCard.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import { Page } from 'puppeteer'
|
||||
|
||||
import { doPoll } from './activities/Poll'
|
||||
import { doQuiz } from './activities/Quiz'
|
||||
import { doUrlReward } from './activities/UrlReward'
|
||||
import { doThisOrThat } from './activities/ThisOrThat'
|
||||
|
||||
import { wait } from '../util/Utils'
|
||||
import { log } from '../util/Logger'
|
||||
|
||||
import { DashboardData } from '../interface/DashboardData'
|
||||
|
||||
export async function doPunchCard(page: Page, data: DashboardData) {
|
||||
|
||||
const punchCardsUncompleted = data.punchCards?.filter(x => !x.parentPromotion.complete) ?? [] // filter out the uncompleted punch cards
|
||||
|
||||
if (!punchCardsUncompleted.length) {
|
||||
log('PUNCH-CARD', 'All punch cards have already been completed')
|
||||
return
|
||||
}
|
||||
|
||||
// Todo
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const activitiesUncompleted: any = ''
|
||||
|
||||
for (const activity of activitiesUncompleted) {
|
||||
log('PUNCH-CARD', 'Started doing daily set items')
|
||||
|
||||
// If activity does not give points, skip
|
||||
if (activity.pointProgressMax <= 0) {
|
||||
continue
|
||||
}
|
||||
|
||||
switch (activity.promotionType) {
|
||||
// Quiz (Poll/Quiz)
|
||||
case 'quiz':
|
||||
|
||||
switch (activity.pointProgressMax) {
|
||||
// Poll (Usually 10 points)
|
||||
case 10:
|
||||
log('ACTIVITY', 'Found daily activity type: Poll')
|
||||
await doPoll(page, activity)
|
||||
break
|
||||
|
||||
// This Or That Quiz (Usually 50 points)
|
||||
case 50:
|
||||
log('ACTIVITY', 'Found daily activity type: ThisOrThat')
|
||||
await doThisOrThat(page, activity)
|
||||
break
|
||||
|
||||
// Quizzes are usually 30-40 points
|
||||
default:
|
||||
log('ACTIVITY', 'Found daily activity type: Quiz')
|
||||
await doQuiz(page, activity)
|
||||
break
|
||||
}
|
||||
break
|
||||
|
||||
// UrlReward (Visit)
|
||||
case 'urlreward':
|
||||
log('ACTIVITY', 'Found daily activity type: UrlReward')
|
||||
await doUrlReward(page, activity)
|
||||
break
|
||||
|
||||
default:
|
||||
break
|
||||
}
|
||||
await wait(1500)
|
||||
}
|
||||
|
||||
log('PUNCH-CARD', 'Punch card items have been completed')
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
import { Page } from 'puppeteer'
|
||||
import { MorePromotion, PromotionalItem } from '../../interface/DashboardData'
|
||||
|
||||
import { getLatestTab } from '../../BrowserUtil'
|
||||
import { log } from '../../util/Logger'
|
||||
import { randomNumber, wait } from '../../util/Utils'
|
||||
|
||||
import { MorePromotion, PromotionalItem } from '../../interface/DashboardData'
|
||||
|
||||
export async function doPoll(page: Page, data: PromotionalItem | MorePromotion) {
|
||||
log('POLL', 'Trying to complete poll')
|
||||
|
||||
@@ -18,7 +20,7 @@ export async function doPoll(page: Page, data: PromotionalItem | MorePromotion)
|
||||
|
||||
const buttonId = `#btoption${Math.floor(randomNumber(0, 1))}`
|
||||
|
||||
await pollPage.waitForSelector(buttonId)
|
||||
await pollPage.waitForSelector(buttonId, { visible: true, timeout: 5000 })
|
||||
await pollPage.click(buttonId)
|
||||
|
||||
await wait(2000)
|
||||
@@ -26,6 +28,6 @@ export async function doPoll(page: Page, data: PromotionalItem | MorePromotion)
|
||||
|
||||
log('POLL', 'Completed the poll successfully')
|
||||
} catch (error) {
|
||||
log('POLL', 'An error occurred:' + error, 'error')
|
||||
log('POLL', 'An error occurred:' + JSON.stringify(error, null, 2), 'error')
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
import { Page } from 'puppeteer'
|
||||
import { MorePromotion, PromotionalItem } from '../../interface/DashboardData'
|
||||
import { getQuizData } from '../../BrowserFunc'
|
||||
import { wait } from '../../util/Utils'
|
||||
|
||||
import { getLatestTab } from '../../BrowserUtil'
|
||||
import { getQuizData, waitForQuizRefresh } from '../../BrowserFunc'
|
||||
import { wait } from '../../util/Utils'
|
||||
import { log } from '../../util/Logger'
|
||||
|
||||
import { MorePromotion, PromotionalItem } from '../../interface/DashboardData'
|
||||
|
||||
export async function doQuiz(page: Page, data: PromotionalItem | MorePromotion) {
|
||||
log('QUIZ', 'Trying to complete quiz')
|
||||
|
||||
@@ -28,7 +30,6 @@ export async function doQuiz(page: Page, data: PromotionalItem | MorePromotion)
|
||||
await wait(2000)
|
||||
|
||||
const quizData = await getQuizData(quizPage)
|
||||
|
||||
const questionsRemaining = quizData.maxQuestions - quizData.CorrectlyAnsweredQuestionCount // Amount of questions remaining
|
||||
|
||||
// All questions
|
||||
@@ -38,7 +39,7 @@ export async function doQuiz(page: Page, data: PromotionalItem | MorePromotion)
|
||||
const answers: string[] = []
|
||||
|
||||
for (let i = 0; i < quizData.numberOfOptions; i++) {
|
||||
const answerSelector = await quizPage.waitForSelector(`#rqAnswerOption${i}`)
|
||||
const answerSelector = await quizPage.waitForSelector(`#rqAnswerOption${i}`, { visible: true, timeout: 5000 })
|
||||
const answerAttribute = await answerSelector?.evaluate(el => el.getAttribute('iscorrectoption'))
|
||||
await wait(500)
|
||||
|
||||
@@ -49,7 +50,7 @@ export async function doQuiz(page: Page, data: PromotionalItem | MorePromotion)
|
||||
|
||||
// Click the answers
|
||||
for (const answer of answers) {
|
||||
await wait(2000)
|
||||
await quizPage.waitForSelector(answer, { visible: true, timeout: 2000 })
|
||||
|
||||
// Click the answer on page
|
||||
await quizPage.click(answer)
|
||||
@@ -68,7 +69,7 @@ export async function doQuiz(page: Page, data: PromotionalItem | MorePromotion)
|
||||
|
||||
for (let i = 0; i < quizData.numberOfOptions; i++) {
|
||||
|
||||
const answerSelector = await quizPage.waitForSelector(`#rqAnswerOption${i}`)
|
||||
const answerSelector = await quizPage.waitForSelector(`#rqAnswerOption${i}`, { visible: true, timeout: 5000 })
|
||||
const dataOption = await answerSelector?.evaluate(el => el.getAttribute('data-option'))
|
||||
|
||||
if (dataOption === correctOption) {
|
||||
@@ -97,27 +98,7 @@ export async function doQuiz(page: Page, data: PromotionalItem | MorePromotion)
|
||||
} catch (error) {
|
||||
const quizPage = await getLatestTab(page)
|
||||
await quizPage.close()
|
||||
log('QUIZ', 'An error occurred:' + error, 'error')
|
||||
log('QUIZ', 'An error occurred:' + JSON.stringify(error, null, 2), 'error')
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async function waitForQuizRefresh(page: Page) {
|
||||
try {
|
||||
await page.waitForSelector('#rqHeaderCredits', { timeout: 5000 })
|
||||
return true
|
||||
} catch (error) {
|
||||
log('QUIZ-REFRESH', 'An error occurred:' + error, 'error')
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
async function checkQuizCompleted(page: Page) {
|
||||
try {
|
||||
await page.waitForSelector('#quizCompleteContainer', { timeout: 1000 })
|
||||
return true
|
||||
} catch (error) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
checkQuizCompleted
|
||||
}
|
||||
@@ -1,16 +1,16 @@
|
||||
import { Page } from 'puppeteer'
|
||||
import axios from 'axios'
|
||||
|
||||
import { getLatestTab } from '../../BrowserUtil'
|
||||
import { getSearchPoints } from '../../BrowserFunc'
|
||||
import { log } from '../../util/Logger'
|
||||
import { randomNumber, shuffleArray, wait } from '../../util/Utils'
|
||||
import { getSearchPoints } from '../../BrowserFunc'
|
||||
|
||||
import { searches } from '../../config.json'
|
||||
|
||||
import { DashboardData, DashboardImpression } from '../../interface/DashboardData'
|
||||
import { GoogleTrends } from '../../interface/GoogleDailyTrends'
|
||||
import { GoogleSearch } from '../../interface/Search'
|
||||
import { getLatestTab } from '../../BrowserUtil'
|
||||
|
||||
export async function doSearch(page: Page, data: DashboardData, mobile: boolean) {
|
||||
const locale = await page.evaluate(() => {
|
||||
@@ -19,11 +19,11 @@ export async function doSearch(page: Page, data: DashboardData, mobile: boolean)
|
||||
|
||||
log('SEARCH-BING', 'Starting bing searches')
|
||||
|
||||
const mobileData = data.userStatus.counters.mobileSearch[0] as DashboardImpression // Mobile searches
|
||||
const mobileData = data.userStatus.counters?.mobileSearch ? data.userStatus.counters.mobileSearch[0] : null // Mobile searches
|
||||
const edgeData = data.userStatus.counters.pcSearch[1] as DashboardImpression // Edge searches
|
||||
const genericData = data.userStatus.counters.pcSearch[0] as DashboardImpression // Normal searches
|
||||
|
||||
let missingPoints = mobile ?
|
||||
let missingPoints = (mobile && mobileData) ?
|
||||
(mobileData.pointProgressMax - mobileData.pointProgress) :
|
||||
(edgeData.pointProgressMax - edgeData.pointProgress) + (genericData.pointProgressMax - genericData.pointProgress)
|
||||
|
||||
@@ -32,7 +32,7 @@ export async function doSearch(page: Page, data: DashboardData, mobile: boolean)
|
||||
return
|
||||
}
|
||||
|
||||
// Generate search queries
|
||||
// Generate search queries
|
||||
let googleSearchQueries = await getGoogleTrends(locale, missingPoints) as GoogleSearch[]
|
||||
googleSearchQueries = shuffleArray(googleSearchQueries)
|
||||
|
||||
@@ -59,11 +59,11 @@ export async function doSearch(page: Page, data: DashboardData, mobile: boolean)
|
||||
|
||||
const newData = await bingSearch(page, searchPage, query, mobile)
|
||||
|
||||
const newMobileData = newData.mobileSearch[0] as DashboardImpression // Mobile searches
|
||||
const newMobileData = newData.mobileSearch ? newData.mobileSearch[0] : null // Mobile searches
|
||||
const newEdgeData = newData.pcSearch[1] as DashboardImpression // Edge searches
|
||||
const newGenericData = newData.pcSearch[0] as DashboardImpression // Normal searches
|
||||
|
||||
const newMissingPoints = mobile ?
|
||||
const newMissingPoints = (mobile && newMobileData) ?
|
||||
(newMobileData.pointProgressMax - newMobileData.pointProgress) :
|
||||
(newEdgeData.pointProgressMax - newEdgeData.pointProgress) + (newGenericData.pointProgressMax - newGenericData.pointProgress)
|
||||
|
||||
@@ -103,11 +103,11 @@ export async function doSearch(page: Page, data: DashboardData, mobile: boolean)
|
||||
log('SEARCH-BING-EXTRA', `${missingPoints} Points Remaining | Query: ${term} | Mobile: ${mobile}`)
|
||||
const newData = await bingSearch(page, searchPage, query.topic, mobile)
|
||||
|
||||
const newMobileData = newData.mobileSearch[0] as DashboardImpression // Mobile searches
|
||||
const newMobileData = newData.mobileSearch ? newData.mobileSearch[0] : null // Mobile searches
|
||||
const newEdgeData = newData.pcSearch[1] as DashboardImpression // Edge searches
|
||||
const newGenericData = newData.pcSearch[0] as DashboardImpression // Normal searches
|
||||
|
||||
const newMissingPoints = mobile ?
|
||||
const newMissingPoints = (mobile && newMobileData) ?
|
||||
(newMobileData.pointProgressMax - newMobileData.pointProgress) :
|
||||
(newEdgeData.pointProgressMax - newEdgeData.pointProgress) + (newGenericData.pointProgressMax - newGenericData.pointProgress)
|
||||
|
||||
@@ -143,7 +143,7 @@ async function bingSearch(page: Page, searchPage: Page, query: string, mobile: b
|
||||
for (let i = 0; i < 5; i++) {
|
||||
try {
|
||||
const searchBar = '#sb_form_q'
|
||||
await searchPage.waitForSelector(searchBar, { timeout: 3000 })
|
||||
await searchPage.waitForSelector(searchBar, { visible: true, timeout: 3000 })
|
||||
await searchPage.click(searchBar) // Focus on the textarea
|
||||
await wait(500)
|
||||
await searchPage.keyboard.down('Control')
|
||||
@@ -169,10 +169,11 @@ async function bingSearch(page: Page, searchPage: Page, query: string, mobile: b
|
||||
|
||||
} catch (error) {
|
||||
if (i === 5) {
|
||||
log('SEARCH-BING', 'Failed after 5 retries... An error occurred:' + error, 'error')
|
||||
return await getSearchPoints(page)
|
||||
log('SEARCH-BING', 'Failed after 5 retries... An error occurred:' + JSON.stringify(error, null, 2), 'error')
|
||||
break
|
||||
|
||||
}
|
||||
log('SEARCH-BING', 'Search failed, An error occurred:' + error, 'error')
|
||||
log('SEARCH-BING', 'Search failed, An error occurred:' + JSON.stringify(error, null, 2), 'error')
|
||||
log('SEARCH-BING', `Retrying search, attempt ${i}/5`, 'warn')
|
||||
|
||||
await wait(4000)
|
||||
@@ -214,7 +215,7 @@ async function getGoogleTrends(locale: string, queryCount: number): Promise<Goog
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
log('SEARCH-GOOGLE-TRENDS', 'An error occurred:' + error, 'error')
|
||||
log('SEARCH-GOOGLE-TRENDS', 'An error occurred:' + JSON.stringify(error, null, 2), 'error')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,7 +236,7 @@ async function getRelatedTerms(term: string): Promise<string[]> {
|
||||
|
||||
return response.data[1] as string[]
|
||||
} catch (error) {
|
||||
log('SEARCH-BING-RELTATED', 'An error occurred:' + error, 'error')
|
||||
log('SEARCH-BING-RELTATED', 'An error occurred:' + JSON.stringify(error, null, 2), 'error')
|
||||
}
|
||||
return []
|
||||
}
|
||||
@@ -255,7 +256,7 @@ async function randomScroll(page: Page) {
|
||||
await page.keyboard.press('ArrowDown')
|
||||
}
|
||||
} catch (error) {
|
||||
log('SEARCH-RANDOM-SCROLL', 'An error occurred:' + error, 'error')
|
||||
log('SEARCH-RANDOM-SCROLL', 'An error occurred:' + JSON.stringify(error, null, 2), 'error')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -301,6 +302,6 @@ async function clickRandomLink(page: Page, mobile: boolean) {
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
log('SEARCH-RANDOM-CLICK', 'An error occurred:' + error, 'error')
|
||||
log('SEARCH-RANDOM-CLICK', 'An error occurred:' + JSON.stringify(error, null, 2), 'error')
|
||||
}
|
||||
}
|
||||
39
src/functions/activities/ThisOrThat.ts
Normal file
39
src/functions/activities/ThisOrThat.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { Page } from 'puppeteer'
|
||||
|
||||
import { getLatestTab } from '../../BrowserUtil'
|
||||
import { wait } from '../../util/Utils'
|
||||
import { log } from '../../util/Logger'
|
||||
|
||||
import { PromotionalItem, MorePromotion } from '../../interface/DashboardData'
|
||||
|
||||
export async function doThisOrThat(page: Page, data: PromotionalItem | MorePromotion) {
|
||||
return // Todo
|
||||
log('THIS-OR-THAT', 'Trying to complete ThisOrThat')
|
||||
|
||||
try {
|
||||
const selector = `[data-bi-id="${data.offerId}"]`
|
||||
|
||||
// Wait for page to load and click to load the this or that quiz in a new tab
|
||||
await page.waitForSelector(selector, { timeout: 5000 })
|
||||
await page.click(selector)
|
||||
|
||||
const thisorthatPage = await getLatestTab(page)
|
||||
|
||||
// Check if the quiz has been started or not
|
||||
const quizNotStarted = await thisorthatPage.waitForSelector('#rqStartQuiz', { visible: true, timeout: 3000 }).then(() => true).catch(() => false)
|
||||
if (quizNotStarted) {
|
||||
await thisorthatPage.click('#rqStartQuiz')
|
||||
} else {
|
||||
log('THIS-OR-THAT', 'ThisOrThat has already been started, trying to finish it')
|
||||
}
|
||||
|
||||
await wait(2000)
|
||||
|
||||
// Solving
|
||||
|
||||
log('THIS-OR-THAT', 'Completed the ThisOrthat successfully')
|
||||
} catch (error) {
|
||||
log('THIS-OR-THAT', 'An error occurred:' + JSON.stringify(error, null, 2), 'error')
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
import { Page } from 'puppeteer'
|
||||
|
||||
import { getLatestTab } from '../../BrowserUtil'
|
||||
import { log } from '../../util/Logger'
|
||||
import { PromotionalItem, MorePromotion } from '../../interface/DashboardData'
|
||||
|
||||
import { PromotionalItem, MorePromotion } from '../../interface/DashboardData'
|
||||
|
||||
export async function doUrlReward(page: Page, data: PromotionalItem | MorePromotion) {
|
||||
log('URL-REWARD', 'Trying to complete UrlReward')
|
||||
@@ -20,7 +21,7 @@ export async function doUrlReward(page: Page, data: PromotionalItem | MorePromot
|
||||
|
||||
log('URL-REWARD', 'Completed the UrlReward successfully')
|
||||
} catch (error) {
|
||||
log('URL-REWARD', 'An error occurred:' + error, 'error')
|
||||
log('URL-REWARD', 'An error occurred:' + JSON.stringify(error, null, 2), 'error')
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user