2022-11-16 05:10:42 -05:00
|
|
|
# NOTE: When changing auto-join logic, make sure to update the `settings.auto_join_users_info` translation as well.
|
2022-11-02 09:41:30 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
module Jobs
|
|
|
|
class AutoManageChannelMemberships < ::Jobs::Base
|
|
|
|
def execute(args)
|
|
|
|
channel =
|
|
|
|
ChatChannel.includes(:chatable).find_by(
|
|
|
|
id: args[:chat_channel_id],
|
|
|
|
auto_join_users: true,
|
|
|
|
chatable_type: "Category",
|
|
|
|
)
|
|
|
|
|
|
|
|
return if !channel&.chatable
|
|
|
|
|
|
|
|
processed =
|
|
|
|
UserChatChannelMembership.where(
|
|
|
|
chat_channel: channel,
|
|
|
|
following: true,
|
|
|
|
join_mode: UserChatChannelMembership.join_modes[:automatic],
|
|
|
|
).count
|
|
|
|
|
|
|
|
auto_join_query(channel).find_in_batches do |batch|
|
|
|
|
break if processed >= SiteSetting.max_chat_auto_joined_users
|
|
|
|
|
|
|
|
starts_at = batch.first.query_user_id
|
|
|
|
ends_at = batch.last.query_user_id
|
|
|
|
|
|
|
|
Jobs.enqueue(
|
|
|
|
:auto_join_channel_batch,
|
|
|
|
chat_channel_id: channel.id,
|
|
|
|
starts_at: starts_at,
|
|
|
|
ends_at: ends_at,
|
|
|
|
)
|
|
|
|
|
|
|
|
processed += batch.size
|
|
|
|
end
|
|
|
|
|
|
|
|
# The Jobs::AutoJoinChannelBatch job will only do this recalculation
|
|
|
|
# if it's operating on one user, so we need to make sure we do it for
|
|
|
|
# the channel here once this job is complete.
|
|
|
|
Chat::ChatChannelMembershipManager.new(channel).recalculate_user_count
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def auto_join_query(channel)
|
|
|
|
category = channel.chatable
|
|
|
|
|
|
|
|
users =
|
|
|
|
User
|
|
|
|
.real
|
|
|
|
.activated
|
|
|
|
.not_suspended
|
|
|
|
.not_staged
|
|
|
|
.distinct
|
|
|
|
.select(:id, "users.id AS query_user_id")
|
|
|
|
.where("last_seen_at > ?", 3.months.ago)
|
|
|
|
.joins(:user_option)
|
|
|
|
.where(user_options: { chat_enabled: true })
|
|
|
|
.joins(<<~SQL)
|
|
|
|
LEFT OUTER JOIN user_chat_channel_memberships uccm
|
|
|
|
ON uccm.chat_channel_id = #{channel.id} AND
|
|
|
|
uccm.user_id = users.id
|
|
|
|
SQL
|
|
|
|
.where("uccm.id IS NULL")
|
|
|
|
|
|
|
|
if category.read_restricted?
|
|
|
|
users =
|
|
|
|
users
|
|
|
|
.joins(:group_users)
|
|
|
|
.joins("INNER JOIN category_groups cg ON cg.group_id = group_users.group_id")
|
|
|
|
.where("cg.category_id = ?", channel.chatable_id)
|
|
|
|
end
|
|
|
|
|
|
|
|
users
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|