I use the following code inside a Tampermonkey script.
function scriptMain () {
setTimeout(function(){
GM_notification ( {
title: 'Refresh Business Manager', text: 'Your about to be logged out of staging, click here to refresh your login.', image: 'https://i.sstatic.net/geLPT.png',
onclick: () => {
console.log ("My notice was clicked.");
location.reload();
}
} );
}, 5*1000);
console.log ("Script main code ran.");
}
The code shows a notification whenever a browser tab is open for more than 5 seconds which includes a button to refresh the current browser tab. I wanna use this script to alert me every 20 minutes or so, that one of the logins in the browser is about to auto-logout.
The functionality works as expected, but if I have 5 tabs open from the site where im logged in, I will get 5 notifications when the page is about to run out. I would love to be able to tell from within the Tampermonkey script if this script is already running on another tab, to not execute or to maybe just be able to only show the notification once.
I have been looking into the Tampermonkey documentation for the following Grants:
GM_getTab(callback)
GM_saveTab(tab)
GM_getTabs(callback)
But I dont seem to be able to work out if this functionality would be possible or not.
Can someone help me shine some light on this topic, or perhaps share a solution?
On modern spec-compliant browsers, you can use BroadcastChannel inside the userscript to communicate with other tabs on the same domain. Make the timeout slightly random - add or subtract a few seconds to allow for all the open tabs to coordinate. When sending a notification, also send a message in the BroadcastChannel telling other instances of the userscript to reset their timers as well.
const channel = new BroadcastChannel('logout-notify');
let timeoutId;
function makeTimeout() {
clearTimeout(timeoutId);
timeoutId = setTimeout(function () {
GM_notification({
title: 'Refresh Business Manager', text: 'Your about to be logged out of staging, click here to refresh your login.', image: 'https://i.sstatic.net/geLPT.png',
onclick: () => {
console.log("My notice was clicked.");
location.reload();
}
});
channel.postMessage('notified');
}, 1000 * 60 * 20 + (Math.random() * 10000)); // 20 minutes plus up to 10 seconds
}
// When below runs, another tab created a notification
// reset the timeout for this tab, schedule another one for 20ish minutes from now
channel.onmessage = makeTimeout;
// initialize timeout on pageload?
makeTimeout();
This code will result in alerts being shown only once every 20 minutes at most. If you close one tab you were working on, other tabs will take up the slack without interruption.