Last active
June 9, 2023 17:36
-
-
Save jonathansampson/1da625d8d9e8913a70374f59f0fd4d67 to your computer and use it in GitHub Desktop.
When viewing a list of users who retweeted a Tweet, these functions can extract that list from the global React state, making it easier to analyze the accounts for commonalities and other patterns.
This file contains 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
const SELECTORS = { | |
RT_ROOT: "div[aria-label='Timeline: Retweeted by']", | |
REACT_ROOT: "#react-root > div > div", | |
}; | |
/** | |
* Retrieve the properties of a React element. | |
* @param {Object} element - The target React element. | |
* @returns {Object} The properties of the given React element. | |
* @throws Will throw an error if React props are not found. | |
*/ | |
function getReactProps(element) { | |
const key = Object.keys(element).find((key) => | |
key.startsWith("__reactProps") | |
); | |
if (key) { | |
return element[key]; | |
} | |
throw new Error("React props not found"); | |
} | |
/** | |
* Retrieves the properties of a React element from a specified selector. | |
* @param {string} selector - The CSS selector of the target React element. | |
* @returns {Object} The properties of the React element found at the selector. | |
* @throws Will throw an error if the element is not found. | |
*/ | |
function getReactPropsFromSelector(selector) { | |
const element = document.querySelector(selector); | |
if (!element) { | |
throw new Error("Element not found"); | |
} | |
return getReactProps(element); | |
} | |
/** | |
* Retrieves user data for a given user ID. | |
* @param {string} userID - The unique identifier of the user. | |
* @returns {Object} The user data for the given user ID. | |
*/ | |
function getUserData(userID) { | |
const reactProps = getReactPropsFromSelector(SELECTORS.REACT_ROOT); | |
const state = reactProps.children.props.store.getState(); | |
return state?.entities?.users?.entities?.[userID]; | |
} | |
/** | |
* Retrieves the data of users who retweeted a tweet. | |
* @returns {Array} An array containing the data of all users who retweeted a tweet. | |
*/ | |
function getRetweeters() { | |
const retweeters = new Map(); | |
const reactProps = getReactPropsFromSelector(SELECTORS.RT_ROOT); | |
for (const child of reactProps.children.filter(Boolean)) { | |
const items = child?.props?.items; | |
if (!items) { | |
continue; | |
} | |
for (const item of items) { | |
const { id } = item.content; | |
if (!retweeters.has(id)) { | |
const userData = getUserData(id); | |
retweeters.set(id, userData); | |
} | |
} | |
} | |
return [...retweeters.values()]; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment