Class: GroupMessage

Inherits:
Object
  • Object
show all
Defined in:
app/services/group_message.rb

Overview

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.

Constant Summary collapse

RECENT_MESSAGE_PERIOD =
3.months

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(group_name, message_type, opts = {}) ⇒ GroupMessage

Returns a new instance of GroupMessage.



22
23
24
25
26
# File 'app/services/group_message.rb', line 22

def initialize(group_name, message_type, opts = {})
  @group_name = group_name
  @message_type = message_type
  @opts = opts
end

Class Method Details

.create(group_name, message_type, opts = {}) ⇒ Object



18
19
20
# File 'app/services/group_message.rb', line 18

def self.create(group_name, message_type, opts = {})
  GroupMessage.new(group_name, message_type, opts).create
end

Instance Method Details

#createObject



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'app/services/group_message.rb', line 28

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

#delete_previous!(respect_sent_recently: true, match_raw: true) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'app/services/group_message.rb', line 44

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

#message_paramsObject



76
77
78
79
80
81
82
83
84
85
# File 'app/services/group_message.rb', line 76

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].username))
      end
      h
    end
end

#remember_message_sentObject

default is to send no more than once every 24 hours (24 * 60 * 60 = 86,400 seconds)



93
94
95
96
97
# File 'app/services/group_message.rb', line 93

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

#sent_recently?Boolean

Returns:

  • (Boolean)


87
88
89
90
# File 'app/services/group_message.rb', line 87

def sent_recently?
  return false if @opts[:limit_once_per] == false
  Discourse.redis.get(sent_recently_key).present?
end

#sent_recently_keyObject



99
100
101
# File 'app/services/group_message.rb', line 99

def sent_recently_key
  "grpmsg:#{@group_name}:#{@message_type}:#{@opts[:user] ? @opts[:user].username : ""}"
end