Created
August 16, 2025 08:20
-
-
Save eferbarn/a1951e9d42b3b171cd8de014840d6ff7 to your computer and use it in GitHub Desktop.
randomMenionPicker
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
| (function () { | |
| // Helpers | |
| const cleanText = (el) => (el ? (el.innerText || el.textContent || "").replace(/\s+/g, " ").trim() : ""); | |
| const scrapeMentions = () => { | |
| const nodes = Array.from(document.querySelectorAll('div[data-testid="cellInnerDiv"] article[data-testid="tweet"]')); | |
| const items = []; | |
| for (const tw of nodes) { | |
| try { | |
| const timeEl = tw.querySelector('time'); | |
| if (!timeEl) continue; | |
| const iso = timeEl.getAttribute('datetime'); | |
| if (!iso) continue; | |
| const date = new Date(iso); | |
| const nameBlock = tw.querySelector('[data-testid="User-Name"]'); | |
| const handleMatch = nameBlock?.textContent?.match(/@\w+/); | |
| const handle = handleMatch ? handleMatch[0] : "@unknown"; | |
| const textEl = tw.querySelector('[data-testid="tweetText"]'); | |
| const text = cleanText(textEl); | |
| if (!text) continue; | |
| items.push({ handle, date, iso, text }); | |
| } catch (_) {} | |
| } | |
| items.sort((a, b) => a.date - b.date); | |
| return items; | |
| }; | |
| const labelRelative = (baseDate, d) => { | |
| const diffHours = (d - baseDate) / (1000 * 60 * 60); | |
| // Using the first mention as t0: | |
| // If the mention time is >= 24h after t0 => "after 24h" | |
| // Otherwise => "before 24h" | |
| return diffHours >= 24 ? "after 24h" : "before 24h"; | |
| }; | |
| const formatLine = (item, baseDate) => { | |
| const when = item.date.toLocaleString(); | |
| const rel = labelRelative(baseDate, item.date); | |
| const snippet = item.text.slice(0, 100); | |
| return `${item.handle} at ${when} | ${rel}: ${snippet}...`; | |
| }; | |
| const pickRandom = (arr, n) => { | |
| const copy = arr.slice(); | |
| for (let i = copy.length - 1; i > 0; i--) { | |
| const j = Math.floor(Math.random() * (i + 1)); | |
| [copy[i], copy[j]] = [copy[j], copy[i]]; | |
| } | |
| return copy.slice(0, Math.min(n, copy.length)); | |
| }; | |
| window.createMentionReporter = function () { | |
| const mentions = scrapeMentions(); | |
| if (!mentions.length) { | |
| console.warn("No mentions found. Scroll to load more, then try again."); | |
| return { printAll: () => {}, printRandom: () => {} }; | |
| } | |
| const baseDate = mentions[0].date; | |
| const printAll = () => { | |
| for (const m of mentions) console.log(formatLine(m, baseDate)); | |
| }; | |
| const printRandom = (n = 5) => { | |
| console.log("β".repeat(80)); | |
| const picks = pickRandom(mentions, n); | |
| for (const m of picks) console.log(`πππ ${formatLine(m, baseDate)}`); | |
| }; | |
| return { printAll, printRandom, _mentions: mentions, _base: baseDate }; | |
| }; | |
| window.listMentions = function (n = 5) { | |
| const r = window.createMentionReporter(); | |
| if (!r || !r._mentions || !r._mentions.length) return; | |
| r.printAll(); | |
| r.printRandom(n); | |
| }; | |
| })(); | |
| const r = createMentionReporter(); | |
| listMentions(2); | |
| // βorβ | |
| // r.printAll(); | |
| // r.printRandom(2) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment