82 lines
2.8 KiB
Ruby
82 lines
2.8 KiB
Ruby
# NOTE: When changing auto-join logic, make sure to update the `settings.auto_join_users_info` translation as well.
|
|
# frozen_string_literal: true
|
|
|
|
module Jobs
|
|
class AutoJoinChannelBatch < ::Jobs::Base
|
|
def execute(args)
|
|
return "starts_at or ends_at missing" if args[:starts_at].blank? || args[:ends_at].blank?
|
|
start_user_id = args[:starts_at].to_i
|
|
end_user_id = args[:ends_at].to_i
|
|
|
|
return "End is higher than start" if end_user_id < start_user_id
|
|
|
|
channel =
|
|
ChatChannel.find_by(
|
|
id: args[:chat_channel_id],
|
|
auto_join_users: true,
|
|
chatable_type: "Category",
|
|
)
|
|
|
|
return if !channel
|
|
|
|
category = channel.chatable
|
|
return if !category
|
|
|
|
query_args = {
|
|
chat_channel_id: channel.id,
|
|
start: start_user_id,
|
|
end: end_user_id,
|
|
suspended_until: Time.zone.now,
|
|
last_seen_at: 3.months.ago,
|
|
channel_category: channel.chatable_id,
|
|
mode: Chat::UserChatChannelMembership.join_modes[:automatic],
|
|
}
|
|
|
|
new_member_ids = DB.query_single(create_memberships_query(category), query_args)
|
|
|
|
# Only do this if we are running auto-join for a single user, if we
|
|
# are doing it for many then we should do it after all batches are
|
|
# complete for the channel in Jobs::AutoJoinChannelMemberships
|
|
if start_user_id == end_user_id
|
|
Chat::ChatChannelMembershipManager.new(channel).recalculate_user_count
|
|
end
|
|
|
|
Chat::Publisher.publish_new_channel(channel.reload, User.where(id: new_member_ids))
|
|
end
|
|
|
|
private
|
|
|
|
def create_memberships_query(category)
|
|
query = <<~SQL
|
|
INSERT INTO user_chat_channel_memberships (user_id, chat_channel_id, following, created_at, updated_at, join_mode)
|
|
SELECT DISTINCT(users.id), :chat_channel_id, TRUE, NOW(), NOW(), :mode
|
|
FROM users
|
|
INNER JOIN user_options uo ON uo.user_id = users.id
|
|
LEFT OUTER JOIN user_chat_channel_memberships uccm ON
|
|
uccm.chat_channel_id = :chat_channel_id AND uccm.user_id = users.id
|
|
SQL
|
|
|
|
query += <<~SQL if category.read_restricted?
|
|
INNER JOIN group_users gu ON gu.user_id = users.id
|
|
LEFT OUTER JOIN category_groups cg ON cg.group_id = gu.group_id
|
|
SQL
|
|
|
|
query += <<~SQL
|
|
WHERE (users.id >= :start AND users.id <= :end) AND
|
|
users.staged IS FALSE AND users.active AND
|
|
NOT EXISTS(SELECT 1 FROM anonymous_users a WHERE a.user_id = users.id) AND
|
|
(suspended_till IS NULL OR suspended_till <= :suspended_until) AND
|
|
(last_seen_at > :last_seen_at) AND
|
|
uo.chat_enabled AND
|
|
uccm.id IS NULL
|
|
SQL
|
|
|
|
query += <<~SQL if category.read_restricted?
|
|
AND cg.category_id = :channel_category
|
|
SQL
|
|
|
|
query += "RETURNING user_chat_channel_memberships.user_id"
|
|
end
|
|
end
|
|
end
|