discourse/plugins/chat/app/jobs/regular/auto_manage_channel_members...

79 lines
2.1 KiB
Ruby

# 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