{"action":"created","comment":{"url":"https://api.github.com/repos/google/WebFundamentals/pulls/comments/68775136","id":68775136,"diff_hunk":"@@ -0,0 +1,243 @@\n+---  \n+layout: shared/narrow\n+title: \"What makes a good notification?\"\n+description: \"There are right ways of using notifications, and ways of using\n+them better. Learn what makes a good notification. We won't just show you what\n+to do. We'll show you how to do it.\"\n+published_on: 2016-07-01\n+updated_on: 2016-07-01\n+order: 10\n+translation_priority: 0\n+authors:\n+  - josephmedley\n+---\n+\n+<p class=\"intro\">\n+You've no doubt implemented some form of notification before. Maybe you've\n+used them in a native application. Perhaps you've created your own web\n+notifications from scratch. Maybe you've never done anything like them.\n+Regardless, there are right ways of using them, and ways of using them better.\n+Let's start our review of notifications by demonstrating what makes a good\n+notification. We won't just show you what to do. We'll show you how to do it.\n+</p>\n+\n+{% include shared/toc.liquid %}\n+\n+## Timely {#timely}\n+\n+A timely notification is a notification that appears when users want it and\n+when it matters to them. Timely means timely to the user, not necessarily timely\n+to you.\n+\n+### Make it available regardless of connectivity {#make-it-available}\n+\n+You'll want to show most notices right away. There are reasons to hold on to a\n+notice before showing it, the least of which is that push payloads may not be\n+supported on all platforms, so you may need to fetch the critical information\n+before displaying it.\n+\n+Until recently only mobile apps could do this. With service workers you can\n+store a notification until a user wants it. When the user clicks it, the status\n+of the network is irrelevant.\n+\n+{% highlight javascript %}\n+self.addEventListener('push', event => {\n+  var dataPromise;\n+  if (data in event) {\n+    dataPromise = Promise.resolve(event.data.json());\n+  } else {\n+    dataPromise = fetch('notification/end/point/data.json')\n+      .then(response => {\n+        return response.json();\n+      });\n+  }\n+\n+  event.waitUntil(\n+    dataPromise\n+    .then(msgData => {\n+      // Now tell the user.\n+      return self.registration.showNotification(data.title, {\n+        // Whether you show data and how much you show depends on\n+        // content of the data itself.\n+        body: event.data.body,\n+        icon: 'images/icon.png'\n+      });\n+    })\n+  );\n+}); \n+{% endhighlight %}\n+\n+### Use vibration judiciously {#vibrate-judiciously}\n+\n+Vibration may seem like an odd thing to list under timely. In fact, it's closely\n+related and there are several issues.\n+\n+First, vibration may seem like the ideal way to make users aware of new\n+notifications. But not all users have vibrations turned on and some devices\n+can't vibrate. Consequently, any urgency that you intend to communicate with\n+vibration can be lost.\n+\n+Second, making every notification vibrate can create a false sense of urgency.\n+If users are being nagged by notifications that aren't as important as they\n+seem, they may turn off notifications entirely.\n+\n+In short, let the user decide how to use vibrations. Give them the ability to\n+select which notifications use vibrations or whether to use them at all. If you\n+have different categories of notifications, you could even let them select\n+different vibration patterns.\n+\n+Finally, remember that to vibrate a mobile device has to run a motor and motors\n+use more power than an on-screen notification.\n+\n+## Precise {#precise}\n+\n+A precise notification is one that has specific information that can be acted on\n+immediately. Consider the image from the anatomy lesson again.\n+\n+<img src=\"images/joe-asked.png\" width=\"300\" height=\"109\" />\n+\n+It tells you:\n+\n+* Who sent the message.\n+* An image so that you don't confuse the sender with any old average Joe.\n+* Since the notification is a question, you can turn him down with as little\n+  effort as is humanly possible.\n+\n+### Offer enough information that the user doesn't need to visit your site {#offer-enough}\n+\n+This may not be appropriate in every case, but if the information is simple\n+enough to convey in a small space, don't make users open your web site to read\n+it. For example, if you wanted to notify one user of acknowledgment by another,\n+then don't show a message that says, \"New notification\". Show one that says,\n+\"Pete said, 'no'.\"\n+\n+Good:\n+<img src=\"images/pete-replied.png\" width=\"298\" height=\"69\" />\n+\n+Bad:\n+<img src=\"images/new-missive.png\" width=\"297\" height=\"70\" />\n+\n+This is especially important for critical information.\n+\n+Good:\n+<img src=\"images/extreme-danger.png\" width=\"304\" height=\"70\" />\n+\n+Bad:\n+<img src=\"images/suggestion.png\" width=\"301\" height=\"70\" />\n+\n+### Put actions right in the notification {#offer-actions}\n+\n+We've seen this a few times already and the anatomy lesson even showed how to\n+add them to a notification. The service worker needs to process those actions.\n+Do this in the notificationclick event.\n+\n+{% highlight javascript %}\n+self.addEventListener('notificationclick', event => {\n+  var messageId = event.notification.data;\n+  \n+  event.notification.close();\n+\n+  if (event.action) {\n+    // Send the response directly to the server.\n+  } else {\n+    // Open the app.\n+  }\n+}, false);\n+{% endhighlight %}\n+\n+### Make the title and content specific {#specific-title}\n+\n+Make the title relevant to the context of the message and include something\n+specific from the message.\n+\n+Good:","path":"src/content/en/fundamentals/engage-and-retain/push-notifications/good-notification.markdown","position":153,"original_position":153,"commit_id":"4108afa3eb0f2ec1045ff22a717a4879d1fbb0a0","original_commit_id":"4108afa3eb0f2ec1045ff22a717a4879d1fbb0a0","user":{"login":"petele","id":718038,"avatar_url":"https://avatars.githubusercontent.com/u/718038?v=3","gravatar_id":"","url":"https://api.github.com/users/petele","html_url":"https://github.com/petele","followers_url":"https://api.github.com/users/petele/followers","following_url":"https://api.github.com/users/petele/following{/other_user}","gists_url":"https://api.github.com/users/petele/gists{/gist_id}","starred_url":"https://api.github.com/users/petele/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/petele/subscriptions","organizations_url":"https://api.github.com/users/petele/orgs","repos_url":"https://api.github.com/users/petele/repos","events_url":"https://api.github.com/users/petele/events{/privacy}","received_events_url":"https://api.github.com/users/petele/received_events","type":"User","site_admin":false},"body":"Good/Bad images","created_at":"2016-06-28T15:04:42Z","updated_at":"2016-06-28T15:04:42Z","html_url":"https://github.com/google/WebFundamentals/pull/3031#discussion_r68775136","pull_request_url":"https://api.github.com/repos/google/WebFundamentals/pulls/3031","_links":{"self":{"href":"https://api.github.com/repos/google/WebFundamentals/pulls/comments/68775136"},"html":{"href":"https://github.com/google/WebFundamentals/pull/3031#discussion_r68775136"},"pull_request":{"href":"https://api.github.com/repos/google/WebFundamentals/pulls/3031"}}},"pull_request":{"url":"https://api.github.com/repos/google/WebFundamentals/pulls/3031","id":75390693,"html_url":"https://github.com/google/WebFundamentals/pull/3031","diff_url":"https://github.com/google/WebFundamentals/pull/3031.diff","patch_url":"https://github.com/google/WebFundamentals/pull/3031.patch","issue_url":"https://api.github.com/repos/google/WebFundamentals/issues/3031","number":3031,"state":"open","locked":false,"title":"New Push Notifications Section for Engage and Retain","user":{"login":"jpmedley","id":8204171,"avatar_url":"https://avatars.githubusercontent.com/u/8204171?v=3","gravatar_id":"","url":"https://api.github.com/users/jpmedley","html_url":"https://github.com/jpmedley","followers_url":"https://api.github.com/users/jpmedley/followers","following_url":"https://api.github.com/users/jpmedley/following{/other_user}","gists_url":"https://api.github.com/users/jpmedley/gists{/gist_id}","starred_url":"https://api.github.com/users/jpmedley/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jpmedley/subscriptions","organizations_url":"https://api.github.com/users/jpmedley/orgs","repos_url":"https://api.github.com/users/jpmedley/repos","events_url":"https://api.github.com/users/jpmedley/events{/privacy}","received_events_url":"https://api.github.com/users/jpmedley/received_events","type":"User","site_admin":false},"body":"","created_at":"2016-06-27T22:28:57Z","updated_at":"2016-06-28T15:04:42Z","closed_at":null,"merged_at":null,"merge_commit_sha":"0646ab7ae36647a2541e87819c0196bf7b340151","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/google/WebFundamentals/pulls/3031/commits","review_comments_url":"https://api.github.com/repos/google/WebFundamentals/pulls/3031/comments","review_comment_url":"https://api.github.com/repos/google/WebFundamentals/pulls/comments{/number}","comments_url":"https://api.github.com/repos/google/WebFundamentals/issues/3031/comments","statuses_url":"https://api.github.com/repos/google/WebFundamentals/statuses/4108afa3eb0f2ec1045ff22a717a4879d1fbb0a0","head":{"label":"jpmedley:enr","ref":"enr","sha":"4108afa3eb0f2ec1045ff22a717a4879d1fbb0a0","user":{"login":"jpmedley","id":8204171,"avatar_url":"https://avatars.githubusercontent.com/u/8204171?v=3","gravatar_id":"","url":"https://api.github.com/users/jpmedley","html_url":"https://github.com/jpmedley","followers_url":"https://api.github.com/users/jpmedley/followers","following_url":"https://api.github.com/users/jpmedley/following{/other_user}","gists_url":"https://api.github.com/users/jpmedley/gists{/gist_id}","starred_url":"https://api.github.com/users/jpmedley/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jpmedley/subscriptions","organizations_url":"https://api.github.com/users/jpmedley/orgs","repos_url":"https://api.github.com/users/jpmedley/repos","events_url":"https://api.github.com/users/jpmedley/events{/privacy}","received_events_url":"https://api.github.com/users/jpmedley/received_events","type":"User","site_admin":false},"repo":{"id":56626575,"name":"WebFundamentals","full_name":"jpmedley/WebFundamentals","owner":{"login":"jpmedley","id":8204171,"avatar_url":"https://avatars.githubusercontent.com/u/8204171?v=3","gravatar_id":"","url":"https://api.github.com/users/jpmedley","html_url":"https://github.com/jpmedley","followers_url":"https://api.github.com/users/jpmedley/followers","following_url":"https://api.github.com/users/jpmedley/following{/other_user}","gists_url":"https://api.github.com/users/jpmedley/gists{/gist_id}","starred_url":"https://api.github.com/users/jpmedley/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jpmedley/subscriptions","organizations_url":"https://api.github.com/users/jpmedley/orgs","repos_url":"https://api.github.com/users/jpmedley/repos","events_url":"https://api.github.com/users/jpmedley/events{/privacy}","received_events_url":"https://api.github.com/users/jpmedley/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jpmedley/WebFundamentals","description":"Best practices for modern web development","fork":true,"url":"https://api.github.com/repos/jpmedley/WebFundamentals","forks_url":"https://api.github.com/repos/jpmedley/WebFundamentals/forks","keys_url":"https://api.github.com/repos/jpmedley/WebFundamentals/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jpmedley/WebFundamentals/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jpmedley/WebFundamentals/teams","hooks_url":"https://api.github.com/repos/jpmedley/WebFundamentals/hooks","issue_events_url":"https://api.github.com/repos/jpmedley/WebFundamentals/issues/events{/number}","events_url":"https://api.github.com/repos/jpmedley/WebFundamentals/events","assignees_url":"https://api.github.com/repos/jpmedley/WebFundamentals/assignees{/user}","branches_url":"https://api.github.com/repos/jpmedley/WebFundamentals/branches{/branch}","tags_url":"https://api.github.com/repos/jpmedley/WebFundamentals/tags","blobs_url":"https://api.github.com/repos/jpmedley/WebFundamentals/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jpmedley/WebFundamentals/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jpmedley/WebFundamentals/git/refs{/sha}","trees_url":"https://api.github.com/repos/jpmedley/WebFundamentals/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jpmedley/WebFundamentals/statuses/{sha}","languages_url":"https://api.github.com/repos/jpmedley/WebFundamentals/languages","stargazers_url":"https://api.github.com/repos/jpmedley/WebFundamentals/stargazers","contributors_url":"https://api.github.com/repos/jpmedley/WebFundamentals/contributors","subscribers_url":"https://api.github.com/repos/jpmedley/WebFundamentals/subscribers","subscription_url":"https://api.github.com/repos/jpmedley/WebFundamentals/subscription","commits_url":"https://api.github.com/repos/jpmedley/WebFundamentals/commits{/sha}","git_commits_url":"https://api.github.com/repos/jpmedley/WebFundamentals/git/commits{/sha}","comments_url":"https://api.github.com/repos/jpmedley/WebFundamentals/comments{/number}","issue_comment_url":"https://api.github.com/repos/jpmedley/WebFundamentals/issues/comments{/number}","contents_url":"https://api.github.com/repos/jpmedley/WebFundamentals/contents/{+path}","compare_url":"https://api.github.com/repos/jpmedley/WebFundamentals/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jpmedley/WebFundamentals/merges","archive_url":"https://api.github.com/repos/jpmedley/WebFundamentals/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jpmedley/WebFundamentals/downloads","issues_url":"https://api.github.com/repos/jpmedley/WebFundamentals/issues{/number}","pulls_url":"https://api.github.com/repos/jpmedley/WebFundamentals/pulls{/number}","milestones_url":"https://api.github.com/repos/jpmedley/WebFundamentals/milestones{/number}","notifications_url":"https://api.github.com/repos/jpmedley/WebFundamentals/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jpmedley/WebFundamentals/labels{/name}","releases_url":"https://api.github.com/repos/jpmedley/WebFundamentals/releases{/id}","deployments_url":"https://api.github.com/repos/jpmedley/WebFundamentals/deployments","created_at":"2016-04-19T19:41:45Z","updated_at":"2016-04-19T19:41:55Z","pushed_at":"2016-06-27T22:28:16Z","git_url":"git://github.com/jpmedley/WebFundamentals.git","ssh_url":"git@github.com:jpmedley/WebFundamentals.git","clone_url":"https://github.com/jpmedley/WebFundamentals.git","svn_url":"https://github.com/jpmedley/WebFundamentals","homepage":"https://developers.google.com/web/fundamentals","size":1046592,"stargazers_count":0,"watchers_count":0,"language":"HTML","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"google:master","ref":"master","sha":"968a4a104577f8f02088920960a7de26289c646e","user":{"login":"google","id":1342004,"avatar_url":"https://avatars.githubusercontent.com/u/1342004?v=3","gravatar_id":"","url":"https://api.github.com/users/google","html_url":"https://github.com/google","followers_url":"https://api.github.com/users/google/followers","following_url":"https://api.github.com/users/google/following{/other_user}","gists_url":"https://api.github.com/users/google/gists{/gist_id}","starred_url":"https://api.github.com/users/google/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/google/subscriptions","organizations_url":"https://api.github.com/users/google/orgs","repos_url":"https://api.github.com/users/google/repos","events_url":"https://api.github.com/users/google/events{/privacy}","received_events_url":"https://api.github.com/users/google/received_events","type":"Organization","site_admin":false},"repo":{"id":19249835,"name":"WebFundamentals","full_name":"google/WebFundamentals","owner":{"login":"google","id":1342004,"avatar_url":"https://avatars.githubusercontent.com/u/1342004?v=3","gravatar_id":"","url":"https://api.github.com/users/google","html_url":"https://github.com/google","followers_url":"https://api.github.com/users/google/followers","following_url":"https://api.github.com/users/google/following{/other_user}","gists_url":"https://api.github.com/users/google/gists{/gist_id}","starred_url":"https://api.github.com/users/google/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/google/subscriptions","organizations_url":"https://api.github.com/users/google/orgs","repos_url":"https://api.github.com/users/google/repos","events_url":"https://api.github.com/users/google/events{/privacy}","received_events_url":"https://api.github.com/users/google/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/google/WebFundamentals","description":"Best practices for modern web development","fork":false,"url":"https://api.github.com/repos/google/WebFundamentals","forks_url":"https://api.github.com/repos/google/WebFundamentals/forks","keys_url":"https://api.github.com/repos/google/WebFundamentals/keys{/key_id}","collaborators_url":"https://api.github.com/repos/google/WebFundamentals/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/google/WebFundamentals/teams","hooks_url":"https://api.github.com/repos/google/WebFundamentals/hooks","issue_events_url":"https://api.github.com/repos/google/WebFundamentals/issues/events{/number}","events_url":"https://api.github.com/repos/google/WebFundamentals/events","assignees_url":"https://api.github.com/repos/google/WebFundamentals/assignees{/user}","branches_url":"https://api.github.com/repos/google/WebFundamentals/branches{/branch}","tags_url":"https://api.github.com/repos/google/WebFundamentals/tags","blobs_url":"https://api.github.com/repos/google/WebFundamentals/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/google/WebFundamentals/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/google/WebFundamentals/git/refs{/sha}","trees_url":"https://api.github.com/repos/google/WebFundamentals/git/trees{/sha}","statuses_url":"https://api.github.com/repos/google/WebFundamentals/statuses/{sha}","languages_url":"https://api.github.com/repos/google/WebFundamentals/languages","stargazers_url":"https://api.github.com/repos/google/WebFundamentals/stargazers","contributors_url":"https://api.github.com/repos/google/WebFundamentals/contributors","subscribers_url":"https://api.github.com/repos/google/WebFundamentals/subscribers","subscription_url":"https://api.github.com/repos/google/WebFundamentals/subscription","commits_url":"https://api.github.com/repos/google/WebFundamentals/commits{/sha}","git_commits_url":"https://api.github.com/repos/google/WebFundamentals/git/commits{/sha}","comments_url":"https://api.github.com/repos/google/WebFundamentals/comments{/number}","issue_comment_url":"https://api.github.com/repos/google/WebFundamentals/issues/comments{/number}","contents_url":"https://api.github.com/repos/google/WebFundamentals/contents/{+path}","compare_url":"https://api.github.com/repos/google/WebFundamentals/compare/{base}...{head}","merges_url":"https://api.github.com/repos/google/WebFundamentals/merges","archive_url":"https://api.github.com/repos/google/WebFundamentals/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/google/WebFundamentals/downloads","issues_url":"https://api.github.com/repos/google/WebFundamentals/issues{/number}","pulls_url":"https://api.github.com/repos/google/WebFundamentals/pulls{/number}","milestones_url":"https://api.github.com/repos/google/WebFundamentals/milestones{/number}","notifications_url":"https://api.github.com/repos/google/WebFundamentals/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/google/WebFundamentals/labels{/name}","releases_url":"https://api.github.com/repos/google/WebFundamentals/releases{/id}","deployments_url":"https://api.github.com/repos/google/WebFundamentals/deployments","created_at":"2014-04-28T18:45:45Z","updated_at":"2016-06-28T13:42:15Z","pushed_at":"2016-06-28T08:13:29Z","git_url":"git://github.com/google/WebFundamentals.git","ssh_url":"git@github.com:google/WebFundamentals.git","clone_url":"https://github.com/google/WebFundamentals.git","svn_url":"https://github.com/google/WebFundamentals","homepage":"https://developers.google.com/web/fundamentals","size":1080064,"stargazers_count":5988,"watchers_count":5988,"language":"HTML","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":1097,"mirror_url":null,"open_issues_count":324,"forks":1097,"open_issues":324,"watchers":5988,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/google/WebFundamentals/pulls/3031"},"html":{"href":"https://github.com/google/WebFundamentals/pull/3031"},"issue":{"href":"https://api.github.com/repos/google/WebFundamentals/issues/3031"},"comments":{"href":"https://api.github.com/repos/google/WebFundamentals/issues/3031/comments"},"review_comments":{"href":"https://api.github.com/repos/google/WebFundamentals/pulls/3031/comments"},"review_comment":{"href":"https://api.github.com/repos/google/WebFundamentals/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/google/WebFundamentals/pulls/3031/commits"},"statuses":{"href":"https://api.github.com/repos/google/WebFundamentals/statuses/4108afa3eb0f2ec1045ff22a717a4879d1fbb0a0"}}}}
{"actor":{"display_login":"petele"}}