Skip to content

Instantly share code, notes, and snippets.

@aanari
Created May 14, 2025 00:25
Show Gist options
  • Save aanari/2c84502867640fd56614f7b623fd3600 to your computer and use it in GitHub Desktop.
Save aanari/2c84502867640fd56614f7b623fd3600 to your computer and use it in GitHub Desktop.
Archive Google Chat
(() => {
/* ---------- helpers ---------- */
const clean = s => s?.replace(/\s+/g, ' ').trim(); // collapse whitespace
/* ---------- collect ---------- */
const raw = [...document.querySelectorAll('span[data-message-id]')].map(span => {
const msgId = span.dataset.messageId;
const user = clean(span.innerText); // sender name
/* find the surrounding <div role="group"> that owns this message */
const group = span.closest('div[role="group"]') ||
span.closest(`div[data-id="${msgId}"]`) ||
span;
/* 1️⃣ try the canonical payload container Chat uses for text */
let body = group.querySelector('div[jsname="bgckF"]');
/* 2️⃣ fall back to a few older / edge-case selectors */
if (!body)
body = group.querySelector('[data-message-text], div[dir="auto"]');
const text = clean(body?.innerText) || ''; // empty string if nothing
/* timestamp (epoch ms) – stays the same */
const tsNode = group.querySelector('span[jsname="E53oB"]');
const tsEpoch = tsNode?.getAttribute('data-absolute-timestamp') || undefined;
return { user, text, ...(tsEpoch && { timestamp: tsEpoch }) };
});
/* ---------- output ---------- */
console.table(raw);
console.log('Users:', [...new Set(raw.map(r => r.user))]);
copy(JSON.stringify(raw, null, 2)); // ⌘-V straight into a file
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment