const fetch = require('node-fetch'); const cache = {}; const default_headers = { 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'accept-language': 'en-US,en;q=0.9', 'upgrade-insecure-requests': '1', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36', }; function isFull(t) { return (t.includes('This beta is full.') || t.includes('This beta isn\'t accepting any new testers right now.')); } function getName(t) { return (t.includes('Join the ') ? t.split('<title>Join the ')[1].split(' - TestFlight - Apple')[0] : 'App'); } async function do_request(a, h, m = 'GET', d = null) { const r = await fetch(a, { headers: Object.assign(h), method: m, redirect: 'manual', body: m == 'POST' ? JSON.stringify(d) : null, }); return (await r.text()); } (async () => { setInterval(async () => { console.log('Refreshing now.'); const p = { id: process.env.TESTFLIGHT_ID, url: process.env.DISCORD_WEBHOOK_URL, }; const r = await do_request('https://testflight.apple.com/join/' + p.id, default_headers); if (!isFull(r)) { if (!cache[p.id]) { const message = getName(r) + ' is available at https://testflight.apple.com/join/' + p.id; if (p.url) { await do_request( p.url, Object.assign(default_headers, { 'Content-Type': 'application/json' }), 'POST', { 'content': message }, ); } console.log(message); } cache[p.id] = true; } else { delete cache[p.id]; console.log(getName(r) + ' is still full.'); } }, 30000); })();