From 08a01b23fe5ffab244969331fdf6dc5872e79022 Mon Sep 17 00:00:00 2001 From: David Battersby Date: Fri, 18 Apr 2025 15:50:57 +0400 Subject: [PATCH] FEATURE: add option to send individual report PM to group members (#369) This change adds an option to the Schedule a PM with Data Explorer results script, which when selected will send individual PMs to each group member selected in the Send to User, Group or Email field. When this field is not checked, the functionality for groups will work as it did before (ie. send a single PM to the group). --- config/locales/client.en.yml | 2 ++ lib/discourse_data_explorer/report_generator.rb | 15 ++++++++++++--- plugin.rb | 4 +++- spec/report_generator_spec.rb | 11 +++++++++++ 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index c445d90..2bd9787 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -118,6 +118,8 @@ en: label: Skip sending PM if there are no results attach_csv: label: Attach the CSV file to the PM + users_from_group: + label: Send individual PM to each group member recurring_data_explorer_result_topic: fields: topic_id: diff --git a/lib/discourse_data_explorer/report_generator.rb b/lib/discourse_data_explorer/report_generator.rb index b014d01..9fc9ac7 100644 --- a/lib/discourse_data_explorer/report_generator.rb +++ b/lib/discourse_data_explorer/report_generator.rb @@ -6,7 +6,12 @@ module ::DiscourseDataExplorer query = DiscourseDataExplorer::Query.find(query_id) return [] if !query || recipients.empty? - recipients = filter_recipients_by_query_access(recipients, query) + recipients = + filter_recipients_by_query_access( + recipients, + query, + users_from_group: opts[:users_from_group], + ) params = params_to_hash(query_params) result = DataExplorer.run_query(query, params) @@ -114,7 +119,7 @@ module ::DiscourseDataExplorer UploadCreator.new(tmp, tmp_filename, type: "csv_export").create_for(Discourse.system_user.id) end - def self.filter_recipients_by_query_access(recipients, query) + def self.filter_recipients_by_query_access(recipients, query, users_from_group: false) users = User.where(username: recipients) groups = Group.where(name: recipients) emails = recipients - users.pluck(:username) - groups.pluck(:name) @@ -126,7 +131,11 @@ module ::DiscourseDataExplorer groups.each do |group| if group.id == Group::AUTO_GROUPS[:admins] || query.query_groups.exists?(group_id: group.id) - result << [group.name, "group_name"] + if users_from_group + result.concat(group.users.pluck(:username).map { |username| [username, "username"] }) + else + result << [group.name, "group_name"] + end end end diff --git a/plugin.rb b/plugin.rb index df79050..8eb351c 100644 --- a/plugin.rb +++ b/plugin.rb @@ -82,6 +82,7 @@ after_initialize do field :query_id, component: :choices, required: true, extra: { content: queries } field :query_params, component: :"key-value", accepts_placeholders: true field :skip_empty, component: :boolean + field :users_from_group, component: :boolean field :attach_csv, component: :boolean, validator: ->(attach_csv) do @@ -103,6 +104,7 @@ after_initialize do query_id = fields.dig("query_id", "value") query_params = fields.dig("query_params", "value") || {} skip_empty = fields.dig("skip_empty", "value") || false + users_from_group = fields.dig("users_from_group", "value") || false attach_csv = fields.dig("attach_csv", "value") || false unless SiteSetting.data_explorer_enabled @@ -120,7 +122,7 @@ after_initialize do query_id, query_params, recipients, - { skip_empty:, attach_csv:, render_url_columns: true }, + { skip_empty:, users_from_group:, attach_csv:, render_url_columns: true }, ) .each do |pm| begin diff --git a/spec/report_generator_spec.rb b/spec/report_generator_spec.rb index 6c28bda..a1d5c94 100644 --- a/spec/report_generator_spec.rb +++ b/spec/report_generator_spec.rb @@ -175,6 +175,17 @@ describe DiscourseDataExplorer::ReportGenerator do expect(result[2]["target_emails"]).to eq(["john@doe.com"]) end + it "extracts users from group when option is selected" do + Fabricate(:query_group, query: query, group: group) + DiscourseDataExplorer::ResultToMarkdown.expects(:convert).returns("le table") + freeze_time + + result = + described_class.generate(query.id, query_params, [group.name], { users_from_group: true }) + expect(result.length).to eq(1) + expect(result[0]["target_usernames"]).to eq([user.username]) + end + it "works with attached csv file" do SiteSetting.personal_message_enabled_groups = group.id DiscourseDataExplorer::ResultToMarkdown.expects(:convert).returns("le table")