Public Lab Research note

  • 1

GSoC Proposal - Email Notifications Overhaul

by Khamba |

About me

Hi, My name is Saurabh Sikchi and I am a third year student of Computer Science and Engineering. I have been working with Ruby and Ruby on Rails for about 2 years.

Github: Khamba

Affiliation: BITS Pilani K. K. Birla Goa Campus

Location: Goa, India

Project description

Abstract/summary (<20 words):

Upgrade email notifications for new features such as reply by email, per user notification preference, scheduled email jobs, etc.


Advanced email features greatly improve usability and user-friendliness.


Total Time: May 22nd to August 21st, 2017 = 13 weeks

Notification Preferences for users - 2 weeks

Sign Up Offers to auto subscribe you to the tags you were looking at - 2 weeks

Improve tag subscriptions when tags are added late - 2 weeks

Reply by email to comments - 3 weeks

There are still 4 weeks left. What else can I add here?




Have you forked the relevant codebases?

Yes. (

Installed them in a dev environment such as

I have installed it on my local computer.


Tell us how you've learned about writing software; what languages you've been learning, if you've worked on other projects, links to GitHub or other code repositories or samples.

I start learning web development in PHP and ruby in my first year. As time passed, I fell more in love with ruby than PHP, so I stuck with that. After learning rails, I started freelancing and working as a contract based developer. A lot of my projects are hosted on my github (

Have you looked over our welcome page and are you familiar with how to make your first contribution? Have you already?

Yes, I have.

My pull request submission that was merged:

My pull request that is yet to be merged (Edit: Now Merged.):

I raised a new issue:

Accepted solution to the issue submitted:


I have worked in a team environment before, as a web developer under a project manager. I believe in writing descriptive tests and well-documented code so that others on the team don't face inconvenience.

In open source, I have contributed to the plutus gem (, but that contribution was minor and I want to contribute something more useful.


What about our projects, and Public Lab, interests you? What are you passionate about? Open science, environmental justice?

I truly admire what does to bring more transparency and accessibility to science and environmental research. Public participation and on-the-ground community work is the best way forward to address real life environmental issues.


Whom do you want your work to help? We especially appreciate proposals which make technologies and techniques more welcoming and friendly to those who've often been excluded.

I want my work to help the day-to-day users of Features such as replying by email will be extremely helpful for people who are busy and cannot access the website at the time.I also want my work to help the core contributors of plots2. They will have some nice features added to the codebase, and I will get to learn from the work.


Do you understand this is a serious commitment, equivalent to a full-time summer job? Tell us how you'll structure your schedule from day to day!

I do understand that this is a full time commitment. Since, these will be summer vacations I will have a lot of free time on my hands. Dedicating enough time to Public Lab will not be a problem.

Reply by Email to Comments

I read your suggestion about using mailman for this. I want to propose an alternative - griddler. Griddler seems to more maintained. The last commit on mailman was approximately 2 years ago, and on griddler it was 2 weeks ago. What do you think?


Add griddler and an adapter gem(more on this adapter gem in a while) to your application's Gemfile.

Griddler requires a route for the endpoint which receives POST messages.

In routes.rb, add

mount_griddler('/email/incoming') # or whatever incoming email path suits us

In config/initializers/griddler.rb

Griddler.configure do |config| config.processor_class = CommentByEmail config.email_class = Griddler::Email config.processor_method = :create_reply # (A method on CommentByEmail class) config.reply_delimiter = '-- REPLY ABOVE THIS LINE --' config.email_service = :googleapps # this is the adapter. I will write the adapter myself. end

In app/email_processors/comment_by_email.rb

``` class CommentByEmail def initialize(email)

@email = email


def create_reply

current_user = User.find_by_email(@email.from[:email])
@node = Node.find(@email.headers[:node_id])
if current_user && @node
  @comment = @node.add_comment({ uid: current_user.uid,body: @email[:body]})
    # Should we notify the user of failure here?

end end ```

About the adapter:

Griddler already has adapters for some popular mail services. However, I noticed that plots2 is using google apps and I intend to write an adapter for g-apps myself by taking cues from the earlier adapters:

Ok then, I guess that is it for now for reply by email. Any additions or modifications?

Notification Preferences for Users

I was thinking of a simple solution of making a user_notification_preference model.

ruser has_one user_notification_preference

user_notification_preference belongs_to ruser

UserNotificationPreference will have fields -

comments:boolean (default: true)

subscriptions:boolean (default:true)

likes:boolean (default:true)

Then we can provide additional options in edit profile form with three checkboxes.

Every notify method in the models will be modified with a conditional. For example, Comment#notify will go from:

``` def notify_users(uids, current_user) DrupalUsers.find(:all, :conditions => ['uid IN (?)',uids]).each do |user|

if user.uid != current_user.uid

end end ```


``` def notify_users(uids, current_user) DrupalUsers.find(:all, :conditions => ['uid IN (?)',uids]).each do |user|

if user.uid != current_user.uid && user.user_notification_preference.comments? # check if user wants to receive comment mails

end end ```

Sign Up Offers to Auto Subscribe you to the Tags you were Looking at

I agree with you that it would be better to do this on the client side.

some method like getNodeTags() which returns an array of tagnames, I guess? And a way to histogram them, to find the most common of them, like mostCommonTags() which returns an array.

What if we store a hash/object with the tag name as key and the number of times user has visited it as the value?

``` function setTags(tagNames){ var storedTags = JSON.parse(localStorage.getItem('tags')); storedTags ? storedTags : {}{

storedTags[tagName] = storedTags[tagName] ? storedTags[tagName] + 1 : 1
// if we have already stored the tag, increment by 1
// else set it to one.

}); localStorage.setItem('tags', JSON.stringify(storedTags)); } ```

Then we can implement a getMostCommonTags function:

``` function getMostCommonTags(){ var storedTags = JSON.parse(localStorage.getItem('tags')); if(!storedTags){

return []; // Or should we return something else, in case no tags are stored?

} // Now we convert storedTags hash to array of 2 element arrays [ key, obj[key] ] // for sort purposes var sortable = [] for(tagName in storedTags){

  sortable.push([ tagName, storedTags[tagName] ])

} sortable.sort(function(a, b){ // reverse sort

  return b[1]-a[1];

return sortable.slice(0, 3); // 3 or how many ever tags we want } ```

These tags can then be submitted with the sign up form, and added in users_controller#create

``` def create ... @user.add_to_lists(['publiclaboratory']) if(params[:tags])

params[:tags].each do |tag| tag)

end flash[:notice] = I18n.t('users_controller.registration_successful').html_safe ... end ```

What are your thoughts?

Improve Tag Subscriptions when Tags are Added Late

I read your solution and although I agree with it, I kind of like your first solution here more - a 20 minute delay in sending the email. It's a good practice to handle email sending asynchronously. I also think this solution will be simpler, require lesser code and will be easier to understand for future contributors. What do you think?

software gsoc gsoc-2017 soc soc-2017 soc-2017-proposals



Hi, @Khamba - thanks; I was thinking some of these could be broken up a bit more -- for example, the one on "Sign Up Offers to auto subscribe you to the tags you were looking at - 2 weeks" would involve some way to store tags you've looked at. Would this be done on the server side, the client side, or what? Maybe for privacy reasons it could be client side in JavaScript, using localStorage, that way it's not like we are spying on what people read.

If so, what would you need to get this information -- some method like getNodeTags() which returns an array of tagnames, I guess? And a way to histogram them, to find the most common of them, like mostCommonTags() which returns an array.

For Improve tag subscriptions when tags are added late - 2 weeks, I've been thinking about a simple way to start, which could be to have an ActiveJob that runs every period which collects all the content that's been created or updated in the period that has the right tags, and assembles an email. We could test this out without ActiveJob first -- just a User method like user.getTaggedContentSince(tagnames, start(, end)) or something. That could be unit tested, which is nice.

For the notifications interface, are there examples from other sites that work well, that we could look to as an example? Maybe a screenshot or sketch could help.

Thank you!

Hello Mr. @warren - thanks for that very detailed comment.

I realize that my proposal lacks severely in how I am going to implement the features. I will work hard on it and update the proposal with the relevant road-map.

Thank you for your valuable time.


I have updated the proposal with the plan. All new edits are after the Commitment section. There is some md formatting issue with the editor, I think, so I made a gist of it too.

Sorry for the wall of text.

Thank you.

You must be logged in to comment.