-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.ts
142 lines (128 loc) · 4.99 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import dotenv from "dotenv";
import { FingerprintInjector } from "fingerprint-injector";
import { FingerprintGenerator } from "fingerprint-generator";
import puppeteer from "puppeteer-extra";
import StealthPlugin from "puppeteer-extra-plugin-stealth";
import { setTimeout } from "node:timers/promises";
puppeteer.use(StealthPlugin());
dotenv.config();
/**
* Feel free to change these both to `true` to run in headless mode. However, you may be more likely
* to get recognized as a bot and be blocked if you run this script headless, so watch out!
*/
const NYT_HEADLESS = false;
const WAPO_HEADLESS = true;
async function setupBrowser(headless: boolean) {
const browser = await puppeteer.launch({ headless });
const page = await browser.newPage();
const generator = new FingerprintGenerator();
const fingerprintWithHeaders = generator.getFingerprint({});
const injector = new FingerprintInjector();
await injector.attachFingerprintToPuppeteer(page, fingerprintWithHeaders);
return { browser, page }
}
/**
* Note: NYT bot detection seems to work fairly well, so you may occasionally get blocked by their
* bot detection with this script. Changing your IP or waiting a day or so should get you unblocked.
*/
async function autoRenewNYT() {
const { browser, page } = await setupBrowser(NYT_HEADLESS)
const accounts = JSON.parse(process.env.NYT_ACCOUNTS!) as {
user: string;
pass: string;
}[];
await Promise.all(
accounts.map(async ({ user, pass }) => {
try {
await page.setViewport({ width: 1920, height: 1080 });
await page.goto(
"https://www.dclibrary.org/research-and-learn/new-york-times-digital",
{
waitUntil: "domcontentloaded",
timeout: 30000,
},
);
const elementHandle = await page.locator('.resource__link.container a').waitHandle()
const href = await (await elementHandle.getProperty('href')).jsonValue()
const [ match, campaignId, giftCode ] = href.match(/[?&]campaignId=([^&]+).*?[?&]gift_code=([^&]+)/) as string[]
await page.goto(
`https://myaccount.nytimes.com/auth/login?response_type=cookie&client_id=gftrdm&display=gift&redirect_uri=https%3A%2F%2Fwww.nytimes.com%2Factivate-access%2Faccess-code%3Faccess_code%3D${giftCode}%26source%3Daccess_code_redemption_lp%3Anews%26campaignId%3D${campaignId}`,
{
waitUntil: "domcontentloaded",
timeout: 30000,
},
);
await page.mouse.move(40, 160);
await setTimeout(3000);
await page.type("#email", user, { delay: 105 });
await page.locator('[data-testid="submit-email"]').click();
await setTimeout(3000);
await page.mouse.move(-40, -160);
await page.type("#password", pass, { delay: 120 });
await setTimeout(3000);
await page.mouse.move(70, 150);
await page.locator('[data-testid="login-button"]').click();
await setTimeout(3000);
await page.locator('[data-testid="get-started-btn"]').click();
console.log(`Successfully renewed your NYT subscription for ${user}`);
} catch (e) {
console.error(`Error renewing the NYT subscription for ${user}: ${e}`);
return Promise.reject(e);
}
}),
);
await browser.close();
}
async function autoRenewWaPo() {
const { browser, page } = await setupBrowser(WAPO_HEADLESS)
const accounts = JSON.parse(process.env.WAPO_ACCOUNTS!) as {
user: string;
pass: string;
}[];
await Promise.all(
accounts.map(async ({ user, pass }) => {
try {
await page.goto("https://www.washingtonpost.com/subscribe/signin/");
await setTimeout(3000);
await page.mouse.move(40, 160);
await page.type("#username", user, { delay: 112 });
await setTimeout(1600);
await page.mouse.move(-40, -160);
await page.locator('[data-test-id="sign-in-btn"]').click();
await setTimeout(2300);
await page.type("#password", pass, { delay: 114 });
await setTimeout(1200);
await page.mouse.move(70, 150);
await page.locator('[data-test-id="sign-in-btn"]').click();
await setTimeout(3000);
await page.goto(
"https://www.washingtonpost.com/subscribe/signin/special-offers?s_oe=SPECIALOFFER_DCPUBLICLIBRARY",
);
await setTimeout(5000);
console.log(
`Successfully renewed your Washington Post subscription for ${user}`,
);
} catch (e) {
console.error(
`Error renewing the Washington Post subscription for ${user}: ${e}`,
);
return Promise.reject(e);
}
}),
);
await browser.close();
}
async function renewAccounts() {
if (!process.env.NYT_ACCOUNTS && !process.env.WAPO_ACCOUNTS) {
console.error('ERROR: No accounts configured in your .env file! Exiting...\n')
process.exit(1);
}
if (process.env.NYT_ACCOUNTS) {
await autoRenewNYT();
}
if (process.env.WAPO_ACCOUNTS) {
await autoRenewWaPo();
}
process.exit();
}
renewAccounts();