Web Notifications API - Only show once per period - javascript

I'm writing a web app that needs to send notifications. It checks 12 different things every 30 seconds and if one of them meets the criteria it should send a notification; it then shouldn't send another notification until the next 30 minute (on the hour and half past the hour) interval. How do you check if a notification has already been sent and not to send it again? I thought this was done via tags but two notifications with the same tag will still pop-up, the second will just replace the first.
The function used to generate the notification is
function randomNotification(whoisit, tagtoPass) {
var message = whoisit + " is getting a notification";
var options = {
body: message,
icon: 'logo.png',
tag: tagtoPass,
}
var n = new Notification('Website Says:',options);
setTimeout(n.close.bind(n), 5000);
}
That function is called from another script that is loaded via Ajax every 30 seconds. That script checks the database to see if one of the 12 things is in a state that requires a notifications then calls the function and passes the name and a unique tag for that 30 minute interval.
Also I've noticed with this code, which was based on the developer docs from Mozilla on Notifications API, doesn't add the notification to the OS X Notification Centre.

Have you considered using a flag in localStorage to store the time when the last notification was sent?
Let's say that you store the time when you send the first notification, then check it again and if it's old enough you send another one and update that flag.
localStorage data will stay even if you refresh the web page.
Example:
localStorage.setItem("last_notification", timestamp)
localStorage.getItem("last_notification")
Reference: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage

Related

How to insert into database every x seconds, but that the user cannot change time to the inspect element?

I want to insert 1 point into the database every x seconds, but I don't want to allow a user that he can speed up that time into inspecting element. How can I do that?
var time = 1;
var interval = setInterval(function() {
if (time != time + 1) {
//some ajax code for sending points into database
time++;
}
}, 5000);
This code is what I looking for but user easy can change this 5000 to etc. 500 and speed up the process of getting point. Is there any way to prevent the user from changing that time?
Assuming that your ajax calls a PHP page, you should rate limit within the PHP (server-side) so that it cannot be modified by the user.
As it has been pointed out in the comments to your question, this task isn't well suited to ajax as it will constantly open and close connections which can degrade network performance and could trigger a WAF to start blocking those requests. You should use a WebSocket instead or send your data in bulk via ajax at a slower rate.

Backend only alternative to javascript periodic function call?

I have the following in my js file that is included in the main .cshtml page of my ASP.NET MVC application:
var ajax_call = function () {
$.ajax({
type: "GET",
cache: false,
url: "/Session/Index/",
success: function (result) {
if (!(result.length > 0)) {
window.location.href = '/Home/Index/'
}
}
});
};
var interval = 1000 * 60 * .2; // where X is your every X minutes---.2 -> every 12 seconds
setInterval(ajax_call, interval);
The goal is to check if the session is still valid (the SessionController only returns a result if the session is active), otherwise the browser gets redirected to Home/Index, where HomeController has a global authorization attribute that redirects to the login page if the log in is not a valid session.
My questions are, is this a valid approach? It works (if I login in with a user, then open a new window and log in with the same user in the new window, the old window gets redirected to the login screen shortly after, depending on where it is in the 12 second cycle), but is there a way I can do such a thing entirely in the backend?
Thank you.
The goal is to check if the session is still valid
This is not a good approach, because a request to a server will rest the session timeout to 0. It means you are making session alive forever. If a user forgets to close the browser and leave the computer open, other can still access the account.
Here is the approach I use in my websites inspired by banking/credit card websites.
By default, Session Time out is 20 minutes (you can adjust the way you want). So, I let timer run at client side. When it reaches 19 minutes, I display a popup message with a minute count down timer.
If use does not close the popup, I redirect to logout page.
Here is the concept and sample code, but you do not need to use Telerik control to achieve it.

Chrome extension - Background page and unread items

