FEATURE: add support for like webhooks (#12917)
* FEATURE: add support for like webhooks Add support for like webhooks. Webhook events only send on user membership in the defined webhook group filters. This also fixes group webhook events, as before this was never used, and the logic was not correct.
This commit is contained in:
parent
656b0ae39e
commit
75e159f0ed
|
@ -115,8 +115,8 @@ module Jobs
|
|||
end
|
||||
|
||||
def group_webhook_invalid?
|
||||
@web_hook.group_ids.present? && (@arguments[:group_id].present? ||
|
||||
!@web_hook.group_ids.include?(@arguments[:group_id]))
|
||||
@web_hook.group_ids.present? && (@arguments[:group_ids].blank? ||
|
||||
(@web_hook.group_ids & @arguments[:group_ids]).blank?)
|
||||
end
|
||||
|
||||
def category_webhook_invalid?
|
||||
|
|
|
@ -57,13 +57,14 @@ class WebHook < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
|
||||
def self.enqueue_object_hooks(type, object, event, serializer = nil)
|
||||
def self.enqueue_object_hooks(type, object, event, serializer = nil, opts = {})
|
||||
if active_web_hooks(type).exists?
|
||||
payload = WebHook.generate_payload(type, object, serializer)
|
||||
|
||||
WebHook.enqueue_hooks(type, event,
|
||||
id: object.id,
|
||||
payload: payload
|
||||
WebHook.enqueue_hooks(type, event, opts.merge(
|
||||
id: object.id,
|
||||
payload: payload
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -13,6 +13,7 @@ class WebHookEventType < ActiveRecord::Base
|
|||
ASSIGN = 12
|
||||
USER_BADGE = 13
|
||||
GROUP_USER = 14
|
||||
LIKE = 15
|
||||
|
||||
has_and_belongs_to_many :web_hooks
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
class WebHookLikeSerializer < ApplicationSerializer
|
||||
has_one :post, serializer: WebHookPostSerializer, embed: :objects
|
||||
has_one :user, serializer: BasicUserSerializer, embed: :objects
|
||||
end
|
|
@ -106,3 +106,9 @@ DiscourseEvent.on(:user_added_to_group) do |user, group, options|
|
|||
group_user = GroupUser.find_by(user: user, group: group)
|
||||
WebHook.enqueue_object_hooks(:group_user, group_user, :user_added_to_group, WebHookGroupUserSerializer)
|
||||
end
|
||||
|
||||
DiscourseEvent.on(:like_created) do |post_action|
|
||||
user = post_action.user
|
||||
group_ids = user.groups.map(&:id)
|
||||
WebHook.enqueue_object_hooks(:like, post_action, :post_liked, WebHookLikeSerializer, group_ids: group_ids)
|
||||
end
|
||||
|
|
|
@ -4040,6 +4040,9 @@ en:
|
|||
group_user_event:
|
||||
name: "Group User Event"
|
||||
details: "When a user is added or removed in a group."
|
||||
like_event:
|
||||
name: "Like Event"
|
||||
details: "When a user likes a post."
|
||||
delivery_status:
|
||||
title: "Delivery Status"
|
||||
inactive: "Inactive"
|
||||
|
|
|
@ -59,3 +59,8 @@ WebHookEventType.seed do |b|
|
|||
b.id = WebHookEventType::GROUP_USER
|
||||
b.name = "group_user"
|
||||
end
|
||||
|
||||
WebHookEventType.seed do |b|
|
||||
b.id = WebHookEventType::LIKE
|
||||
b.name = "like"
|
||||
end
|
||||
|
|
|
@ -102,3 +102,11 @@ Fabricator(:group_user_web_hook, from: :web_hook) do
|
|||
web_hook.web_hook_event_types = [transients[:group_user_hook]]
|
||||
end
|
||||
end
|
||||
|
||||
Fabricator(:like_web_hook, from: :web_hook) do
|
||||
transient like_hook: WebHookEventType.find_by(name: 'like')
|
||||
|
||||
after_build do |web_hook, transients|
|
||||
web_hook.web_hook_event_types = [transients[:like_hook]]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -234,6 +234,42 @@ describe Jobs::EmitWebHookEvent do
|
|||
end
|
||||
end
|
||||
|
||||
context 'with group filters' do
|
||||
fab!(:group) { Fabricate(:group) }
|
||||
fab!(:user) { Fabricate(:user, groups: [group]) }
|
||||
fab!(:like_hook) { Fabricate(:like_web_hook, groups: [group]) }
|
||||
|
||||
it "doesn't emit when event is not included any groups" do
|
||||
subject.execute(
|
||||
web_hook_id: like_hook.id,
|
||||
event_type: 'like',
|
||||
payload: { test: "some payload" }.to_json
|
||||
)
|
||||
end
|
||||
|
||||
it "doesn't emit when event is not related with defined groups" do
|
||||
subject.execute(
|
||||
web_hook_id: like_hook.id,
|
||||
event_type: 'like',
|
||||
group_ids: [Fabricate(:group).id],
|
||||
payload: { test: "some payload" }.to_json
|
||||
)
|
||||
end
|
||||
|
||||
it 'emit when event is related with defined groups' do
|
||||
stub_request(:post, like_hook.payload_url)
|
||||
.with(body: "{\"like\":{\"test\":\"some payload\"}}")
|
||||
.to_return(body: 'OK', status: 200)
|
||||
|
||||
subject.execute(
|
||||
web_hook_id: like_hook.id,
|
||||
event_type: 'like',
|
||||
group_ids: user.groups.pluck(:id),
|
||||
payload: { test: "some payload" }.to_json
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#send_webhook!' do
|
||||
it 'creates delivery event record' do
|
||||
stub_request(:post, post_hook.payload_url)
|
||||
|
|
|
@ -572,5 +572,25 @@ describe WebHook do
|
|||
expect(payload["group_id"]).to eq(group.id)
|
||||
expect(payload["user_id"]).to eq(user.id)
|
||||
end
|
||||
|
||||
it 'should enqueue hooks for user likes in a group' do
|
||||
group = Fabricate(:group)
|
||||
Fabricate(:like_web_hook, groups: [group])
|
||||
group_user = Fabricate(:group_user, group: group, user: user)
|
||||
poster = Fabricate(:user)
|
||||
post = Fabricate(:post, user: poster)
|
||||
like = Fabricate(:post_action, post: post, user: user, post_action_type_id: PostActionType.types[:like])
|
||||
now = Time.now
|
||||
freeze_time now
|
||||
|
||||
DiscourseEvent.trigger(:like_created, like)
|
||||
|
||||
job_args = Jobs::EmitWebHookEvent.jobs.last["args"].first
|
||||
expect(job_args["event_name"]).to eq("post_liked")
|
||||
expect(job_args["group_ids"]).to eq([group.id])
|
||||
payload = JSON.parse(job_args["payload"])
|
||||
expect(payload["post"]["id"]).to eq(post.id)
|
||||
expect(payload["user"]["id"]).to eq(user.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue