Skip to content

Instantly share code, notes, and snippets.

@vegerot
Last active October 1, 2022 03:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vegerot/5ac0405f2166e7b2c5470b07e0c56710 to your computer and use it in GitHub Desktop.
Save vegerot/5ac0405f2166e7b2c5470b07e0c56710 to your computer and use it in GitHub Desktop.
Notify you when someone in a Zoom call says something
/*
Steps to use this:
1. Join a Zoom call from the web
2. Enable Live Transcription
3. Open the console (Cmd + Opt + J)
4. Paste this code into the console
*/
// In order to be able to paste this script multiple times in the console,
// check if it's already been defined and disconnect it
var observeDomNodeAdditions;
if (typeof observeDomNodeAdditions !== 'undefined') observeDomNodeAdditions.disconnect()
observeDomNodeAdditions = new MutationObserver(mutations => {
for (let mutation of mutations) {
for (let addedNode of Array.from(mutation.addedNodes)) {
if (addedNode instanceof HTMLElement) {
// unfortunately these are the only details we get
if (addedNode.tagName === 'DIV') {
// it takes a few frames for the transcript node to appear after this node appears
setTimeout(() => {
// makes TypeScript happy
if (!(addedNode instanceof HTMLElement)) {
throw new Error('impossible')
}
let subtitlesElement = addedNode.querySelector('#live-transcription-subtitle');
if (subtitlesElement) {
observeTranscriptTextChanges.observe(subtitlesElement, {characterData: true, subtree: true})
}
}, 100)
}
}
}
for (let removedNode of Array.from(mutation.removedNodes)) {
if (removedNode instanceof HTMLElement) {
if (removedNode.querySelector('#live-transcription-subtitle')) {
console.log("removed", {removedNode})
observeTranscriptTextChanges.disconnect()
}
}
}
}
})
/**
When somebody's talking
```html
<div class="meeting-client-inner">
<div id="wc-content"></div>
<div
class="join-dialog"
role="presentation"
style="bottom: 52px; width: 1792px;"
></div>
<div></div>
<div>
<div
class="live-transcription-subtitle__box react-draggable"
style="touch-action: none; bottom: 68px; transform: translate(0px, 0px);"
>
<div
id="live-transcription-subtitle"
class="live-transcription-subtitle__item"
>
Would someone from List Service please respond?
</div>
</div>
</div>
<div></div>
</div>;
```
When nobody's talking
```html
<div class="meeting-client-inner">
<div id="wc-content"></div>
<div
class="join-dialog"
role="presentation"
style="bottom: 52px; width: 1792px;"
></div>
</div>;
```
*/
observeDomNodeAdditions.observe(document.querySelector('.meeting-client-inner'), {childList: true, subtree: true, })
let keywords = [
"list",
"regist",
"regest",
"heart",
"favorite"
]
let observeTranscriptTextChanges = new MutationObserver(mutations => {
for (let mutation of mutations) {
let text = mutation.target.textContent
if (text) {
respondToKeyWords(text)
}
}
})
function respondToKeyWords(text) {
for (let keyword of keywords) {
if (text.toLowerCase().includes(keyword)) {
let msg = new SpeechSynthesisUtterance(`I heard the word`)
debouncedSpeak(msg)
debouncedLog(text)
}
}
}
function debounce(func, timeout = 1000){
let timer = 0;
return function(...args) {
clearTimeout(timer);
timer = setTimeout(() => { func.apply(this, args); }, timeout);
};
}
let debouncedSpeak = debounce((...args)=>window.speechSynthesis.speak(...args), 1000)
let debouncedLog = debounce((...args)=>console.log(...args), 1000)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment