From b4878cde6f959ebb5a56dcdd702a209eab3dd7db Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Thu, 15 Aug 2019 14:45:30 -0400 Subject: [PATCH] FEATURE: Add a webhook for user notifications If enabled, this will fire a webhook whenever a user's notification has been created. This could potentially be a lot of data depending on your forum, and should be used carefully since it includes everything all users will see in their feeds. --- app/models/notification.rb | 4 ++++ app/models/web_hook_event_type.rb | 1 + config/initializers/012-web_hook_events.rb | 4 ++++ config/locales/client.en.yml | 3 +++ db/fixtures/007_web_hook_event_types.rb | 5 +++++ spec/fabricators/web_hook_fabricator.rb | 8 ++++++++ spec/models/web_hook_spec.rb | 10 ++++++++++ 7 files changed, 35 insertions(+) diff --git a/app/models/notification.rb b/app/models/notification.rb index fdfd00655df..b31812c75af 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -26,6 +26,10 @@ class Notification < ActiveRecord::Base after_commit :send_email, on: :create after_commit :refresh_notification_count, on: [:create, :update, :destroy] + after_commit(on: :create) do + DiscourseEvent.trigger(:notification_created, self) + end + def self.ensure_consistency! DB.exec(<<~SQL, Notification.types[:private_message]) DELETE diff --git a/app/models/web_hook_event_type.rb b/app/models/web_hook_event_type.rb index 297c11776ff..719ceaa712e 100644 --- a/app/models/web_hook_event_type.rb +++ b/app/models/web_hook_event_type.rb @@ -10,6 +10,7 @@ class WebHookEventType < ActiveRecord::Base FLAG = 7 QUEUED_POST = 8 REVIEWABLE = 9 + NOTIFICATION = 10 has_and_belongs_to_many :web_hooks diff --git a/config/initializers/012-web_hook_events.rb b/config/initializers/012-web_hook_events.rb index 1451a5ddeea..d93faa08562 100644 --- a/config/initializers/012-web_hook_events.rb +++ b/config/initializers/012-web_hook_events.rb @@ -106,3 +106,7 @@ DiscourseEvent.on(:reviewable_transitioned_to) do |status, reviewable| end end end + +DiscourseEvent.on(:notification_created) do |notification| + WebHook.enqueue_object_hooks(:notification, notification, :notification_created, NotificationSerializer) +end diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 583e88637c9..940879d8977 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -3322,6 +3322,9 @@ en: reviewable_event: name: "Reviewable Event" details: "When a new item is ready for review and when its status is updated." + notification_event: + name: "Notification Event" + details: "When a user receives a notification in their feed." delivery_status: title: "Delivery Status" inactive: "Inactive" diff --git a/db/fixtures/007_web_hook_event_types.rb b/db/fixtures/007_web_hook_event_types.rb index 4f3d2d15df3..0645cfad8e5 100644 --- a/db/fixtures/007_web_hook_event_types.rb +++ b/db/fixtures/007_web_hook_event_types.rb @@ -44,3 +44,8 @@ WebHookEventType.seed do |b| b.id = WebHookEventType::REVIEWABLE b.name = "reviewable" end + +WebHookEventType.seed do |b| + b.id = WebHookEventType::NOTIFICATION + b.name = "notification" +end diff --git a/spec/fabricators/web_hook_fabricator.rb b/spec/fabricators/web_hook_fabricator.rb index eff69dff40a..6d03c7b47f7 100644 --- a/spec/fabricators/web_hook_fabricator.rb +++ b/spec/fabricators/web_hook_fabricator.rb @@ -94,3 +94,11 @@ Fabricator(:reviewable_web_hook, from: :web_hook) do web_hook.web_hook_event_types = [transients[:reviewable_hook]] end end + +Fabricator(:notification_web_hook, from: :web_hook) do + transient notification_hook: WebHookEventType.find_by(name: 'notification') + + after_build do |web_hook, transients| + web_hook.web_hook_event_types = [transients[:notification_hook]] + end +end diff --git a/spec/models/web_hook_spec.rb b/spec/models/web_hook_spec.rb index 92283e49c4d..bc4b0f4d6f4 100644 --- a/spec/models/web_hook_spec.rb +++ b/spec/models/web_hook_spec.rb @@ -508,6 +508,16 @@ describe WebHook do expect(payload["id"]).to eq(reviewable.id) end + it 'should enqueue the right hooks for notifications' do + Fabricate(:notification_web_hook) + notification = Fabricate(:notification) + job_args = Jobs::EmitWebHookEvent.jobs.last["args"].first + + expect(job_args["event_name"]).to eq("notification_created") + payload = JSON.parse(job_args["payload"]) + expect(payload["id"]).to eq(notification.id) + end + it 'should enqueue the right hooks for reviewables' do Fabricate(:reviewable_web_hook) reviewable = Fabricate(:reviewable)