fp/services/scout/src/index.browser.js
CJ_Clippy fdd295e2b8
Some checks failed
ci / build (push) Failing after 0s
change scout to a service
2024-08-26 23:11:24 -08:00

174 lines
5.0 KiB
JavaScript

// watches chaturbate for go live
import puppeteer from 'puppeteer-extra';
import { dirname } from 'path';
import { fileURLToPath } from 'url';
import StealthPlugin from 'puppeteer-extra-plugin-stealth'
import delay from 'delay'
import ReplPlugin from 'puppeteer-extra-plugin-repl'
import fsp from 'fs/promises';
import repl from 'puppeteer-extra-plugin-repl';
const __dirname = dirname(fileURLToPath(import.meta.url));
const browserDataDir = __dirname+'/futureporn-scout-datadir';
const searchInputSelector = 'body > app-root > div > div.site-wrapper.nav-bar-visible.nav-bar-top-visible > div > app-explore-route > div > app-account-explore-route > div > input'
const followButtonSelector = "xpath///app-account-follow-button/div/xd-localization-string[contains(., 'Follow')]"
const onlineIndicator = 'a.online-indicator.is-live'
// @todo Get this value from Strapi
const channels = [
'avabrooks'
]
const scrollDown = async (page) => {
console.log('scrolling down')
await page.keyboard.press('PageDown')
await page.evaluate(async () => {
window.scrollBy(0, 500);
});
}
const handleOnlineChannel = async (page) => {
const href = await page.evaluate(async () => {
const onlineIndicator = 'a.online-indicator.is-live'
const href = document.querySelector(onlineIndicator).href
return href
})
console.log(`${href} is online!`)
await fsp.appendFile('./data.csv', `${new Date().toISOString()},${href}\n`)
}
/**
* Open up a tab to the channel.
* Intercept websockets events which tell us when the channel is online
*/
const monitor = async (browser, channel) => {
if (!browser) throw new Error('monitor requires page arg');
if (!channel) throw new Error('monitor requires channel arg');
console.log(`monitoring ${channel}`)
const page = await browser.newPage();
await page.setRequestInterception(true);
const url = await new Promise((resolve) => {
page.on('request', interceptRequest => {
const url = interceptRequest.url();
console.log(url)
if (url.startsWith('wss://realtime')) {
console.log(`request! ${interceptRequest.url()} ${JSON.stringify(interceptRequest.headers(), null, 2)}`);
resolve(interceptRequest.url());
}
interceptRequest.continue();
});
page.goto(`https://chaturbate.com/${channel}`);
})
await page.repl()
}
const dash = async (page, channel) => {
console.log('check')
await page.goto(`https://chaturbate.com/${channel}`)
// look for is-live indicator
try {
console.log('waiting for home page')
await page.waitForSelector('div.stories-scroll-container', { timeout: 15000 })
console.log('waiting for online indicators')
await page.waitForSelector(onlineIndicator, { timeout: 10000 })
console.log(`FOUND online channel! ${JSON.stringify(onlineIndicator, null, 2)}`);
handleOnlineChannel(page)
delay(1000)
} catch (e) {
console.error(e)
console.log('error on the dash. lets move on.')
}
}
const discover = async (page) => {
// Navigate the page to a URL
await page.goto('https://fansly.com/explore/discover');
console.log('wait for search input')
await page.waitForSelector(searchInputSelector)
// console.log('click search input')
// await page.click(searchInputSelector)
console.log('type a random letter')
const letter = (() => {
const letters = 'abcdefghijklmnopqrstuvwxyz'
const randomIndex = Math.floor(Math.random() * letters.length);
return letters[randomIndex];
})()
await page.type(searchInputSelector, letter)
// // Start an interactive REPL here with the `page` instance.
// await page.repl()
// // Afterwards start REPL with the `browser` instance.
// await browser.repl()
let go = true
setTimeout(() => {
go = false
}, 1000*30*1) // ~2 minutes of following
while (go) {
try {
console.log('Wait for Follow/Unfollow buttons')
try {
await page.waitForSelector(followButtonSelector, { timeout: 1000 })
await page.click(followButtonSelector, { timeout: 1000 })
} catch {}
// look for is-live indicator
try {
await page.waitForSelector(onlineIndicator, { timeout: 100 })
console.log(`FOUND online channel! ${JSON.stringify(onlineIndicator, null, 2)}`);
handleOnlineChannel(page)
} catch (e) {
// console.log('online channel not found')
}
scrollDown(page)
await page.keyboard.press('PageDown')
} catch (e) {
console.error('Error while waiting for follow button')
console.error(e)
}
await delay(15000)
}
}
(async () => {
// Launch the browser and open a new blank page
puppeteer.use(StealthPlugin())
puppeteer.use(ReplPlugin())
const browser = await puppeteer.launch({
headless: false,
args: [
`--user-data-dir=${browserDataDir}`
]
});
for (const ch of channels) {
await monitor(browser, ch)
// await dash(page)
// await discover(page) // discover & follow
// await dash(page) // dashboard & see who's live
}
})();