|
|
const puppeteer = require('puppeteer'); const fs = require('fs').promises;
const FACEBOOK_URL = '<%POSTURL%>';
const isLoggedIn = async (page) => { const current_url_cookies = await page.cookies(); if(current_url_cookies.filter(x=>x.name == 'c_user').length == 0){ throw 'Not Login'; } };
const loginWithSession = async (cookies, page) => { await page.setCookie(...cookies); await page.goto(FACEBOOK_URL, { waitUntil: 'networkidle2' }); await isLoggedIn(page).catch((error) => {
throw error; }); }
const loginWithCredentials = async (username, password, page) => { //console.log('Logging into Facebook using credentials for', username);
await page.goto(FACEBOOK_URL, { waitUntil: 'networkidle2', });
await page.waitForSelector('input[name=email]'); await page.click('input[name=email]'); await page.type('input[name=email]', username);
await page.waitForSelector('input[name=pass]'); await page.click('input[name=pass]'); await page.type('input[name=pass]', password); const cookieBanner = 'div[data-testid="cookie-policy-banner"]'; if (await page.$(cookieBanner) !== null) { //console.log('Facebook cookie banner found'); await page.evaluate((selector) => { const elements = document.querySelectorAll(selector); for (let i = 0; i < elements.length; i += 1) { elements[i].parentNode.removeChild(elements[i]); } }, cookieBanner); }
await page.waitForSelector("div[aria-label='Accessible login button']"); await page.click("div[aria-label='Accessible login button']"); await page.waitForNavigation(); await isLoggedIn(page).catch((error) => { console.error('App is not logged into Facebook'); throw error; }); }
const getDefaultBrowser = async (headless) => { const browser = await puppeteer.launch({ headless: false, devtools: false, args: ['--no-sandbox', '--disable-setuid-sandbox',"--disable-notifications"], }); const context = browser.defaultBrowserContext(); context.overridePermissions(FACEBOOK_URL, []); return browser; };
const getDefaultPage = async (browser) => { const page = await browser.newPage(); await page.setViewport({ width: 1920, height: 1000 }); return page; };
(async () => { const browser = await getDefaultBrowser(true); const page = await getDefaultPage(browser); const username = '<%ACCOUNT%>'; const password = '<%ENTERCODE%>';
// Load cookies from previous session const cookies = await fs.readFile('cookies.js') .then((facebookCookies) => JSON.parse(facebookCookies)) .catch((error) => { console.error(`Unable to load FB cookies file: ${error}`); return {}; }); // use for debug //await page.cookies().then(async (freshCookies) => { //console.log(JSON.stringify(freshCookies, null, 2)); //});
// Use our cookies to login. If it fails fallback to username and password login. if (cookies && Object.keys(cookies).length) { await loginWithSession(cookies, page).catch(async (error) => { console.error(`Unable to login using session: ${error}`); await loginWithCredentials(username, password, page); }); } else { await loginWithCredentials(username, password, page); }
// Save our freshest cookies that contain our Facebook session await page.cookies().then( async(freshCookies) => { await fs.writeFile('cookies.js', JSON.stringify(freshCookies, null, 2)).catch(async (error)=>{ await fs.access('cookies.js', fs.F_OK); await fs.writeFile('cookies.js', JSON.stringify(freshCookies, null, 2)); }); });
await page.waitForSelector("div[aria-label='可對此貼文採取的動作']"); await page.click("div[aria-label='可對此貼文採取的動作']");
await page.waitForXPath('//span[contains(text(), "編輯貼文")]'); // const linkEx = await page.$x('//span[contains(text(), "編輯貼文")]');
if (linkEx.length > 0) { await linkEx[0].click(); }
await page.waitForSelector("div[aria-label='移除貼文附件']"); await page.click("div[aria-label='移除貼文附件']");
await page.waitForSelector("div[aria-label='相片/影片']"); //await page.click("div[aria-label='相片/影片']"); try{ const [fileChooser] = await Promise.all([ page.waitForFileChooser(), page.click("div[aria-label='相片/影片']") ]); await fileChooser.cancel() ; } catch(e) { console.error(`Unable Get Dialog: ${e}`); }
// get the ElementHandle of the selector above // aria-label="附加相片或影片" //const inputUploadHandles = await page.$x("//input[contains(@accept,'video')]"); // const inputUploadHandle = inputUploadHandles[0]; await page.waitForXPath('//input[@multiple]'); await page.waitForTimeout(2000); var inputUploadHandles = await page.$x('//input[@multiple]'); var inputUploadHandle = inputUploadHandles[0];
// prepare file to upload, I'm using test_to_upload.jpg file on same directory as this script // Photo by Ave Calvar Martinez from Pexels https://www.pexels.com/photo/lighthouse-3361704/
const files = await Promise.all(<%UPLOAD_MEDIA_JSONARRAY%>);
// Sets the value of the file input to fileToUpload await inputUploadHandle.uploadFile(...files);
await inputUploadHandle.evaluate(upload => upload.dispatchEvent(new Event('change')));
await page.waitForTimeout(4000); await page.waitForSelector("div[aria-label='儲存']"); await page.click("div[aria-label='儲存']"); await page.waitForTimeout(10000);
console.log('OK');// Necessary, RPA success status check
await page.close(); await browser.close();
})();
|