# frozen_string_literal: true # GroupMessage sends a private message to a group. # It will also avoid sending the same message repeatedly, which can happen with # notifications to moderators when spam is detected. # # Options: # # user: (User) If the message is about a user, pass the user object. # limit_once_per: (seconds) Limit sending the given type of message once every X seconds. # The default is 24 hours. Set to false to always send the message. class GroupMessage include Rails.application.routes.url_helpers RECENT_MESSAGE_PERIOD = 3.months def self.create(group_name, message_type, opts = {}) GroupMessage.new(group_name, message_type, opts).create end def initialize(group_name, message_type, opts = {}) @group_name = group_name @message_type = message_type @opts = opts end def create return false if sent_recently? post = PostCreator.create( Discourse.system_user, target_group_names: [@group_name], archetype: Archetype.private_message, subtype: TopicSubtype.system_message, title: I18n.t("system_messages.#{@message_type}.subject_template", message_params), raw: I18n.t("system_messages.#{@message_type}.text_body_template", message_params), ) remember_message_sent post end def delete_previous!(respect_sent_recently: true, match_raw: true) return false if respect_sent_recently && sent_recently? posts = Post .joins(topic: { topic_allowed_groups: :group }) .where( topic: { posts_count: 1, user_id: Discourse.system_user, archetype: Archetype.private_message, subtype: TopicSubtype.system_message, title: I18n.t("system_messages.#{@message_type}.subject_template", message_params), topic_allowed_groups: { groups: { name: @group_name, }, }, }, ) .where("posts.created_at > ?", RECENT_MESSAGE_PERIOD.ago) if match_raw posts = posts.where( raw: I18n.t("system_messages.#{@message_type}.text_body_template", message_params).rstrip, ) end posts.find_each { |post| PostDestroyer.new(Discourse.system_user, post).destroy } end def message_params @message_params ||= begin h = { base_url: Discourse.base_url }.merge(@opts[:message_params] || {}) if @opts[:user] h.merge!( username: @opts[:user].username, user_url: user_path(@opts[:user].encoded_username(lower: true)), ) end h end end def sent_recently? return false if @opts[:limit_once_per] == false Discourse.redis.get(sent_recently_key).present? end # default is to send no more than once every 24 hours (24 * 60 * 60 = 86,400 seconds) def remember_message_sent unless @opts[:limit_once_per] == false Discourse.redis.setex(sent_recently_key, @opts[:limit_once_per].try(:to_i) || 86_400, 1) end end def sent_recently_key "grpmsg:#{@group_name}:#{@message_type}:#{@opts[:user] ? @opts[:user].username : ""}" end end