diff --git a/README.md b/README.md index 1388704..3cbd219 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,7 @@ Available options/variables and their default values: | PG_EMAIL | | Prime Gaming email for login. Overrides EMAIL. | | PG_PASSWORD | | Prime Gaming password for login. Overrides PASSWORD. | | PG_OTPKEY | | Prime Gaming MFA OTP key. | +| PG_REDEEM | 0 | Prime Gaming: try to redeem keys on external stores (experimental). | | GOG_EMAIL | | GOG email for login. Overrides EMAIL. | | GOG_PASSWORD | | GOG password for login. Overrides PASSWORD. | @@ -118,8 +119,8 @@ Run `node prime-gaming` (locally or in Docker). Claiming the Amazon Games works out-of-the-box, however, for games on external stores you need to either link your account or redeem a key. -- Stores that require account linking: Epic Games, Battle.net. -- Stores that require redeeming a key: Origin, GOG.com, Microsoft Games, Legacy Games. +- Stores that require account linking: Epic Games, Battle.net, Origin. +- Stores that require redeeming a key: GOG.com, Microsoft Games, Legacy Games. Keys and URLs are printed to the console, included in notifications and saved in `data/prime-gaming.json`. A screenshot of the page with the key is also saved to `data/screenshots`. [TODO](https://github.com/vogler/free-games-claimer/issues/5): ~~redeem keys on external stores.~~ diff --git a/config.js b/config.js index d75ee98..f1e0b10 100644 --- a/config.js +++ b/config.js @@ -33,4 +33,7 @@ export const cfg = { gog_email: process.env.GOG_EMAIL || process.env.EMAIL, gog_password: process.env.GOG_PASSWORD || process.env.PASSWORD, // OTP only via GOG_EMAIL, can't add app... + + // experimmental - likely to change + pg_redeem: process.env.PG_REDEEM, // prime-gaming: redeem keys on external stores }; diff --git a/prime-gaming.js b/prime-gaming.js index 7405f91..344f5f8 100644 --- a/prime-gaming.js +++ b/prime-gaming.js @@ -137,8 +137,8 @@ try { const redeem = { // 'origin': 'https://www.origin.com/redeem', // TODO still needed or now only via account linking? 'gog.com': 'https://www.gog.com/redeem', - 'legacy games': 'https://www.legacygames.com/primedeal', 'microsoft games': 'https://redeem.microsoft.com', + 'legacy games': 'https://www.legacygames.com/primedeal', }; if (store in redeem) { // did not work for linked origin: && !await page.locator('div:has-text("Successfully Claimed")').count() const code = await page.inputValue('input[type="text"]'); @@ -148,7 +148,64 @@ try { } console.log(' URL to redeem game:', redeem[store]); db.data[user][title].code = code; - notify_game.status = `redeem ${code} on ${store}`; + let redeem_action = 'redeem'; + if (cfg.pg_redeem) { // try to redeem keys on external stores + console.log(` Trying to redeem ${code} on ${store} (need to be logged in)!`); + const page2 = await context.newPage(); + await page2.goto(redeem[store], { waitUntil: 'domcontentloaded' }); + if (store == 'gog.com') { + // await page.goto(`https://redeem.gog.com/v1/bonusCodes/${code}`); // {"reason":"Invalid or no captcha"} + await page2.fill('#codeInput', code); + const r = page2.waitForResponse(r => r.url().startsWith('https://redeem.gog.com/')); + await page2.click('[type="submit"]'); + // console.log(await page2.locator('.warning-message').innerText()); + const rt = await (await r).text(); + console.debug(` Response: ${rt}`); + // {"reason":"Invalid or no captcha"} + // {"reason":"code_used"} + // {"reason":"code_not_found"} + const reason = JSON.parse(rt).reason; + if (reason.includes('captcha')) { + redeem_action = 'redeem (got captcha)'; + console.error(' Got captcha; could not redeem!'); + } else if (reason == 'code_used') { + redeem_action = 'already redeemed'; + console.log(' Code was already used!'); + } else if (reason == 'code_not_found') { + redeem_action = 'redeem (not found)'; + console.error(' Code was not found!'); + } else { // TODO not logged in? need valid unused code to test. + redeem_action = 'redeemed?'; + console.log(' Redeemed successfully? Please report your Response from above (if it is new) in https://github.com/vogler/free-games-claimer/issues/5'); + } + await page2.pause(); + await page2.close(); + } else if (store == 'microsoft games') { + console.error(` Redeem on ${store} not yet implemented!`); + if (page2.url().startsWith('https://login.')) { + console.error(' Not logged in! Use the browser to login manually.'); + redeem_action = 'redeem (login)'; + } else { + const r = page2.waitForResponse(r => r.url().startsWith('https://purchase.mp.microsoft.com/')); + await page2.fill('[name=tokenString]', code); + // console.log(await page2.locator('.redeem_code_error').innerText()); + const rt = await (await r).text(); + console.debug(` Response: ${rt}`); + // {"code":"NotFound","data":[],"details":[],"innererror":{"code":"TokenNotFound",... + const reason = JSON.parse(rt).code; + if (reason == 'NotFound') { + redeem_action = 'redeem (not found)'; + console.error(' Code was not found!'); + } else { // TODO find out other responses + redeem_action = 'redeemed?'; + console.log(' Redeemed successfully? Please report your Response from above (if it is new) in https://github.com/vogler/free-games-claimer/issues/5'); + } + } + } else if (store == 'legacy games') { + console.error(` Redeem on ${store} not yet implemented!`); + } + } + notify_game.status = `${redeem_action} ${code} on ${store}`; } else { notify_game.status = `claimed on ${store}`; }