Create a simple private message system in rails with inbox, send, and reply's? - ruby-on-rails

There are some gems out there to instantly have a simple messaging system for users which I have looked at but they don't really fit the bill in terms of having a way to easy customize them.
Therefore I would like to ask some suggestions of gems that you consider be good for an instant messaging on a site, or discuss how one could implement this functionality.
I have built a simple system before that consisted of a messages table like this:
inbox
outbox
friend request
replies
id|message_id|sender_id|receiver_id|is_reply|is_friendreq|message
I'm thinking of storing everything in this one table and get all messages of a certain user where the user_id == receiver_id. This is very basic. I'm learning Rails and try to learn how to implement this on best Rails practice, so any tips/suggestions/ideas are more than welcome.

Related

Rails - email as part of a conversation (mailboxer?)

I have a rails app that needs 'conversations' between two entities around a shared object (a proposal). Very simple, just two or more users chatting about the shared object. I have looked at a couple of gems, including Mailboxer, but was thinking of handrolling it instead.
However, the client wants the users to A) be sent email of the conversation (no problem) and B) be able to reply to those emails, where the reply gets added to the conversation. This would likely be similar to how eg airbnb handles it:
It's the B part that I'm struggling with. To my knowledge, Mailboxer wouldn't handle this. Are there other gems that do? Or do I need an entirely different approach?
You should use gem msgthr to handle conversational mail.
https://rubygems.org/gems/msgthr/versions/1.2.0

Best way to build a feed notification system like Facebook in Rails?

I'm a new junior developer joining to this awesome community. I'm developing my first big personal project, and I'm stuck with this specific part.
I would like to build a feed notification system like Facebook with the following features:
Track different models and relationships, for example: new badges earned, new comments in subscribed models, new posts by followed users, new comments on my posts, new likes on my posts...
Group the activities, for example, instead of have 400 activities for each likes in my post, has just one notification that says "User X and 399 more likes your post"
Be possible to mark notifications as readed to don't see them again, at least you explore past notifications.
Scalability, good perfomance, and possible integration in the future in an APP developed for example with Iconic framework.
Push notifications are optional, it's ok if the user need to refresh the page to see the new notifications.
So for that, I have readed a lot of. I have watched some Railcast Videos, followed tutorials, but still I'm not really sure how to begin.
I have considered the following methods:
Use public_activity gem, adding a new a new field "readed" to the migration. And thinking how to manage grouped activites. But I have seen a lot of complains about perfomance. I'm expecting to have around 50000 users in my website in the first month (I already have the users), with peaks of 500-1000 users online. So maybe this is not the best way to go... as I would have a lot of activities, a lot of "notifications" and a lot of users.
Use a system like https://getstream.io/ because they also have integrations available for RoR and Ruby. The main concern here is about pricing, because checking it, if I'm not wrong, with that number of users, with around 10 notifications per user per day, I would be paying probably more than 200$ month, and always keep growing as the users grow.
Build my own system, maybe using Redis. But maybe this would be too complex and require a lot of time for a good, efficient and working code.
So still, considered these option, I don't know which one is best for me, or if it's another possibilities.
If someone have asked before these questions, please let me know your thoughts and what you think is the correct way to go.
Thank you !! :)

Create an internal message system with Rails

I have Users that can create DinnerEvent that contain Food. User specify preferred Food using a join table. Would like to create an internal message system that automatically sends out a notice to other Users who "prefer" the Food in the DinnerEvent that was created. Can anyone provide some guidance as to how I can go about approaching this or if there are any good reference resources out there (haven't had much luck searching)? Thought about ActiveMailer but decided I wouldn't want people to get spammed all the time in their email inbox. Would prefer to only use Rails to achieve this.
There's a lot of options here and many use cases to think through. Maybe you can start with something very simple that:
Tracks the last date/time of login for each user
On some page (specific to the logged in user), display all DinnerEvents created since last login that match their Food preferences. Should be simple Active Record to pull this.
Continue to show this list until they dismiss it (record this date/time) or login again
A full blown messaging system will probably require more complex stuff like queues for each user that are subscribed to a master queue. And, possibly an additional backend data store like Redis. I'm purposefully leaving out the details of something like this for now; it's a much bigger topic.

Implementing Notifications in Rails

In my application, I want to notify a user, when he/she is mentioned in a comment or a post.
The user handle is #user_name, similar to Facebook.
The database table for mentions looks like:
Mention
mentioned_by: user_id (foreign key)
user_mentioned: user_id (foreign key)
comment_id: (foreign key)
post_id: (foreign key)
I can't figure out a way to implement it though. How do Facebook / Twitter do it?
What I decided to go with, was use ActiveRecord callbacks/ Observer design pattern and whenever a new comment/post is saved to database, I can go through the contents of the post/comment, and look out for any mentions and then execute the notifications as required.
I get the feeling that there are some missing pieces and I am not getting it right.
Is this the best way of doing it?
Facebook and Twitter are not mid-size Rails applications. They are companies. The tech that runs them is distributed and mostly custom, especially in the case of Facebook.
The part that you seem to be grasping for is how they determine who to notify in a performant and scalable way. This is where shit gets real. You can find a lot of information about the architecture behind each on of them, and there is certainly a lot of great stuff to help you think about these things, but ultimately none of it is going to be something you implement into whatever application you're building.
http://www.quora.com/What-is-Facebooks-architecture
Facebook Architecture
http://www.infoq.com/news/2009/06/Twitter-Architecture
http://engineering.twitter.com/2010/10/twitters-new-search-architecture.html
Plenty more juicy details over at Quora.
Unfortunately, none of this gets you closer to your goal. I think the most realistic thing for you to do to start out with woud be to simply tie in a service like Pusher to send messages to clients without worrying about it, use an ActiveRecord Observer to add notifications to a background queue where the workers actually send those notifications to Pusher. This is a day or less of work and it should scale well to at least 10k notifications a day. Once you start having performance problems, ditch the Observer and Pusher for something like Goliath that can handle both of the jobs locally.
Bottom line, learn what you can about large and experienced systems that have been put through the paces, but mainly just to see what problems they ran into and how they solved them. These methods aren't the same among the big guys even, and they are going to vary for each implementation.
Hopefully that helps point you in a good direction. :)
You can use ActiveRecord callbacks while record is saved (like before_save, after_save or before_create, after_create) to go through comment content, find and create all mentions models and save them to db.
I actually am interested in a concrete answer to this myself. I don't know how Facebook and Twitter do it, but I do know from general searches that the gem acts-as-taggable-on could get the job done. Check out https://github.com/mbleigh/acts-as-taggable-on.
Also, this question on stackoverflow might also provide you with some info: Implementing twitter-like hashtag on rails
Good luck. I encourage you to try to get more attention to this question and get a more solid answer than what I've said. :]
Tumblr uses a Redis queuing system (like Resque) I believe to handle the volume.
Do a callback (as you mentioned) and hand it off to Resque. (There was a Railscasts about Resuqe recently)
There is no single recommended approach for this. At an uber level, you may want to look at 'Comet programming', Polling and WebSockets [HTML5] and then choose the right combination. There are a couple of great implementations to manage push notifications in rails. Orbited, Juggernaut, PusherApp, Faye etc. You'll have to dig deep to figure out which of 'em use web-sockets & and fall-back to flash option to handle full support.
Faye gives a Node.js configuration also, but I am not sure about others.
Tentatively the steps would look something like:
Save the content - queue it to parser
Parse the content to find out involved users - Use Nokogiri or equivalent.
Comet/Poll it to involved users in current_session as a separate process if you're looking at Twitter like approach.
//Do other things with Post record
Push notifications to involved users and destroy() when they come online later.
Hope that gives some direction.
I know this question is outdated but I released a MentionSystem gem recently to rubygems.org that allows to create mentions between mentionee objects and mentioners, it also allows you to detect mentions in facebook / twitter styler like #username1 and #hashtag in order to create the mentions.
The gem is hosted at github: https://github.com/pmviva/mention_system
Lets say you have a Post that can mention users in the form of #username.
you have the class
class Post < ActiveRecord::Base
act_as_mentioner
end
and
class User < ActiveRecord::Base
act_as_mentionee
end
Then you define a custom mention processor:
class PostMentionProcessor < MentionSystem::MentionProcessor
def extract_mentioner_content(post)
return post.content
end
def find_mentionees_by_handles(*handles)
User.where(username: handles)
end
end
Then in your Posts controller create action you have:
def create
#post = Post.new(params[:post])
if #post.save
m = PostMentionProcessor.new
m.add_after_callback Proc.new { |post, user| UserMailer.notify_mention(post, user) }
m.process_mentions(post)
end
respond_with #post
end
If your post has #user1, #user2 and #user3 in its content the mention processor will parse user1, user2, user3, will find users with username [user1, user2, user3] and then create the mentions in the database, after each of the mentions it will run the after callback that in the example will send an email notifying the mention between post and user.

Integrating twitter,facebook and other services in one single site

I need to develop an application which should help me in getting all the status,messages from different servers like Twitter,facebook etc in my application and also when i post a message it should gets updated in all the services. I am using authlogic for authentication. Can anyone suggest me what gems/plug-ins i can use..
I need API help to get all the tweets/messages to be displayed in my application and also ways to post the messages to the corresponding services by posting it from my application. Can anyone help me from design point.
Walk through what you'd want to do in your head. Imagine the working site, imagine your webapp working before you start. So your user logs in (handled by authlogic) and sees a textbox called "What are you doing right now?". The user fills in a status message and clicks "post". The status message appears at the top of their previously posted messages.
Start with the easy part. Create a class that posts to two services. Use the twitter gem and rfacebook to post to two already defined services. In the future, you'll want to let the user associate services to their account and you would iterate through the associated services and post the message to each. Once you have this working, you can refactor or polish the UI a bit to round out this feature. I personally would do the "add a social media account to my profile" feature towards the end.
Harder is the reading of the data (strangely enough) because you're going to have to figure out how to store it. You could store nothing but I suspect you'd run into API limits just searching all the time (could design around this). I would keep a little cache of posts associated to the user's social media account. In this way, the data model would look like this:
A user has many social media accounts.
A social media account has many posts. (cache)
Of course, now you need to schedule the caching of the posts. This could be done manually, based on an event (like when they login) or time based. So when the update happens, you load up the posts for that social media account and the user will see the posts the next time they hit the page. For real-time push to the client's browser while they stare at the screen, use faye (non-trivial) and ajax to pull the new posts to the top of the social media stream view.
The time based one is tricky because you'd either have to have a cron job run or have rails handle it all with a gem like clockwork. But then you have to leave rails running. I've also solved this by having a class in /lib do all the work and a simple web call kicks off the update. But it wasn't in a multi-user use case. So that might not work. In any case, you'll want to have some nice reusable code for these problems since update requests can come from many different sources.
You'll also have to deal with the API limits. When pulling down content from twitter, you won't get everything. That will just have to be known by the user or you'll have to indicate a "break in time" somehow.
The UI should be pretty easy (functionally anyway), because you know which source the post/content is coming from. It'd be easy to throw a little icon next to the post to display which social media site it's coming from.
Anyway, good luck, sounds like a fun project.

Resources