FEATURE: Webhooks and Event for user being granted a badge
Adding a webhook for badge revocation is left for future work as it's relatively rare.
This commit is contained in:
parent
14467757df
commit
138d4aebde
|
@ -13,6 +13,7 @@ class WebHookEventType < ActiveRecord::Base
|
||||||
NOTIFICATION = 10
|
NOTIFICATION = 10
|
||||||
SOLVED = 11
|
SOLVED = 11
|
||||||
ASSIGN = 12
|
ASSIGN = 12
|
||||||
|
USER_BADGE = 13
|
||||||
|
|
||||||
has_and_belongs_to_many :web_hooks
|
has_and_belongs_to_many :web_hooks
|
||||||
|
|
||||||
|
|
|
@ -410,7 +410,7 @@ class BadgeGranter
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.send_notification(user_id, username, locale, badge)
|
def self.send_notification(user_id, username, locale, badge)
|
||||||
I18n.with_locale(notification_locale(locale)) do
|
notification = I18n.with_locale(notification_locale(locale)) do
|
||||||
Notification.create!(
|
Notification.create!(
|
||||||
user_id: user_id,
|
user_id: user_id,
|
||||||
notification_type: Notification.types[:granted_badge],
|
notification_type: Notification.types[:granted_badge],
|
||||||
|
@ -423,6 +423,10 @@ class BadgeGranter
|
||||||
}.to_json
|
}.to_json
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
DiscourseEvent.trigger(:user_badge_granted, badge, user_id)
|
||||||
|
|
||||||
|
notification
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -74,6 +74,16 @@ end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
%i(
|
||||||
|
user_badge_granted
|
||||||
|
).each do |event|
|
||||||
|
# user_badge_revoked
|
||||||
|
DiscourseEvent.on(event) do |badge, user_id|
|
||||||
|
ub = UserBadge.find_by(badge: badge, user_id: user_id)
|
||||||
|
WebHook.enqueue_object_hooks(:user_badge, ub, event, UserBadgeSerializer)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
DiscourseEvent.on(:reviewable_created) do |reviewable|
|
DiscourseEvent.on(:reviewable_created) do |reviewable|
|
||||||
WebHook.enqueue_object_hooks(:reviewable, reviewable, :reviewable_created, reviewable.serializer)
|
WebHook.enqueue_object_hooks(:reviewable, reviewable, :reviewable_created, reviewable.serializer)
|
||||||
end
|
end
|
||||||
|
|
|
@ -3562,6 +3562,9 @@ en:
|
||||||
notification_event:
|
notification_event:
|
||||||
name: "Notification Event"
|
name: "Notification Event"
|
||||||
details: "When a user receives a notification in their feed."
|
details: "When a user receives a notification in their feed."
|
||||||
|
user_badge_event:
|
||||||
|
name: "Badge Grant Event"
|
||||||
|
details: "When a user receives a badge."
|
||||||
delivery_status:
|
delivery_status:
|
||||||
title: "Delivery Status"
|
title: "Delivery Status"
|
||||||
inactive: "Inactive"
|
inactive: "Inactive"
|
||||||
|
|
|
@ -59,3 +59,8 @@ WebHookEventType.seed do |b|
|
||||||
b.id = WebHookEventType::ASSIGN
|
b.id = WebHookEventType::ASSIGN
|
||||||
b.name = "assign"
|
b.name = "assign"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
WebHookEventType.seed do |b|
|
||||||
|
b.id = WebHookEventType::USER_BADGE
|
||||||
|
b.name = "user_badge"
|
||||||
|
end
|
||||||
|
|
|
@ -102,3 +102,11 @@ Fabricator(:notification_web_hook, from: :web_hook) do
|
||||||
web_hook.web_hook_event_types = [transients[:notification_hook]]
|
web_hook.web_hook_event_types = [transients[:notification_hook]]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Fabricator(:user_badge_web_hook, from: :web_hook) do
|
||||||
|
transient user_badge_hook: WebHookEventType.find_by(name: 'user_badge')
|
||||||
|
|
||||||
|
after_build do |web_hook, transients|
|
||||||
|
web_hook.web_hook_event_types = [transients[:user_badge_hook]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -486,5 +486,30 @@ describe WebHook do
|
||||||
payload = JSON.parse(job_args["payload"])
|
payload = JSON.parse(job_args["payload"])
|
||||||
expect(payload["id"]).to eq(reviewable.id)
|
expect(payload["id"]).to eq(reviewable.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'should enqueue the right hooks for badge grants' do
|
||||||
|
Fabricate(:user_badge_web_hook)
|
||||||
|
badge = Fabricate(:badge)
|
||||||
|
badge.multiple_grant = true
|
||||||
|
badge.show_posts = true
|
||||||
|
badge.save
|
||||||
|
|
||||||
|
now = Time.now
|
||||||
|
freeze_time now
|
||||||
|
|
||||||
|
BadgeGranter.grant(badge, user, granted_by: admin, post_id: post.id)
|
||||||
|
|
||||||
|
job_args = Jobs::EmitWebHookEvent.jobs.last["args"].first
|
||||||
|
expect(job_args["event_name"]).to eq("user_badge_granted")
|
||||||
|
payload = JSON.parse(job_args["payload"])
|
||||||
|
expect(payload["badge_id"]).to eq(badge.id)
|
||||||
|
expect(payload["user_id"]).to eq(user.id)
|
||||||
|
expect(payload["granted_by_id"]).to eq(admin.id)
|
||||||
|
# be_within required because rounding occurs
|
||||||
|
expect(Time.zone.parse(payload["granted_at"]).to_f).to be_within(0.001).of(now.to_f)
|
||||||
|
expect(payload["post_id"]).to eq(post.id)
|
||||||
|
|
||||||
|
# Future work: revoke badge hook
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue