Skip to content

Instantly share code, notes, and snippets.

@71
Last active April 18, 2024 19:39
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save 71/7296ec9d44af7d0f1fb36b053bbe2219 to your computer and use it in GitHub Desktop.
Save 71/7296ec9d44af7d0f1fb36b053bbe2219 to your computer and use it in GitHub Desktop.
Lists all participants in a Google Meet meeting.

The following bookmarket shows a popup with the name of the participants separated by newlines.

javascript:-function(maxStrLength = 2000) { try { function findParticipants(current, depth = 0) { if (depth > 7) return; if (typeof current !== "object" || current === null || current === window) return; const descriptors = Object.getOwnPropertyDescriptors(current); for (const prop in descriptors) { if (prop.startsWith('["spaces/')) return Object.values(current); const item = findParticipants(descriptors[prop].value, depth + 1); if (item !== undefined) return item; } } const rootState = Object.entries(window).find(x => x[0].startsWith("closure_lm_"))[1], participants = findParticipants(rootState), names = []; function findName(obj) { for (const prop in obj) { const value = obj[prop]; if (typeof value === "object" && value !== null && typeof value[1] === "string") return value[1]; } } for (let i = 0; i < participants.length; i++) { const name = findName(participants[i]); if (names.indexOf(name) === -1) names.push(name); } if (names.length === 0) throw new Error("Could not find any name."); names.sort((a, b) => a.localeCompare(b)); const groups = names.slice(1).reduce((groups, name) => { if (groups[0].length + name.length + 1 >= maxStrLength) { groups.unshift(name); } else { groups[0] += "\n" + name; } return groups; }, [names[0]]).reverse(); for (let i = 0, {length} = groups; i < length; i++) { const suffix = length === 1 ? "" : " (" + (i + 1) + "/" + length + ")", message = "Please find the list of participants below" + suffix + "."; if (prompt(message, groups[i]) === null) break; } } catch (e) { alert("Unexpected error when running the script: " + e); }}()

This code can be generated by evaluating:

`javascript:${await fetch("https://gist.githubusercontent.com/71/7296ec9d44af7d0f1fb36b053bbe2219/raw/google-meet-participants.js").then(x => x.text())}`.replace(/\n|\/\*[\s\S]+?\*\//g, '').replace(/ +/g, ' ')
-function(maxStrLength = 2000) {
try {
/* 1. Find the objects corresponding to the participants by recursively
walking the state of the webapp. */
function findParticipants(current, depth = 0) {
if (depth > 7)
return; /* We can find it at a lower depth. */
if (typeof current !== "object" || current === null || current === window)
return; /* We're only interested in objects. */
/* Iterate over descriptors to make sure we don't access computed properties. */
const descriptors = Object.getOwnPropertyDescriptors(current);
for (const prop in descriptors) {
if (prop.startsWith('["spaces/'))
/* We're looking for the object whose keys start with '["spaces/'. */
return Object.values(current);
const item = findParticipants(descriptors[prop].value, depth + 1);
if (item !== undefined)
return item;
}
}
const rootState = Object.entries(window).find(x => x[0].startsWith("closure_lm_"))[1],
participants = findParticipants(rootState),
names = [];
/* 2. For each object, determine the participant's name. */
function findName(obj) {
/* The property names are non-deterministic and may change at any time, but the
participant's name is always at 'participant.Aa[1]', where 'Aa' can be an
arbitrary string.
Walk the object and hope that the first match corresponds to the string. */
for (const prop in obj) {
const value = obj[prop];
if (typeof value === "object" && value !== null && typeof value[1] === "string")
return value[1];
}
}
for (let i = 0; i < participants.length; i++) {
const name = findName(participants[i]);
if (names.indexOf(name) === -1)
/* 3. Remove duplicates. */
names.push(name);
}
if (names.length === 0)
throw new Error("Could not find any name.");
/* 4. Sort the names lexicographically. */
names.sort((a, b) => a.localeCompare(b));
/* 5. Chrome limits to 2K characters the number of characters in the string given
to "prompt", so we split the output in several groups if needed. */
const groups = names.slice(1).reduce((groups, name) => {
if (groups[0].length + name.length + 1 >= maxStrLength) {
groups.unshift(name);
} else {
groups[0] += "\n" + name;
}
return groups;
}, [names[0]]).reverse();
/* 6. Finally, output all groups using "prompt". */
for (let i = 0, {length} = groups; i < length; i++) {
const suffix = length === 1 ? "" : " (" + (i + 1) + "/" + length + ")",
message = "Please find the list of participants below" + suffix + ".";
if (prompt(message, groups[i]) === null)
break; /* User pressed "Cancel", so we stop the loop. */
}
} catch (e) {
alert("Unexpected error when running the script: " + e);
}
}()
@yangpu2007360
Copy link

Hi, I am trying to show participant in a popup window in google extension. I tried your code but it did not work. Can you provide some instruction?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment