Last active
October 1, 2024 10:28
-
-
Save letelete/843437eb21236b22adcb449194b0c6dc to your computer and use it in GitHub Desktop.
Slack members scrapper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Slack members scrapper. | |
* | |
* Downloads a .csv file with members details. | |
* | |
* 1. Open /people on slack webapp: https://app.slack.com/client/<WORKSPACE_ID>/people | |
* 2. Paste it into the console | |
*/ | |
(() => { | |
class CSVTransformer { | |
#columns = []; | |
/** | |
* @description Creates a new CSV transformer. | |
* @param {DataEntry[]} data An array of entries to include in the CSV file. | |
*/ | |
constructor(data) { | |
this.data = data; | |
} | |
/** | |
* @description Add a new column that will be respected with the `build` method. | |
* @param {string} label A column title. | |
* @param {(item: DataEntry) => void} transformer Extract column data from the `data` entry. | |
* @returns `CSVTransformer` | |
*/ | |
withColumn(label, transformer) { | |
this.#columns.push({ label, transformer }); | |
return this; | |
} | |
/** | |
* @description Build raw string of CSV formatted `data`. | |
* @returns string | |
*/ | |
build(delimiter = ";") { | |
const header = `${this.#columns.map(({ name }) => name).join(delimiter)}`; | |
const rows = this.data.map((item) => | |
this.#columns | |
.map(({ transformer }) => transformer(item)) | |
.join(delimiter) | |
); | |
return [header, ...rows].join(`\n`); | |
} | |
} | |
class SlackScrapper { | |
#selectors = { | |
memberCard: { | |
default: '[data-qa="browse_page_member"]', | |
image: "img", | |
name: '[data-qa="browse_page_member_card_entity__name_text"]', | |
}, | |
}; | |
getAllMembers() { | |
return [ | |
...document.querySelectorAll(this.#selectors.memberCard.default), | |
].map((card) => { | |
const imageUrl = card.querySelector( | |
this.#selectors.memberCard.image | |
).src; | |
const name = card.querySelector( | |
this.#selectors.memberCard.name | |
).innerHTML; | |
return { imageUrl, name }; | |
}); | |
} | |
} | |
function downloadAsFile(fileContent, fileName, fileExtension) { | |
const hiddenElement = document.createElement("a"); | |
hiddenElement.href = "data:attachment/text," + encodeURI(fileContent); | |
hiddenElement.target = "_blank"; | |
hiddenElement.download = `${fileName}.${fileExtension}`; | |
hiddenElement.click(); | |
} | |
function run() { | |
const slackScrapper = new SlackScrapper(); | |
const members = slackScrapper.getAllMembers(); | |
const csvContent = new CSVTransformer(members) | |
.withColumn("IMAGE_URL", (item) => item.imageUrl) | |
.withColumn("NAME", (item) => item.name) | |
.build(); | |
downloadAsFile(csvContent, "slack-members", "csv"); | |
} | |
run(); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment