Skip to content

Instantly share code, notes, and snippets.

@ErykDarnowski
Last active November 11, 2023 09:35
Show Gist options
  • Save ErykDarnowski/a78e3476e6122e77c7f00aab8eb18d15 to your computer and use it in GitHub Desktop.
Save ErykDarnowski/a78e3476e6122e77c7f00aab8eb18d15 to your computer and use it in GitHub Desktop.
Download FB messenger chat / group chat to txt file (for PL language)
/* Releases
- 1.0.0 Initial
- 1.0.1 Remove '\n' between each msg
*/
const config = {
numbered: true, // whether to number the messages
yourResponsesMargin: 90, // amount of ' ' char
msgsSelector: '__fb-dark-mode x1n2onr6', // message block class (10.11.2023 for first open from right)
defaultChatEmoji: [ 'Gest kciuka w górę', '👍' ], // [string for default emoji ; what to replaec it with]
};
let msgStrsArr = [];
let msgsTranscript = '';
const msgs = [...document.getElementsByClassName(config.msgsSelector)]; // <- getting all available msgs (from popoup on the bottom right side - needs to be scrolled far enough to get all msgs)
const download = (filename, text) => { // dynamically creates and automatically downloads text file with given content
const el = document.createElement('a');
el.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
el.setAttribute('download', filename);
el.style.display = 'none';
document.body.appendChild(el);
el.click();
document.body.removeChild(el);
};
msgs.map(el => {
const personName = el.getElementsByTagName('span')[0]?.textContent;
let msg = el.textContent;
// separating between duplicate msgs (picking one with 'trash' strings)
if (msg.includes('Otwórz')) {
// removing 'trash' strs
msg = msg.replace('Wysłano', '').replace('Otwórz', '');
// replacing default chat emoji
msg = msg.replace(...config.defaultChatEmoji);
// removing person's name and adding margin to your msgs
msg = '\n' + (msg.includes(personName) ? msg.replace(personName, '') : ' '.repeat(config.yourResponsesMargin) + msg)
// ^ checking who sent the msg ^ removing friend's name ^ adding margin to your msgs
// temp img solution
if (msg === '\n') msg = '\n~img~';
if (config.numbered) {
msgStrsArr.push(msg);
} else {
msgsTranscript += msg;
};
};
});
// adding nums to msgs
if (config.numbered) {
const maxCountStrLen = msgStrsArr.length.toString().length;
//msgStrsArr = msgStrsArr.reverse();
for (let i = 0; i < msgStrsArr.length; i++) {
msgsTranscript += '\n{' + (i + 1).toString().padStart(maxCountStrLen, '0') + '} ' + msgStrsArr[i].substring(1);
// removes first `\n` ^
};
};
// Start download of output file
download('transcript.txt', msgsTranscript.substring(2));
// removes the first 2x `\n` ^
// goofy solution a lot to fix but hey, it works
// Config:
let counter = 0;
let iterations = 200;
let delay = 500;
let scrollCount = 0;
for (let i = 0; i < iterations; i++) {
console.log(`${counter += 1} / ${iterations}`);
const msgContainer = document.querySelector("#mount_0_0_5b > div > div:nth-child(1) > div > div:nth-child(6) > div > div.xuk3077.x78zum5.xc8icb0 > div.x1ey2m1c.x78zum5.x164qtfw.xixxii4.x1vjfegm > div > div > div > div > div > div.x78zum5.xdt5ytf.x1iyjqo2.x193iq5w.x2lwn1j.x1n2onr6 > div.x78zum5.xdt5ytf.x1iyjqo2 > div > div > div > div > div > div")
// scroll up till the next batch loads
msgContainer.scroll(0, scrollCount -= 9999999);
// some delay before next scroll
await new Promise(resolve => setTimeout(resolve, delay));
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment