You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

187 lines
5.5 KiB

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();
})();