{"action":"created","comment":{"url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/pulls/comments/243832485","pull_request_review_id":187701559,"id":243832485,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDI0MzgzMjQ4NQ==","diff_hunk":"@@ -90,3 +90,5 @@ test_keys.json\n ###########\n .vagrant/\n dev-datastore/\n+\n+zach-tba-dev-firebase-adminsdk-355dn-5fe528f891.json","path":".gitignore","position":5,"original_position":5,"commit_id":"9bf6ecf7a001a9b458b97d0cef8aaade48f63e5e","original_commit_id":"9bf6ecf7a001a9b458b97d0cef8aaade48f63e5e","user":{"login":"gregmarra","id":57101,"node_id":"MDQ6VXNlcjU3MTAx","avatar_url":"https://avatars0.githubusercontent.com/u/57101?v=4","gravatar_id":"","url":"https://api.github.com/users/gregmarra","html_url":"https://github.com/gregmarra","followers_url":"https://api.github.com/users/gregmarra/followers","following_url":"https://api.github.com/users/gregmarra/following{/other_user}","gists_url":"https://api.github.com/users/gregmarra/gists{/gist_id}","starred_url":"https://api.github.com/users/gregmarra/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gregmarra/subscriptions","organizations_url":"https://api.github.com/users/gregmarra/orgs","repos_url":"https://api.github.com/users/gregmarra/repos","events_url":"https://api.github.com/users/gregmarra/events{/privacy}","received_events_url":"https://api.github.com/users/gregmarra/received_events","type":"User","site_admin":false},"body":"Don't forget to remove this zach-specific line, if it is zach specific.","created_at":"2018-12-24T14:14:29Z","updated_at":"2018-12-24T14:14:29Z","html_url":"https://github.com/the-blue-alliance/the-blue-alliance/pull/2355#discussion_r243832485","pull_request_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/pulls/2355","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/pulls/comments/243832485"},"html":{"href":"https://github.com/the-blue-alliance/the-blue-alliance/pull/2355#discussion_r243832485"},"pull_request":{"href":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/pulls/2355"}}},"pull_request":{"url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/pulls/2355","id":240727565,"node_id":"MDExOlB1bGxSZXF1ZXN0MjQwNzI3NTY1","html_url":"https://github.com/the-blue-alliance/the-blue-alliance/pull/2355","diff_url":"https://github.com/the-blue-alliance/the-blue-alliance/pull/2355.diff","patch_url":"https://github.com/the-blue-alliance/the-blue-alliance/pull/2355.patch","issue_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/issues/2355","number":2355,"state":"open","locked":false,"title":"[WIP] TBA Notification Service, using Firebase HTTPv1 API","user":{"login":"ZachOrr","id":516458,"node_id":"MDQ6VXNlcjUxNjQ1OA==","avatar_url":"https://avatars2.githubusercontent.com/u/516458?v=4","gravatar_id":"","url":"https://api.github.com/users/ZachOrr","html_url":"https://github.com/ZachOrr","followers_url":"https://api.github.com/users/ZachOrr/followers","following_url":"https://api.github.com/users/ZachOrr/following{/other_user}","gists_url":"https://api.github.com/users/ZachOrr/gists{/gist_id}","starred_url":"https://api.github.com/users/ZachOrr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ZachOrr/subscriptions","organizations_url":"https://api.github.com/users/ZachOrr/orgs","repos_url":"https://api.github.com/users/ZachOrr/repos","events_url":"https://api.github.com/users/ZachOrr/events{/privacy}","received_events_url":"https://api.github.com/users/ZachOrr/received_events","type":"User","site_admin":false},"body":"Throwing this up so people can start to get eyes on it. This is very much a first step, and not a complete system. Reviews are appreciated.\r\n\r\n## Description\r\nThis introduces a new service - The Blue Alliance Notification Service (or TBANS). TBANS manages dispatching notifications to clients and webhooks, and managing the lifecycle of notifications (handling retries, handling failures, etc.).\r\n\r\nUp for discussion is if TBANS should manage client subscriptions, or if that should be managed by another piece of the codebase. (These subscriptions refer to Firebase topics - which will be the new system for sending notifications to multiple clients, as opposed to using an array of Firebase tokens, which isn’t supported anymore. Refer to the [Topic Messaging](https://firebase.google.com/docs/cloud-messaging/js/topic-messaging) section of the FCM documentation)\r\n\r\nFor now, TBANS only manages the immediate dispatching of ping and webhook verifications. Other notifications will be built out, but I need to think more about the subscription stuff mentioned above.\r\n\r\nUpcoming Match, Update Favorites, and Update Subscriptions notifications have been included in this PR (along with their tests), although they’re not used yet. This is to give a sense of how to use notifications with the new objects.\r\n\r\n## Motivation and Context\r\nThe old push notification system (built on the legacy Firebase API) won’t work for iOS clients moving forward. The notification payloads specified by the current notification objects aren’t structured in a way that iOS is able to make sense of them and handle them. I’m unsure about if the web will or won’t support the current notification payloads.\r\n\r\nAdditionally, the legacy notification API hasn’t been receiving updates (it’s missing some new notification features in iOS), and it doesn’t seem to support data notification on iOS (I have no idea why this is - regular title/body notifications work fine, I can’t get a data message to deliver).\r\n\r\nSince our push notification and webhook stack are so tightly coupled, TBANS will now manage dispatching messages to webhooks as well.\r\n\r\nBy splitting notifications in to it’s own service, other TBA services shouldn’t need to be concerned with constructing notification objects or sending them - only calling TBANS.\r\n\r\n## How Has This Been Tested?\r\nUnit tests, along with manual testing with webhook verification in a test instance, and pings via the ping endpoint in the mobile API\r\n\r\n## Screenshots\r\nHere's a Ping sent via the mobile API\r\n![img_0717](https://user-images.githubusercontent.com/516458/50392395-1be54600-071c-11e9-9410-9819d7d9adf8.PNG)\r\n\r\n\r\n## Outstanding Work\r\n- [ ] Need advice on service worker key file - used to generate OAuth2 tokens for the new Firebase HTTPv1 API\r\n- [ ] Finish up tests, since there’s still lots of untested code\r\n- [ ] Is there a way we can grab the project ID dynamically?\r\n- [ ] Is there a way we can grab the project host dynamically?\r\n- [ ] Finish up TBANS README (should be similar to the mobile API stuff)\r\n- [ ] Write docs for how to add notifications, talking about `platform_payload` vs other payloads, and `webhook_payload`/`data_payload`\r\n- [ ] Add logging\r\n- [ ] str/repr methods for notifications, messages, etc. for logging\r\n- [ ] Figure out if FCM passes `content-available` automatically for data messages on APNS\r\n- [ ] Handle FCM errors at all, if we can","created_at":"2018-12-24T06:35:08Z","updated_at":"2018-12-24T14:14:29Z","closed_at":null,"merged_at":null,"merge_commit_sha":"44bb03d283c39d59886aa5048b4f9a04e1d35261","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/pulls/2355/commits","review_comments_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/pulls/2355/comments","review_comment_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/pulls/comments{/number}","comments_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/issues/2355/comments","statuses_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/statuses/9bf6ecf7a001a9b458b97d0cef8aaade48f63e5e","head":{"label":"ZachOrr:zorr/new-notifications","ref":"zorr/new-notifications","sha":"9bf6ecf7a001a9b458b97d0cef8aaade48f63e5e","user":{"login":"ZachOrr","id":516458,"node_id":"MDQ6VXNlcjUxNjQ1OA==","avatar_url":"https://avatars2.githubusercontent.com/u/516458?v=4","gravatar_id":"","url":"https://api.github.com/users/ZachOrr","html_url":"https://github.com/ZachOrr","followers_url":"https://api.github.com/users/ZachOrr/followers","following_url":"https://api.github.com/users/ZachOrr/following{/other_user}","gists_url":"https://api.github.com/users/ZachOrr/gists{/gist_id}","starred_url":"https://api.github.com/users/ZachOrr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ZachOrr/subscriptions","organizations_url":"https://api.github.com/users/ZachOrr/orgs","repos_url":"https://api.github.com/users/ZachOrr/repos","events_url":"https://api.github.com/users/ZachOrr/events{/privacy}","received_events_url":"https://api.github.com/users/ZachOrr/received_events","type":"User","site_admin":false},"repo":{"id":6837206,"node_id":"MDEwOlJlcG9zaXRvcnk2ODM3MjA2","name":"the-blue-alliance","full_name":"ZachOrr/the-blue-alliance","private":false,"owner":{"login":"ZachOrr","id":516458,"node_id":"MDQ6VXNlcjUxNjQ1OA==","avatar_url":"https://avatars2.githubusercontent.com/u/516458?v=4","gravatar_id":"","url":"https://api.github.com/users/ZachOrr","html_url":"https://github.com/ZachOrr","followers_url":"https://api.github.com/users/ZachOrr/followers","following_url":"https://api.github.com/users/ZachOrr/following{/other_user}","gists_url":"https://api.github.com/users/ZachOrr/gists{/gist_id}","starred_url":"https://api.github.com/users/ZachOrr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ZachOrr/subscriptions","organizations_url":"https://api.github.com/users/ZachOrr/orgs","repos_url":"https://api.github.com/users/ZachOrr/repos","events_url":"https://api.github.com/users/ZachOrr/events{/privacy}","received_events_url":"https://api.github.com/users/ZachOrr/received_events","type":"User","site_admin":false},"html_url":"https://github.com/ZachOrr/the-blue-alliance","description":"FIRST Robotics match video archive website","fork":true,"url":"https://api.github.com/repos/ZachOrr/the-blue-alliance","forks_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/forks","keys_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/teams","hooks_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/hooks","issue_events_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/issues/events{/number}","events_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/events","assignees_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/assignees{/user}","branches_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/branches{/branch}","tags_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/tags","blobs_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/git/refs{/sha}","trees_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/statuses/{sha}","languages_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/languages","stargazers_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/stargazers","contributors_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/contributors","subscribers_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/subscribers","subscription_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/subscription","commits_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/commits{/sha}","git_commits_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/git/commits{/sha}","comments_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/comments{/number}","issue_comment_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/issues/comments{/number}","contents_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/contents/{+path}","compare_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/merges","archive_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/downloads","issues_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/issues{/number}","pulls_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/pulls{/number}","milestones_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/milestones{/number}","notifications_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/labels{/name}","releases_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/releases{/id}","deployments_url":"https://api.github.com/repos/ZachOrr/the-blue-alliance/deployments","created_at":"2012-11-24T06:55:45Z","updated_at":"2018-12-17T04:31:34Z","pushed_at":"2018-12-24T06:44:39Z","git_url":"git://github.com/ZachOrr/the-blue-alliance.git","ssh_url":"git@github.com:ZachOrr/the-blue-alliance.git","clone_url":"https://github.com/ZachOrr/the-blue-alliance.git","svn_url":"https://github.com/ZachOrr/the-blue-alliance","homepage":"thebluealliance.com","size":21522,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit","node_id":"MDc6TGljZW5zZTEz"},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"the-blue-alliance:master","ref":"master","sha":"a1ee2acdadf8637247d6b25f9b212b94f73c0e6b","user":{"login":"the-blue-alliance","id":7354965,"node_id":"MDEyOk9yZ2FuaXphdGlvbjczNTQ5NjU=","avatar_url":"https://avatars0.githubusercontent.com/u/7354965?v=4","gravatar_id":"","url":"https://api.github.com/users/the-blue-alliance","html_url":"https://github.com/the-blue-alliance","followers_url":"https://api.github.com/users/the-blue-alliance/followers","following_url":"https://api.github.com/users/the-blue-alliance/following{/other_user}","gists_url":"https://api.github.com/users/the-blue-alliance/gists{/gist_id}","starred_url":"https://api.github.com/users/the-blue-alliance/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/the-blue-alliance/subscriptions","organizations_url":"https://api.github.com/users/the-blue-alliance/orgs","repos_url":"https://api.github.com/users/the-blue-alliance/repos","events_url":"https://api.github.com/users/the-blue-alliance/events{/privacy}","received_events_url":"https://api.github.com/users/the-blue-alliance/received_events","type":"Organization","site_admin":false},"repo":{"id":888427,"node_id":"MDEwOlJlcG9zaXRvcnk4ODg0Mjc=","name":"the-blue-alliance","full_name":"the-blue-alliance/the-blue-alliance","private":false,"owner":{"login":"the-blue-alliance","id":7354965,"node_id":"MDEyOk9yZ2FuaXphdGlvbjczNTQ5NjU=","avatar_url":"https://avatars0.githubusercontent.com/u/7354965?v=4","gravatar_id":"","url":"https://api.github.com/users/the-blue-alliance","html_url":"https://github.com/the-blue-alliance","followers_url":"https://api.github.com/users/the-blue-alliance/followers","following_url":"https://api.github.com/users/the-blue-alliance/following{/other_user}","gists_url":"https://api.github.com/users/the-blue-alliance/gists{/gist_id}","starred_url":"https://api.github.com/users/the-blue-alliance/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/the-blue-alliance/subscriptions","organizations_url":"https://api.github.com/users/the-blue-alliance/orgs","repos_url":"https://api.github.com/users/the-blue-alliance/repos","events_url":"https://api.github.com/users/the-blue-alliance/events{/privacy}","received_events_url":"https://api.github.com/users/the-blue-alliance/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/the-blue-alliance/the-blue-alliance","description":"A webapp for accessing information about the FIRST Robotics Competition.","fork":false,"url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance","forks_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/forks","keys_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/keys{/key_id}","collaborators_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/teams","hooks_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/hooks","issue_events_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/issues/events{/number}","events_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/events","assignees_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/assignees{/user}","branches_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/branches{/branch}","tags_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/tags","blobs_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/git/refs{/sha}","trees_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/git/trees{/sha}","statuses_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/statuses/{sha}","languages_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/languages","stargazers_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/stargazers","contributors_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/contributors","subscribers_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/subscribers","subscription_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/subscription","commits_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/commits{/sha}","git_commits_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/git/commits{/sha}","comments_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/comments{/number}","issue_comment_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/issues/comments{/number}","contents_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/contents/{+path}","compare_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/compare/{base}...{head}","merges_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/merges","archive_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/downloads","issues_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/issues{/number}","pulls_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/pulls{/number}","milestones_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/milestones{/number}","notifications_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/labels{/name}","releases_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/releases{/id}","deployments_url":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/deployments","created_at":"2010-09-04T20:34:11Z","updated_at":"2018-12-18T02:18:36Z","pushed_at":"2018-12-24T06:44:41Z","git_url":"git://github.com/the-blue-alliance/the-blue-alliance.git","ssh_url":"git@github.com:the-blue-alliance/the-blue-alliance.git","clone_url":"https://github.com/the-blue-alliance/the-blue-alliance.git","svn_url":"https://github.com/the-blue-alliance/the-blue-alliance","homepage":"https://www.thebluealliance.com","size":21534,"stargazers_count":222,"watchers_count":222,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":131,"mirror_url":null,"archived":false,"open_issues_count":313,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit","node_id":"MDc6TGljZW5zZTEz"},"forks":131,"open_issues":313,"watchers":222,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/pulls/2355"},"html":{"href":"https://github.com/the-blue-alliance/the-blue-alliance/pull/2355"},"issue":{"href":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/issues/2355"},"comments":{"href":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/issues/2355/comments"},"review_comments":{"href":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/pulls/2355/comments"},"review_comment":{"href":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/pulls/2355/commits"},"statuses":{"href":"https://api.github.com/repos/the-blue-alliance/the-blue-alliance/statuses/9bf6ecf7a001a9b458b97d0cef8aaade48f63e5e"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"gregmarra"}}