{"action":"created","comment":{"url":"https://api.github.com/repos/Papercloud/notify_user/pulls/comments/75070863","id":75070863,"diff_hunk":"@@ -0,0 +1,64 @@\n+module NotifyUser\n+  class Aggregator\n+    def initialize(notification, aggregation_intervals)\n+      @notification = notification\n+      @aggregation_intervals = aggregation_intervals\n+    end\n+\n+    def has_pending_deliveries?\n+      if notification.class.aggregate_grouping?\n+        unread_unsent_notifications_for_group.any?\n+      else\n+        unread_unsent_notifications.any?\n+      end\n+    end\n+\n+    def delay_time_in_seconds\n+      delay_time_in_minutes = aggregation_intervals[aggregation_interval] || aggregation_intervals.last\n+      delay_time_in_minutes * 60\n+    end\n+\n+    def last_send_time\n+      notification.class.for_target(notification.target)\n+        .where(group_id: notification.group_id)\n+        .where.not(id: notification.id)\n+        .maximum(:created_at)\n+    end\n+\n+    private\n+\n+    attr_reader :notification, :aggregation_intervals\n+\n+    def unread_unsent_notifications\n+      @unread_unsent_notifications ||= notification.class.for_target(notification.target)\n+        .joins(:deliveries)\n+        .where.not(id: notification.id)\n+        .where('notify_user_notifications.read_at IS NULL AND notify_user_deliveries.sent_at IS NULL')\n+    end\n+\n+    def unread_unsent_notifications_for_group\n+      @unread_unsent_notifications_for_group ||= unread_unsent_notifications.where('notify_user_notifications.group_id = ?', notification.group_id)\n+    end\n+\n+    # Finding the appropriate delay time:","path":"app/models/notify_user/aggregator.rb","position":43,"original_position":43,"commit_id":"164b0b7cb87c68fe9ab7680c5564de24f55c71ec","original_commit_id":"164b0b7cb87c68fe9ab7680c5564de24f55c71ec","user":{"login":"antonivanopoulos","id":917575,"avatar_url":"https://avatars.githubusercontent.com/u/917575?v=3","gravatar_id":"","url":"https://api.github.com/users/antonivanopoulos","html_url":"https://github.com/antonivanopoulos","followers_url":"https://api.github.com/users/antonivanopoulos/followers","following_url":"https://api.github.com/users/antonivanopoulos/following{/other_user}","gists_url":"https://api.github.com/users/antonivanopoulos/gists{/gist_id}","starred_url":"https://api.github.com/users/antonivanopoulos/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/antonivanopoulos/subscriptions","organizations_url":"https://api.github.com/users/antonivanopoulos/orgs","repos_url":"https://api.github.com/users/antonivanopoulos/repos","events_url":"https://api.github.com/users/antonivanopoulos/events{/privacy}","received_events_url":"https://api.github.com/users/antonivanopoulos/received_events","type":"User","site_admin":false},"body":"True 👍 ","created_at":"2016-08-17T06:56:45Z","updated_at":"2016-08-17T06:56:45Z","html_url":"https://github.com/Papercloud/notify_user/pull/35#discussion_r75070863","pull_request_url":"https://api.github.com/repos/Papercloud/notify_user/pulls/35","_links":{"self":{"href":"https://api.github.com/repos/Papercloud/notify_user/pulls/comments/75070863"},"html":{"href":"https://github.com/Papercloud/notify_user/pull/35#discussion_r75070863"},"pull_request":{"href":"https://api.github.com/repos/Papercloud/notify_user/pulls/35"}}},"pull_request":{"url":"https://api.github.com/repos/Papercloud/notify_user/pulls/35","id":81586210,"html_url":"https://github.com/Papercloud/notify_user/pull/35","diff_url":"https://github.com/Papercloud/notify_user/pull/35.diff","patch_url":"https://github.com/Papercloud/notify_user/pull/35.patch","issue_url":"https://api.github.com/repos/Papercloud/notify_user/issues/35","number":35,"state":"open","locked":false,"title":"1.0.0 refactor","user":{"login":"antonivanopoulos","id":917575,"avatar_url":"https://avatars.githubusercontent.com/u/917575?v=3","gravatar_id":"","url":"https://api.github.com/users/antonivanopoulos","html_url":"https://github.com/antonivanopoulos","followers_url":"https://api.github.com/users/antonivanopoulos/followers","following_url":"https://api.github.com/users/antonivanopoulos/following{/other_user}","gists_url":"https://api.github.com/users/antonivanopoulos/gists{/gist_id}","starred_url":"https://api.github.com/users/antonivanopoulos/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/antonivanopoulos/subscriptions","organizations_url":"https://api.github.com/users/antonivanopoulos/orgs","repos_url":"https://api.github.com/users/antonivanopoulos/repos","events_url":"https://api.github.com/users/antonivanopoulos/events{/privacy}","received_events_url":"https://api.github.com/users/antonivanopoulos/received_events","type":"User","site_admin":false},"body":"PR involves a major rethink about how we're handling deliveries and aggregation of notifications.\r\n\r\nCurrently, the base `Notification` class knows way too much about how aggregation works, as well as when to schedule in the delivery of itself (adding onto that the different `message` methods that use view helpers to render the actual notification).\r\n\r\nWhat's been done here is break out those different concepts into their own classes. We have the following:\r\n\r\n- A presenter class that's used purely for rendering the notification text. \r\n- An aggregator class; that, given a particular notification and a set of delay intervals, will calculate which delay to use given the number of existing unread notifications in the same group.\r\n- A scheduler class that will use an aggregator, and decide whether or not a given notification needs to be delivered at all. If so, it will create a `Delivery` record for each channel the notification is subscribed to.\r\n\r\nThe new `Delivery` model represents a delivery to be made of a given notification to a given channel. If a notification class is subscribed to both APNS and GCM, a new notification of that type will end up with two deliveries, one for APNS and one for GCM. When the delivery happens for each channel, the send time can be recorded on the delivery itself, which saves us from the issue currently where a notification gets marked as sent, despite one of those channels potentially failing.","created_at":"2016-08-17T05:33:19Z","updated_at":"2016-08-17T06:56:45Z","closed_at":null,"merged_at":null,"merge_commit_sha":"11d1680fcfc67332a853528fc5e6237d15bfee10","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/Papercloud/notify_user/pulls/35/commits","review_comments_url":"https://api.github.com/repos/Papercloud/notify_user/pulls/35/comments","review_comment_url":"https://api.github.com/repos/Papercloud/notify_user/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Papercloud/notify_user/issues/35/comments","statuses_url":"https://api.github.com/repos/Papercloud/notify_user/statuses/164b0b7cb87c68fe9ab7680c5564de24f55c71ec","head":{"label":"Papercloud:1.0.0-refactor","ref":"1.0.0-refactor","sha":"164b0b7cb87c68fe9ab7680c5564de24f55c71ec","user":{"login":"Papercloud","id":893938,"avatar_url":"https://avatars.githubusercontent.com/u/893938?v=3","gravatar_id":"","url":"https://api.github.com/users/Papercloud","html_url":"https://github.com/Papercloud","followers_url":"https://api.github.com/users/Papercloud/followers","following_url":"https://api.github.com/users/Papercloud/following{/other_user}","gists_url":"https://api.github.com/users/Papercloud/gists{/gist_id}","starred_url":"https://api.github.com/users/Papercloud/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Papercloud/subscriptions","organizations_url":"https://api.github.com/users/Papercloud/orgs","repos_url":"https://api.github.com/users/Papercloud/repos","events_url":"https://api.github.com/users/Papercloud/events{/privacy}","received_events_url":"https://api.github.com/users/Papercloud/received_events","type":"Organization","site_admin":false},"repo":{"id":15039722,"name":"notify_user","full_name":"Papercloud/notify_user","owner":{"login":"Papercloud","id":893938,"avatar_url":"https://avatars.githubusercontent.com/u/893938?v=3","gravatar_id":"","url":"https://api.github.com/users/Papercloud","html_url":"https://github.com/Papercloud","followers_url":"https://api.github.com/users/Papercloud/followers","following_url":"https://api.github.com/users/Papercloud/following{/other_user}","gists_url":"https://api.github.com/users/Papercloud/gists{/gist_id}","starred_url":"https://api.github.com/users/Papercloud/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Papercloud/subscriptions","organizations_url":"https://api.github.com/users/Papercloud/orgs","repos_url":"https://api.github.com/users/Papercloud/repos","events_url":"https://api.github.com/users/Papercloud/events{/privacy}","received_events_url":"https://api.github.com/users/Papercloud/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Papercloud/notify_user","description":"A Rails engine for user notifications.","fork":false,"url":"https://api.github.com/repos/Papercloud/notify_user","forks_url":"https://api.github.com/repos/Papercloud/notify_user/forks","keys_url":"https://api.github.com/repos/Papercloud/notify_user/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Papercloud/notify_user/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Papercloud/notify_user/teams","hooks_url":"https://api.github.com/repos/Papercloud/notify_user/hooks","issue_events_url":"https://api.github.com/repos/Papercloud/notify_user/issues/events{/number}","events_url":"https://api.github.com/repos/Papercloud/notify_user/events","assignees_url":"https://api.github.com/repos/Papercloud/notify_user/assignees{/user}","branches_url":"https://api.github.com/repos/Papercloud/notify_user/branches{/branch}","tags_url":"https://api.github.com/repos/Papercloud/notify_user/tags","blobs_url":"https://api.github.com/repos/Papercloud/notify_user/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Papercloud/notify_user/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Papercloud/notify_user/git/refs{/sha}","trees_url":"https://api.github.com/repos/Papercloud/notify_user/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Papercloud/notify_user/statuses/{sha}","languages_url":"https://api.github.com/repos/Papercloud/notify_user/languages","stargazers_url":"https://api.github.com/repos/Papercloud/notify_user/stargazers","contributors_url":"https://api.github.com/repos/Papercloud/notify_user/contributors","subscribers_url":"https://api.github.com/repos/Papercloud/notify_user/subscribers","subscription_url":"https://api.github.com/repos/Papercloud/notify_user/subscription","commits_url":"https://api.github.com/repos/Papercloud/notify_user/commits{/sha}","git_commits_url":"https://api.github.com/repos/Papercloud/notify_user/git/commits{/sha}","comments_url":"https://api.github.com/repos/Papercloud/notify_user/comments{/number}","issue_comment_url":"https://api.github.com/repos/Papercloud/notify_user/issues/comments{/number}","contents_url":"https://api.github.com/repos/Papercloud/notify_user/contents/{+path}","compare_url":"https://api.github.com/repos/Papercloud/notify_user/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Papercloud/notify_user/merges","archive_url":"https://api.github.com/repos/Papercloud/notify_user/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Papercloud/notify_user/downloads","issues_url":"https://api.github.com/repos/Papercloud/notify_user/issues{/number}","pulls_url":"https://api.github.com/repos/Papercloud/notify_user/pulls{/number}","milestones_url":"https://api.github.com/repos/Papercloud/notify_user/milestones{/number}","notifications_url":"https://api.github.com/repos/Papercloud/notify_user/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Papercloud/notify_user/labels{/name}","releases_url":"https://api.github.com/repos/Papercloud/notify_user/releases{/id}","deployments_url":"https://api.github.com/repos/Papercloud/notify_user/deployments","created_at":"2013-12-09T06:16:39Z","updated_at":"2016-01-22T14:28:22Z","pushed_at":"2016-08-17T05:33:19Z","git_url":"git://github.com/Papercloud/notify_user.git","ssh_url":"git@github.com:Papercloud/notify_user.git","clone_url":"https://github.com/Papercloud/notify_user.git","svn_url":"https://github.com/Papercloud/notify_user","homepage":"","size":6252,"stargazers_count":7,"watchers_count":7,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":4,"forks":1,"open_issues":4,"watchers":7,"default_branch":"master"}},"base":{"label":"Papercloud:1.0.0-rc","ref":"1.0.0-rc","sha":"12f93c60b06bcaafbd77d7b8708fc811e314c88f","user":{"login":"Papercloud","id":893938,"avatar_url":"https://avatars.githubusercontent.com/u/893938?v=3","gravatar_id":"","url":"https://api.github.com/users/Papercloud","html_url":"https://github.com/Papercloud","followers_url":"https://api.github.com/users/Papercloud/followers","following_url":"https://api.github.com/users/Papercloud/following{/other_user}","gists_url":"https://api.github.com/users/Papercloud/gists{/gist_id}","starred_url":"https://api.github.com/users/Papercloud/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Papercloud/subscriptions","organizations_url":"https://api.github.com/users/Papercloud/orgs","repos_url":"https://api.github.com/users/Papercloud/repos","events_url":"https://api.github.com/users/Papercloud/events{/privacy}","received_events_url":"https://api.github.com/users/Papercloud/received_events","type":"Organization","site_admin":false},"repo":{"id":15039722,"name":"notify_user","full_name":"Papercloud/notify_user","owner":{"login":"Papercloud","id":893938,"avatar_url":"https://avatars.githubusercontent.com/u/893938?v=3","gravatar_id":"","url":"https://api.github.com/users/Papercloud","html_url":"https://github.com/Papercloud","followers_url":"https://api.github.com/users/Papercloud/followers","following_url":"https://api.github.com/users/Papercloud/following{/other_user}","gists_url":"https://api.github.com/users/Papercloud/gists{/gist_id}","starred_url":"https://api.github.com/users/Papercloud/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Papercloud/subscriptions","organizations_url":"https://api.github.com/users/Papercloud/orgs","repos_url":"https://api.github.com/users/Papercloud/repos","events_url":"https://api.github.com/users/Papercloud/events{/privacy}","received_events_url":"https://api.github.com/users/Papercloud/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Papercloud/notify_user","description":"A Rails engine for user notifications.","fork":false,"url":"https://api.github.com/repos/Papercloud/notify_user","forks_url":"https://api.github.com/repos/Papercloud/notify_user/forks","keys_url":"https://api.github.com/repos/Papercloud/notify_user/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Papercloud/notify_user/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Papercloud/notify_user/teams","hooks_url":"https://api.github.com/repos/Papercloud/notify_user/hooks","issue_events_url":"https://api.github.com/repos/Papercloud/notify_user/issues/events{/number}","events_url":"https://api.github.com/repos/Papercloud/notify_user/events","assignees_url":"https://api.github.com/repos/Papercloud/notify_user/assignees{/user}","branches_url":"https://api.github.com/repos/Papercloud/notify_user/branches{/branch}","tags_url":"https://api.github.com/repos/Papercloud/notify_user/tags","blobs_url":"https://api.github.com/repos/Papercloud/notify_user/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Papercloud/notify_user/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Papercloud/notify_user/git/refs{/sha}","trees_url":"https://api.github.com/repos/Papercloud/notify_user/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Papercloud/notify_user/statuses/{sha}","languages_url":"https://api.github.com/repos/Papercloud/notify_user/languages","stargazers_url":"https://api.github.com/repos/Papercloud/notify_user/stargazers","contributors_url":"https://api.github.com/repos/Papercloud/notify_user/contributors","subscribers_url":"https://api.github.com/repos/Papercloud/notify_user/subscribers","subscription_url":"https://api.github.com/repos/Papercloud/notify_user/subscription","commits_url":"https://api.github.com/repos/Papercloud/notify_user/commits{/sha}","git_commits_url":"https://api.github.com/repos/Papercloud/notify_user/git/commits{/sha}","comments_url":"https://api.github.com/repos/Papercloud/notify_user/comments{/number}","issue_comment_url":"https://api.github.com/repos/Papercloud/notify_user/issues/comments{/number}","contents_url":"https://api.github.com/repos/Papercloud/notify_user/contents/{+path}","compare_url":"https://api.github.com/repos/Papercloud/notify_user/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Papercloud/notify_user/merges","archive_url":"https://api.github.com/repos/Papercloud/notify_user/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Papercloud/notify_user/downloads","issues_url":"https://api.github.com/repos/Papercloud/notify_user/issues{/number}","pulls_url":"https://api.github.com/repos/Papercloud/notify_user/pulls{/number}","milestones_url":"https://api.github.com/repos/Papercloud/notify_user/milestones{/number}","notifications_url":"https://api.github.com/repos/Papercloud/notify_user/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Papercloud/notify_user/labels{/name}","releases_url":"https://api.github.com/repos/Papercloud/notify_user/releases{/id}","deployments_url":"https://api.github.com/repos/Papercloud/notify_user/deployments","created_at":"2013-12-09T06:16:39Z","updated_at":"2016-01-22T14:28:22Z","pushed_at":"2016-08-17T05:33:19Z","git_url":"git://github.com/Papercloud/notify_user.git","ssh_url":"git@github.com:Papercloud/notify_user.git","clone_url":"https://github.com/Papercloud/notify_user.git","svn_url":"https://github.com/Papercloud/notify_user","homepage":"","size":6252,"stargazers_count":7,"watchers_count":7,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":4,"forks":1,"open_issues":4,"watchers":7,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Papercloud/notify_user/pulls/35"},"html":{"href":"https://github.com/Papercloud/notify_user/pull/35"},"issue":{"href":"https://api.github.com/repos/Papercloud/notify_user/issues/35"},"comments":{"href":"https://api.github.com/repos/Papercloud/notify_user/issues/35/comments"},"review_comments":{"href":"https://api.github.com/repos/Papercloud/notify_user/pulls/35/comments"},"review_comment":{"href":"https://api.github.com/repos/Papercloud/notify_user/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Papercloud/notify_user/pulls/35/commits"},"statuses":{"href":"https://api.github.com/repos/Papercloud/notify_user/statuses/164b0b7cb87c68fe9ab7680c5564de24f55c71ec"}}}}
{"actor":{"display_login":"antonivanopoulos"}}