I'm making my first chrome extension and i'm stuck just before the end.
I'm getting a response from a server in json, outputing the html, cache it in localstorage check if there's cache if not getting again from server and then displaying.
Now. In the background.js I need to check every 30 mins if there're updates in the json file on the server... if any display a Badge, once clicked remove badge till next time. but I don't know what to do. Because if I make a setInterval it hits the server and always display a badge even if there's nothing new. Can you guy help me build the js, please?
<script>
setInterval(function(){
chrome.browserAction.setBadgeText({text:chrome.browserAction.setBadgeText({text: "!!!"});});
}, 1800000);
</script>
I've also tried this way, but nothing happens.
function getUnreadItems(callback) {
$.ajax(..., function(data) {
process(data);
callback(data);
});
}
function updateBadge() {
getUnreadItems(function(data) {
chrome.browserAction.setBadgeText({text:data.unreadItems});
});
}
var pollInterval = 1*60*60; // 60 min
var timerId;
function startRequest() {
updateBadge();
timerId = window.setTimeout(startRequest, pollInterval);
}
function stopRequest() {
window.clearTimeout(timerId);
}
background.js
onload='startRequest()'
It looks like you never reset the unread items to "read" on the server, so every time you will ping the server, it will reply with the same number and will thus display that number again.
So you can do a couple of things:
when you click your button and reset the badge to 0, you can send a request to the server to mark all the items as read. Which request will of course depend on your server and what it accepts. That way, the unread count on the server will always be up to date and your extension can be very "stupid": whatever is returned by the server is the current number of unread items.
if you can't do that, you'll have to save some information locally to your extension and figure out the unread count yourself. What I mean by that is that instead of just requesting the unread count you'll need to get information about the specific items like a unique ID. Then every time you poll the server for the list of items, you add the IDs to a list saved in localStorage for example (or chrome.storage.sync) with a viewed tag set to false if that ID is not known yet. The background script will then go through that list and count the number of items that have a viewed tag set to false and use that as an unread count. Whenever you open the popup, you go through your whole list and set the viewed tag to true for all your items.
I've done something similar for an extension to get your Hulu playlist. I did the first option when I delete a video from your playlist, so that it's removed locally and on the server as well. And I did the second option because I wanted to show a count for new videos, but Hulu doesn't keep track of that. (it knows played and unplayed, but not "you've been notified that this new video is available" which I wanted.
See in particular, this section:
// Testing that it's the first time I'm seeing this show
if (show_ids.indexOf(new_show.id) == -1) {
new_shows_number++;
new_show.seen = "no";
} else {
new_show.seen = "yes";
}
Here show_ids is the list of IDs I've already saved and marked as viewed locally. If new_show.id is not in this list, that means it's an unviewed item.

Counter Box, Visible for all clients

Hello I need a button for my website, that will start a countdown from 60 secounds to 0, then it should display some text (lets drink, cheers) and go back to start button.
All users must be able to see this countdown, so that when a user start the countdown other users can see this.
It should also display a counter, of howmany user have clicked the button, and joining in on the "button"
I have looked into this, but i need to do Ajax / javascript pulling.
Since my programming skill is still on copy/paste/edit level, I do not know howto get started, I can build the timer, but dont know howto do the pulling.
can anyone help me get started.
Regards
René
Well first of all, you need a stateful backend, to store a usercount. So php+any db.
you mentioned socket.io, build on nodejs.
With nodejs this aint this difficult, because its a single threaded runtime, so you can share variable values to different clients.
your nodejs have to listen to 3 urls:
for passing the basing page ( can be done without nodejs, just url to html)
ajax url for passing clicks on a button from client to backend, returns current count
ajax url to pass the current seconds, returns current count and connected users.
everytime the 2. channels gets called, you need to check , if the countdown is alrdy running. if not: start it, else increase clicked counter.
like this:
//nodejs code
var currendSeconds=60;
var connectedClients = 0;
var threadid;
function clientClickedButton(req, res){ // 2. url
if(currendSeconds==60 || ) {
threadid = setInterval(function(){
currendSeconds--;
if(currentSeconds == 0){
clearInterval(threadid);
}
}, 1000); //your counter
}
connectedClients++;
res.send(currendSeconds);
}
your clientside have to listen to click event on the button, send a ajax req to 2.url and display the returned seconds ( from now on our dont need to request the seconds, just set up a count down clientside, without requesting the current seconds. )

Listener on Javascript/Jquery

I have a web service where I fetched my data and populate it in my client. As of now, I have a button that will fetch data from the web service when clicked using ajax get. On my web service, I have a maintenance where I will be able to add, edit or delete data. What I want to do is to have my client automatically fetched data from my web service everytime I add, edit, or delete data, so it will show accurate data to the client.
Here's what I'm thinking. On my web service, i will have a json that will tell true/false whether the data has been updated (will be fetched by the client). So every add, edit, delete will turn that to true, and every time the client fetched that data, it will become false.
Now, I need to have a javascript/jquery listener that will listen to any change in that json (the true or false). I need to have that listener run every second? Is it possible?
Thanks.
EDITED:
I've been rereading my post, and it hits me, I'm just thinking with only one client in my mind. Every add,edit,delete in my web service will turn the "updated" to true, and everytime I get a request for the data, I'll set it to false. But how about the other clients? When they sent a request, it's already false, so they will not update it. Any ideas? Thanks
You can do this using two aproaches:
Web sockets; or
setInterval function.
Here is an example of setInterval().
// just a control var...
var gen = 1;
// call the function repeatedly in 5 seconds of interval
// this call returns an id that can be used to stop the calls
var id = setInterval(function(){
// function body...
alert( "making an ajax request...(" + gen + ")" ); // here you call your webservice
gen++;
// just want to stop it, but you wont need this.
if ( gen == 10 ) {
clearInterval( id );
}
}, 5000 ); // 5000 miliseconds == 5 seconds
Some links:
jsFiddle: http://jsfiddle.net/davidbuzatto/EyCSb/
https://developer.mozilla.org/en/DOM/window.setInterval
https://developer.mozilla.org/en/DOM/window.clearInterval
You've got two HTTP options: polling the server, or using a comet request. If you're polling, it might work better to include the last updated time in the request so the server can filter any events older than that time. That way, you don't need to save an extra flag for every event for every client.

Categories