From ea0a6dfbcbaa642d65f6e304135f79f2108fdffc Mon Sep 17 00:00:00 2001 From: Marius Balteanu Date: Sat, 6 Dec 2025 13:58:51 +0000 Subject: [PATCH] Adds webooks for news (#29664). git-svn-id: https://svn.redmine.org/redmine/trunk@24203 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- app/models/news.rb | 4 ++++ app/models/webhook_payload.rb | 20 ++++++++++++++++++++ config/locales/en.yml | 4 ++++ test/unit/webhook_payload_test.rb | 31 +++++++++++++++++++++++++++++++ 4 files changed, 59 insertions(+) diff --git a/app/models/news.rb b/app/models/news.rb index 12c70d5a8..8834e473e 100644 --- a/app/models/news.rb +++ b/app/models/news.rb @@ -41,6 +41,10 @@ class News < ApplicationRecord after_create :add_author_as_watcher after_create_commit :send_notification + after_create_commit ->{ Webhook.trigger('news.created', self) } + after_update_commit ->{ Webhook.trigger('news.updated', self) } + after_destroy_commit ->{ Webhook.trigger('news.deleted', self) } + scope :visible, (lambda do |*args| joins(:project). where(Project.allowed_to_condition(args.shift || User.current, :view_news, *args)) diff --git a/app/models/webhook_payload.rb b/app/models/webhook_payload.rb index e54a17bb6..eeab9a921 100644 --- a/app/models/webhook_payload.rb +++ b/app/models/webhook_payload.rb @@ -31,6 +31,7 @@ class WebhookPayload issue: %w[created updated deleted], wiki_page: %w[created updated deleted], time_entry: %w[created updated deleted], + news: %w[created updated deleted], } def to_h @@ -130,6 +131,25 @@ class WebhookPayload } end + def news_payload(action) + news = object + ts = case action + when 'created' + news.created_on + when 'deleted' + Time.now + else + news.updated_on + end + { + type: event, + timestamp: ts.iso8601, + data: { + news: ApiRenderer.new("app/views/news/show.api.rsb", user).to_h(news: news) + } + } + end + # given a path to an API template (relative to RAILS_ROOT), renders it and returns the resulting hash class ApiRenderer include ApplicationHelper diff --git a/config/locales/en.yml b/config/locales/en.yml index de42a2a2d..fd1a1c8b1 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1197,6 +1197,10 @@ en: webhook_events_time_entry_created: Time entry created webhook_events_time_entry_updated: Time entry updated webhook_events_time_entry_deleted: Time entry deleted + webhook_events_news: News + webhook_events_news_created: News created + webhook_events_news_updated: News updated + webhook_events_news_deleted: News deleted webhook_url_info: Redmine will send a POST request to this URL whenever one of the selected events occurs in one of the selected projects. webhook_secret_info_html: If provided, Redmine will use this to create a hash signature that is sent with each delivery as the value of the X-Redmine-Signature-256 header. diff --git a/test/unit/webhook_payload_test.rb b/test/unit/webhook_payload_test.rb index 329d485a0..317cec055 100644 --- a/test/unit/webhook_payload_test.rb +++ b/test/unit/webhook_payload_test.rb @@ -125,4 +125,35 @@ class WebhookPayloadTest < ActiveSupport::TestCase assert_equal 'time_entry.deleted', h[:type] assert_equal 4.25, h.dig(:data, :time_entry, :hours) end + + test "news created payload should contain news details" do + news = News.generate! + + p = WebhookPayload.new('news.created', news, @dlopper) + assert h = p.to_h + assert_equal 'news.created', h[:type] + assert_equal news.title, h.dig(:data, :news, :title) + end + + test "news updated payload should contain updated timestamp" do + news = News.first + + news.title = 'Updated title' + news.save! + + p = WebhookPayload.new('news.updated', news, @dlopper) + h = p.to_h + assert_equal 'news.updated', h[:type] + assert_equal 'Updated title', h.dig(:data, :news, :title) + end + + test "news deleted payload should contain basic info" do + news = News.first + news.destroy + + p = WebhookPayload.new('news.deleted', news, @dlopper) + h = p.to_h + assert_equal 'news.deleted', h[:type] + assert_equal 'Updated title', h.dig(:data, :news, :title) + end end