How do I implement bubble notifications in rails? - ruby-on-rails

I already have a feed with the public_activity gem . However, I want to have a facebook-like on-site notification system where the user can see a number in red background, representing the new notifications concerning him.
I have never implemented such a thing and I am not sure how to go about it.
Most answers about Rails notifications will recommend using Mailboxer, public_activity, and any other messaging gem but nothing about the dynamic real-time facebook like notification that easily alarms you of the new notifications with the number and links.
Thanks for your help !!!.

You can use polling with a JS library like jQuery. There is another good example that can be followed.
The main focus would be making an ajax request after a specific time and check for the results and repeat the process.

Related

Sending newsletters with SendGrid and Rails - What is the best approach?

I have a rails app with sendgrid API setup and I can send transactional emails just fine. Now I want to be able to send newsletters but I'm a bit confused about the flow and how to keep track of which users want to unsubscribe from the newsletter.
The way I was considering doing this is when a use signsup to automatically send a request to the SendGrid API and add them to the contacts list, and if they want to unsubscribe from the newsletter or transactional emails from my app's settings page I can save this info in my app's DB but also send a request to sendgrid's unsubscribe list to change the value there too. Now I can create a newsletter in sendgrid and send it out from there without having to do anything within my app. One caveat to this approach would be if the users clicks the unsubscribe button via the newsletter and the value gets changed in sendgrid but the change won't be reflected in my app - To work around this would it be better to create a cron job that periodically checks sendgrid for any changes and then save them to my DB, or should the unsubscribe page be part of my app, and when they select unsubscribe I save it to my DB and then push the changes to sendgrid? If i do this approach, would I require users to sign in if they want to make these changes?
An alternative approach would be to forego creating any contact lists in sendgrid and just create the email in sendgrid and sent it out using a rake tasks to trigger the sending?
Apologies if this is a very basic question, but this is my first time trying to setup newsletters etc and can't seem to find anything online about the best strategy to take in order to do this - I hope this question makes sense.
Twilio SendGrid developer evangelist here.
This question is a little too opinion based for Stack Overflow, many of the options you describe will work but they rely on whether it's the right decision for your application. But, I will try to give some guidance.
First, however you approach this, I would recommend you set up subuser accounts within SendGrid so that your transactional and newsletter emails come from different subusers. This way unsubscribes from newsletters won't affect transactional emails.
I would use the SendGrid contacts list to send out newsletters. This gives you a lot of power over your contacts without you having to build things yourself. You can segment your lists, create unsubscribe groups (where a user can unsubscribe from a subset of your emails instead of all of them) and send emails from within SendGrid without bothering your Rails app. You can still set up to trigger a newsletter from your app using the API if you want to.
As for maintaining the user's subscription status, I would go with exporting the contact lists and keeping your database up to date that way. The important thing when sending to your contact list is that SendGrid has the source of truth for subscription status and your application can be a bit behind if it needs to be. The SendGrid docs for exporting contacts also say:
Twilio SendGrid recommends exporting your contacts regularly as a backup to avoid issues or lost data.
So this would fulfil that suggestion too.
As for the unsubscribe links, the easiest way is to use the SendGrid unsubscribe form, have SendGrid handle all the unsubscribes, and your exports can keep your database up to date. That also allows you to handle the addition of unsubscribe groups without any more code on your side.
With more work you could create your own unsubscribe form so that your database stays more up to date with the subscription status. Your choice over whether a user should be logged in or not depends on how much friction you want to give the user before they unsubscribe and how much issue you think you might get from users forwarding your emails and having their friends unsubscribe them. That is up to you to decide on though.
Hope this helps a bit!

Approach to a Notifications system with Rails 4

I have a USER model in rails that I would like to implement a notifications system for.The notifications system is intended to work like Facebook's notifications. Using guides around the internet as a basis, I have theorized that notifications would require its own Model.
Therefore it would be:
Users :has_many Notifications
Notifications :belongs_to Users
The Users model interacts with many models on the app such as articles, post, comments on the articles and posts. Users can "follow" those resources and receive notifications for them. My theory is that I create notifications for each "follower" whenever those resources are updated like so:
Example of Update for an article:
def update
#after the code to update article
#followers.each do |follower|
Notification.create(#code to associate notification with user)
end
end
Then, just display the notification using
current_user.notifications
My primary question is that Is there a better approach to notifications than what I've outlined? Also on a related note, creating notifications like so would fill up the rows in the database with objects that are not needed over time(i.e notifications from a year ago are irrelevant). Is there any negative consequences for leaving those unused objects in the database and letting them add up?
If you are open to using a gem, I would use the Public Activity gem for this. The architecture for Public Activity creates an activity record based on a recipient, an owner and a key, i.e owner: "User 1" key: commented on recipient: "User 2" post. The benefit to this is that there is only one record in the database for the activity and you can present it any way you like through different views for each type of activity.
Public Activity allows you to render different partials based on the activity key and access any of the data of the action referenced in the database. You can even create different views for a newsfeed(activities that involve the users followed by the current user) and a notification feed (activities that directly involve the current user).
This allows your notification feed to remain flexible.
Further, if you combine it with the Unread gem and some javascript you can even mark read and unread notifications (for each particular user) just like Facebook. The only drawback is that the activities would appear only on refresh or visiting the page rather than constant polling like facebook does. There is an excellent tutorial on Public Activity here.
I would use observers for notification as its an orthogonal concern to your model. See https://github.com/rails/rails-observers. for earlier versions of rails, it is part of the framework.
I would create a class Notifier which would observer lifecycle event (in the above case after_update on user) and would send out notifications. One observer can observe many models
While that would work you would still have a problem: how to push those notifications to the user. What this means is that if I get notifications from the system yet I don't reload the page I won't notice until I do so which brings you to two different solutions, which have to do with the client side management of it really:
Polling
Something around WebSockets
Polling
In case you decide to go with the option number 1 you would need to add client-side JavaScript code that keeps polling one endpoint of your application to check for the current user notifications so you can update the UI.
Pros: You have a great control over the client side code and this can be implemented in almost all browsers as long as they support JavaScript. You can support legacy users.
Cons: Tedious to develop and can code can become messy. Not real time at all. Sometimes, using timers in several places within the same client code can lead to unexpected behaviors.
WebSockets
This is a newer technology so while it should work right out of the box in most modern browsers there are still some caveats here and there, which is the reason why few developers still avoid it. Web Sockets basically allow to have an open connection to the application (because as you may know HTTP is stateless) so that you can actually push or send notifications from the application and not the other way around (like when polling, where the client requests for the new info)
Pros: Newer technology but also more flexible in the way that you can control many aspects of the notifications in the backend (like having queues, a different, speedier, data store like nosql for it, etc.)
Cons: Some browsers don't properly support it yet.
I would say that if you are still developing your app and plan to release a little bit later and you don't mind some users having that option disabled when they have ancient browsers then take a look at ActionCable from Rails 5 which serves exactly this purpose. Here's a video from dhh doing a whole demo.
I would also separate notifications from your SQL table and instead of using ActiveRecord just use redis or mongo for that purpose while you keep ActiveRecord for everything else. The advantage is that redis and mongo are super fast and are well-known to outperform SQL in these kind of requirements. You can use the ActiveRecord user ID to map the notifications within the nosql database and subscriptions to those as well.
Good luck!
If all articles, posts and comments, are sources of notifications, it seems to suggest that you could use Single/Multi Table Inheritance or Polymorphism, rather than generate a notification record for each subscribed user for each post, comment, and article.
So, for the sake of argument, let the collective name of articles, posts and comments be Notifications. One notification for each article, post, and comment.
Now it just becomes a matter of working out how to keep track of the Notifications a user has seen. It could either be a simple column on the Notification table that holds a list of user ids {user_1}{user_5} that can be used to filter the records, or a many-many table that stores the user id and the notification id a user has seen. I'm sure there are many more possibilities, but I'm not familiar with the different approaches.
Using this info, it shouldn't be too hard to determine which Notifications have not yet been seen, and then display a message of such.

Doing Notification in Rails

What i want to do is a little different from what people think when they hear rails notification cause i've been reading up a lot about it but it didn't seem to help.
What i want to do is on creation of a new entry in a particular table i want certain users (admins) to get a notification in their home page or whatever page they're in, as the notification apparatus would be in the navigation bar.
How would i go about doing this ? i'm an intermediate rails developer, and i'm using rails 3.2.13.
Thanks in advance!
There are a couple of things you'll want to do (I agree with the approach proposed by japed):
Create the notification model with the required fields, I would suggest make it polymorphic so you can have access to the object that triggered the notification later (for example: having notifiable_type and notifiable_id fields, if an article creation triggered the notification creation you can then do something like notification.notifiable and get the article that was created)
Place the callbacks that will generate the notification in place. for example: if you want to notify an admin every time a user creates an article, you can create the notification in the after_create method on the Article model.
Have a way to know if the admin has read the notification or not (so you can show him a counter of unread notifications for example). For this I would recommend using the unread gem: https://github.com/ledermann/unread
After the admin reads the notification (eg: after clicking on the unread counted) update the status of the notification (using the unread gem of course, not directly on the notification record), maybe with an ajax request.

is it possible to send a directed flash message in rails?

this is kind of a dumb question, but is it possible to send a
flash[:success]
directed to a certain user other than the current user on the screen? in one of my controllers i have
if #article.up_votes.count > 10
flash[:success ] = 'something'
end
is it possible to send that flash to the owner of the article? as opposed to my own screen? or is there another way to do this?
i tried looking through
http://api.rubyonrails.org/classes/ActionDispatch/Flash/FlashHash.html#method-i-notice
but couldn't find any method that would help. maybe i am reading it wrong? is there a way to achieve the same effect then?
thank you...
Not using flash, you'd have to try something else, there are lots of ways to go about it, but flash isn't one of them. Well, you could still use flash, but it wouldn't be to send from one user to another, you could cause a flash message to appear for the user being notified.
First thing to figure out is how do you notify the other user, when would he get that notification, do you want him to get notified anytime he using your site? Or only if he does something specific on your site?
For what I know the best way to go, maybe the only way actually is push notifications. There are many ways to achieve this but I think faye should be the easiest.
See this screencast to understand it and later. You want to have a channel for each user so it will be the one to get that message. Further search for private pub so nobody's can listen to others channel
http://railscasts.com/episodes/260-messaging-with-faye
http://railscasts.com/episodes/316-private-pub
As ismaelga mentioned I also think push notifications is the way to go (WebSockets).
In addition to Faye you can use a hosted solution called Pusher (pusher.com).
Here is a really short description about how Pusher can help you. Bassically all users using your application listens for messages on a WebSocket-server (through JavaScript). In this case Pusher. You can then send messages to Pusher via your Rails application. When you send a message to Pusher, all users will instantly be notified about the new message via JavaScript (through the WebSocket). To only notify a specific user you can use Pusher's "private channels"-feature.
Pusher have some really good documentation on how to use their service: http://pusher.com/docs/javascript_quick_start
This picture (taken from Nettuts+) might also give you a better understanding of how Pusher works: http://d2o0t5hpnwv4c1.cloudfront.net/1059_pusher/pusher_websocket.png
Hope this helps a bit.

Xcode chat app, creating dynamic views - a little lost

Am just about to start doing an iphone application which is supposed to have a multi user private chat. Something like facebook style, where the user has a list of friends and he can chat with them independently. I just need a little direction here
If i have a list of users, let's say i create individual views for the chat, how can I handle these views? If jim is chatting with dick and jane, there should be 2 views, each for one chat window right? Are there any references that i can use.
I am looking for references in socket programming where i can push messages to the user from the server. I have been looking but could not find anything helpful.
If i try to update the user's chat window using local notifications, lets say request data every couple of seconds, will that be battery draining?
I would really like some direction here, i do not want to start something just realize its the wrong way.
Any help is highly appreciated
Those all sound like design decisions. For example, do you want to display each user's messages in a separate view? That's entirely up to you.
You'll want to read about iOS Push Notifications.
If you mean that you intend to poll some server for updates, then yes, that will use a lot of battery. This is exactly the sort of situation that the push notification system was created to help you avoid.

Resources