I've been working with getstream.io for a while
and currently I'm facing an issue with the notifications.
To start using notifications I thought it was easier to implement in reactions due to having the targetFeeds property, but I'm facing an access error. I'm trying achieve it doing the next.
UserA commenting in UserB publication
// Client is initialized with UserA info
const comment = await client.reactions.add('comment', activity.id, { data }, { targetFeeds: [`notifications:UserB.ID`] });
My question is how to send a notification to UserB notification feed.
The result I expect is userB receiving a notification like "userA has commented in your publication" or alike.
I believe the default feed for notifications is 'notification' (no s.)
Also I'm not fully aware of what you are tying to accomplish, but just a heads up there is also the TO field for targeting.
https://getstream.io/docs/targeting/?language=js
The issue as first pointed by Sanchaz was that I was using notifications as slug for the notification feed instead of notification, I thought that wasn't the case because I created the notification feed with notifications slug.
StreamIO support stated that if the notification feed doesn't match notification slug, the default permissions doesn't apply, therefore the solution was to rename the slug from notifications to notification.
I am trying to implement notifications that do not need the interaction of the backend to be shown. The use of this is to put a remind me button, that would send a notification on certain time of the day (that the user specified). I am pretty new to service workers but I understand that they work asynchronously. That being said, is there any way in which I could do something like the following pseudocode?
function timeLeft(time){
setTimeout(() => showNotification(), time);
}
This would work if I put it on a regular javascript file and the user has the browser still open.
It does not need to be exactly like that, it just needs to solve my problem. Thank you un advance.
First you need to have an ID for each browser. If you use the Push API, then you can use the browser endpoint.
When a user adds a reminder, you must store the tuple (endpoint, send_at, reminder) in your database on your server
Run a cron job on your server (or create a scheduled job with Sidekiq, etc.) in order to send the reminder at the correct time (using the Push API)
Otherwise you can use a service which allows you to create scheduled notifications: see this example on my blog.
I am building a simple support chat for my website using Ajax. I would like to check if the user that I am currently chatting with left the browser.
At the moment I have build in that feature by setting interval function at customer side that creates the file with name: userId.txt
In the admin area I have created an interval function that checks if userId.txt exists. If it exists, it deletes it. If the file is not recreated by the custom interval function - next time the admin function will find out that file is not there it mark customer with this userId as inactive.
Abstract representation:
customer -> interval Ajax function -> php [if no file - create a new file]
admin -> interval Ajax function -> php [if file exists - delete the file] -> return state to Ajax function and do something
I was wondering if there is any better way to implement this feature that you can think of?
My solution is to use the jquery ready and beforeunload methods to trigger an ajax post request that will notify when the user arrives and leaves.
This solution is "light" because it only logs twice per user.
support.html
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
//log user that just arrived - Page loaded
$(document).ready(function() {
$.ajax({
type: 'POST',
url: 'log.php',
async:false,
data: {userlog:"userid arrived"}
});
});
//log user that is about to leave - window/tab will be closed.
$(window).bind('beforeunload', function(){
$.ajax({
type: 'POST',
url: 'log.php',
async:false,
data: {userlog:"userid left"}
});
});
</script>
</head>
<body>
<h2>Your support html code...</h2>
</body>
</html>
log.php
<?php
//code this script in a way that you get notified in real time
//in this case, I just log to a txt file
$userLog = $_POST['userlog'];
file_put_contents("userlog.txt", $userLog."\n", FILE_APPEND );
//userid arrived
//userid left
Notes:
1 - Tested on Chrome, FF and Opera. I don't have a mac so I couldn't test it on Safari but it should work too.
2 - I've tried the unload method but it wasn't as reliable as beforeunload.
3 - Setting async to false on the ajax request means that the statement you are calling has to complete before the next statement, this ensures that you'll get notified before the window/tab is closed.
#Gonzalon makes a good point but using a normal DB table or the filesystem for constantly updating user movement would be exhaustive to most hard disks. This would be a good reason for using shared memory functions in PHP.
You have to differentiate a bit between the original question "How do i check in real-time, if a user is logged in?" and "How can i make sure, if a user is still on the other side (in my chat)?".
For a "login system" i would suggest to work with PHP sessions.
For the "is user still there" question, i would suggest to update one field of the active session named LAST_ACTIVITY. It is necessary to write a timestamp with the last contact with the client into a store (database) and test whether that is older than X seconds.
I'm suggesting sessions, because you have not mentioned them in your question and it looks like you are creating the userID.txt file manually on each Ajax request, right? Thats not needed, unless working cookie and session-less is a development requirement.
Now, for the PHP sessions i would simply change the session handler (backend) to whatever scales for you and what makes requesting information easy.
By default PHP uses the session temp folder to create session files,
but you might change it, so that the underlying session handler becomes a mariadb database or memcache or rediska.
When the users sessions are stored into a database you can query them: "How many users are now logged in?", "Who is where?".
The answer for "How can I check in real time if a user is logged in?" is, when the user session is created and the user is successfully authenticated.
For real-time chat application there are a lot of technologies out there, from "php comet", "html5 eventsource" + "websockets" / "long polling" to "message queues", like RabbitMq/ActiveMq with publish/subscribe to specific channels.
If this is a simple or restricted environment, maybe a VPS, then you can still stick to your solution of intervalic Ajax requests. Each request might then update $_SESSION['LAST_ACTIVITY'] with a server-side timestamp. Referencing: https://stackoverflow.com/a/1270960/1163786
A modification to this idea would be to stop doing Ajax requests, when the mouse movement stops. If the user doesn't move the mouse on your page for say 10 minutes, you would stop updating the LAST_ACTIVITY timestamp. This would fix the problem of showing users who are idle as being online.
Another modification is to reduce the size of the "iam still here" REQUEST to the server by using small GET or HEADER requests. A short HEADER "ping" is often enough, instead of sending long messages or JSON via POST.
You might find a complete "How to create an Ajax Web Chat with PHP, jQuery" over here. They use a timeout of 15 seconds for the chat.
Part 1 http://tutorialzine.com/2010/10/ajax-web-chat-php-mysql/
Part 2 http://tutorialzine.com/2010/10/ajax-web-chat-css-jquery/
You can do it this way, but it'll be slow, inefficient, and probably highly insecure. Using a database would be a noticeable improvement, but even that wouldn't be particularly scalable, depending on how "real-time" you want this to be and how many conversations you want it to be able to handle simultaneously.
You'd be much better off using a NoSQL solution such as Redis for any actions that you'll need to run frequently (ie: "is user online" checks, storing short-term conversation updates, and checking for conversation updates at short intervals).
Then you'd use the database for more long-term tasks like storing user information and saving active conversations at regular intervals (maybe once per minute, for example).
Why Ajax and not Websockets? Surely a websocket would give you a considerably faster chat system, wouldn't require generating and checking a text file, would not involve a database lookup and you can tell instantly if the connection is dropped.
I would install the https://github.com/nrk/predis library. So at the time the user authenticates, It publishes a message to Redis server.
Then you can set-up a little node server on the back-end - something simple like:
var server = require('http').Server();
var io = require('socket.io')(server);
var Redis = require('ioredis');
var redis = new Redis();
var authenticatedUsers = [];
// Subscribe to the authenticatedUsers channel in Redis
redis.subscribe('authenticatedUsers');
// Logic for what to do when a message is received from Redis
redis.on('message', function(channel, message) {
authenticatedUsers.push(message);
io.emit('userAuthenticated', message);
});
// What happens when a client connects
io.on('connection', function(socket) {
console.log('connection', socket.id);
socket.on('disconnect', function(a) {
console.log('user disconnected', a);
});
});
server.listen(3000);
Far from complete, but something to get you started.
Alternatively, take a look at Firebase. https://www.firebase.com/ if you dont want to bother with the server-side
I would suggest using in built HTML5 session storage for this purpose. This is supported by all modern browsers so we will not face issues for the same.
This will help us to be efficient and quick to recognize if user is online. Whenever user moves mouse or presses keys update session storage with date and time. Check it periodically to see if it is empty or null and decide user left the site.
Depending on your resources you may opt for websockets or the previous method called long pool request. Both ensure a bidirectional communication between the server and the client. But they may be expensive on resources.
Here is an good tutorial on the websocket:
http://www.binarytides.com/websockets-php-tutorial/
I would use a callback that you (admin) can trigger. I use this technique in web app and mobile apps to (All this is set on the user side from the server):
Send a message to user (like: "behave or I ban you").
Update user status/location. (for events to know when attendants is arriving)
Terminate user connections (e.g. force log out if maintenance).
Set user report time (e.g. how often should the user report back)
The callback for the web app is usually in JavaScript, and you define when and how you want the user to call home. Think of it as a service channel.
Instead of creating and deleting files you can do the same thing with cookie benefits of using cookie are
You do not need to hit ajax request to create a file on server as cookies are accessible by javascript/jquery.
Cookies have an option to set the time interval so would automatically delete themselves after a time, so you will not need php script to delete that.
Cookies are accessible by php, so when ever you need to check if user is still active or not, you can simply check if the cookie exist
If it were aspnet I would say signalR... but for php perhaps you could look into Rachet it might help with a lot of what you are trying to accomplish as the messages could be pushed to the clients instead of client polling.
Imo, there is no need for setting up solutions with bidirectional communications. You only want to know if a user is still logged in or attached to the system. If I understand you right, you only need a communication from server to client. So you can try SSE (server sent events) for that. The link gives you an idea, how to implement this with PHP.
The idea is simple. The server knows if user is attached or not. He could send something like "hey, user xyz is still logged in" or "hey, user xzy seems not to be logged in any more" and the client only listens to that messages and can react to the messages (e.g. via JavaScript).
The advantage is: SSE is really good for realtime applications, because the server only has to send data and the client has only to listen, see also the specification for this.
If you really need bidirectional communications or can't go with the two dependencies mentioned in the specs, it's not the best decision to use SSE, of course.
Here is a late Update with a nice chat example (written in Java). Probably it's also good to get an idea how to implement this in PHP.
So I'm trying to make a notification system similar to Facebook's system. I have a cron job running in the background and when it feels the need to send out a notification to an user it uses the PHP (REST) SDK to send a push to Firebase. On the dashboard I have an 'on' callback that fetches all incoming notifications for the user and shows a notification for each incoming new notification
var push_ref = firebase_ref.on('child_added', function(push) {
new PNotify({
title: 'Notification',
text: push.val().message,
...
});
});
However, when I reload the page all previously sent notifications pops up simultaneously and fills the screen with notification boxes. I don't wanna delete the sent push notifications because later on I'm gonna make a system to fetch them and put them in a dropdown box (similar to the notification dropdown on Facebook).
My question is;
How can I keep all sent notifications but at the same time disable that Firebase returns all notifications when the client goes online again?
UPDATE:
Looked through their documentation again and saw that their retrieving data types are very different. It says under "child_Added" that it "is triggered once for each existing child and then again every time a new child is added to the specified path". This is why it is triggered once I reload the page with all the existing children.
Can you see any other types that might work for me, because I haven't found any.
You could have the client update each message on receipt to acknowledge that it was shown (set acknowledged = true or whatever). Then use the acknowledged field to filter the UI treatment to only highlighting unacknowledged messages.
This assumes the messages are user-specific, or your data structure will require a message/user mapping to hold the acknowledgements.
If the user is reading from a public stream of messages, you could save a user-specific lastReadDate or something that filters out the old messages.
I submitting an app to Facebook with open graph news read type by javascript.
All done so well with flow from user asking for authorized my app, and show the button help user can public the article then they can remove if they want to.
Today I got the request from Facebook need to change my app:
requirements
(https://developers.facebook.com/docs/opengraph/actions/builtin/#read).
Please make sure your users can (1) Turn sharing on/off globally on
each page an article appears. (2) Remove articles they shared within
your app on each page an article appears. (3) Only generate read
actions when you're sure someone is interested in reading the article
- only publish after 10 seconds.
The third request is easy just use timeout to show the button submit after user read article.
The seconds is so hard because I don't know how to full the array list of pass action of user doing with my app include action id and title of article they post which I can use to create "remove link" for each of them if user want to.
The fist request I did search for method of javascript to de-authorized the app from user (not revoke permission) so I can ask user to be reauthorized if they need.
Please help.
Beside I see very nice 2 sample in guild page
https://developers.facebook.com/attachment/OG_App_PublishToggle.png
https://developers.facebook.com/attachment/OG_App_DeleteActivity.png
But they din't give out the link of live site using it.
or may be that is one of Facebook markup similar "recommend box" , but how/where we can get it?
Please advices for the script or sample as Facebook dose will be help full
regards
UPDATE 1 I found the way to reauthorized all app or revoke one permission.
here the function:
var permsNeededPub = "publish_stream";
///notice that if permission is "publish_actions" revoke function not work
function xlfb_revokePerm() {
FB.api("/me/permissions", "delete",{permission:permsNeededPub}, function(response){
console.log(response);
if(response){
console.log(' Remove success '+permsNeededPub);
}
});
}
function xlfb_removeApp() {
FB.api("/me/permissions", "delete", function(response){
console.log("User removed the app from acount: "+response);
});
};
The seconds is so hard because I don't know how to full the array list of pass action of user doing with my app include action id and title of article they post which I can use to create "remove link" for each of them if user want to.
Whenever a user takes an OG action on your site - save the action_instance_id you are getting back from the API call and whatever extra data you might need to your database.
The fist request I did search for method of javascript to de-authorized the app from user (not revoke permission) so I can ask user to be reauthorized if they need.
Why would you want to de-authorize the app?
All that’s required here is to have a global on/off switch for all sharing activity – so if the user sets it to off, then you just don’t publish any actions for him as long as he leaves this setting set to off.