discourse/plugins/chat/lib/duplicate_message_validator.rb

47 lines
1.5 KiB
Ruby

# frozen_string_literal: true
class Chat::DuplicateMessageValidator
attr_reader :chat_message
def initialize(chat_message)
@chat_message = chat_message
end
def validate
return if SiteSetting.chat_duplicate_message_sensitivity.zero?
matrix =
Chat::DuplicateMessageValidator.sensitivity_matrix(
SiteSetting.chat_duplicate_message_sensitivity,
)
# Check if the length of the message is too short to check for a duplicate message
return if chat_message.message.length < matrix[:min_message_length]
# Check if there are enough users in the channel to check for a duplicate message
return if (chat_message.chat_channel.user_count || 0) < matrix[:min_user_count]
# Check if the same duplicate message has been posted in the last N seconds by any user
if !chat_message
.chat_channel
.chat_messages
.where("created_at > ?", matrix[:min_past_seconds].seconds.ago)
.where(message: chat_message.message)
.exists?
return
end
chat_message.errors.add(:base, I18n.t("chat.errors.duplicate_message"))
end
def self.sensitivity_matrix(sensitivity)
{
# 0.1 sensitivity = 100 users and 1.0 sensitivity = 5 users.
min_user_count: (-1.0 * 105.5 * sensitivity + 110.55).to_i,
# 0.1 sensitivity = 30 chars and 1.0 sensitivity = 10 chars.
min_message_length: (-1.0 * 22.2 * sensitivity + 32.22).to_i,
# 0.1 sensitivity = 10 seconds and 1.0 sensitivity = 60 seconds.
min_past_seconds: (55.55 * sensitivity + 4.5).to_i,
}
end
end