I am using Google Meet for presentations from my Surface tablet. What I do is creating a meeting with the tablet and the desktop PC attached to the projector, and then sharing the tablet screen.
It is time-consuming and boring to setup Google Meet on the desktop PC. Thus, I would like to automate the following tasks with a bookmarklet:
Until now, this is my code for Chromium-based browsers.
javascript: (() => {
document.querySelector('[data-tooltip="Turn off camera (ctrl + e)"]').click();
document.querySelector('[data-tooltip="Turn off microphone (ctrl + d)"]').click();
document.querySelector('[placeholder="Your name"]').value = "Desk PC";
join=document.evaluate("//button[contains(., 'Ask to join')]", document, null,
XPathResult.ANY_TYPE, null).iterateNext();
join.disabled = false;
join.click();
setTimeout(function() {
document.querySelector ('button[aria-label="More options"]').click()
document.evaluate("//span[contains(., 'Change layout')]", document, null,
XPathResult.ANY_TYPE, null).iterateNext().click();
document.querySelector ('input[value="Spotlight"]').click()
}, 10000);
})();
My essential problem is to send keys to the browser. With actual typing, when I write "Desk PC" in the input element, the event is detected and the join button is activated. If I set the element value with:
document.querySelector('[placeholder="Your name"]').value = "Desk PC";
the join button is not enabled. In theory, I could manually enable and click it:
join.disabled = false;
join.click();
but Meet detects this as a wrong pattern and gives an error.
I think, I should simulate sending keystrokes with dispatchEvent()
(which would also be used to send an Esc
to exit Meet layout menu). However, I am missing the logic of the function. For example, with Stackoverflow page, I expect the following code:
var evt=new KeyboardEvent('keydown', { key: "a" });
input=document.querySelector(".s-input__search");
input.dispatchEvent(evt)
to send an "a" to SO search box, but this is not what happens.
Any help?
As required in the comments, to reproduce my setting with a single computer:
(*) This simulates the tablet, and you might be required to log in to your account.
(**) This simulates the projecting desk PC, and, because this is typically shared, it's better to use it in private mode and without passwords.
Your problem keyword is actually "trusted input", and when you set value that way (with selector.value
), it wouldn't be detected as a trusted input. A workaround as of now's chrome's latest browser is to use document.execCommand
(there is no telling when this will stop working).
I modified your code a little, and I tested it in my own machine on windows 10 + chrome 110:
javascript: (() => {
document.querySelector('[data-tooltip="Turn off camera (ctrl + e)"]').click();
document.querySelector('[data-tooltip="Turn off microphone (ctrl + d)"]').click();
document.querySelector('[placeholder="Your name"]').focus();
document.execCommand('insertText', false, "Desk PC");
const join = document.evaluate("//button[contains(., 'Ask to join')]", document, null, XPathResult.ANY_TYPE, null).iterateNext();
setTimeout(() => {
setTimeout(() => {
setTimeout(() => {
document.querySelector('button[aria-label="More options"]').click();
setTimeout(() => {
document.evaluate("//span[contains(., 'Change layout')]", document, null, XPathResult.ANY_TYPE, null).iterateNext().click();
setTimeout(() => {
document.querySelector('input[value="Spotlight"]').click();
}, 500);
}, 500);
}, 500);
}, 10000);
join.click();
}, 500);
})();
I know there's a callback hell happening there, but trust me, it has to be that way lol.