Chatwoot/app/services/round_robin/manage_service.rb
Sojan Jose 823c0ab6a7
chore: Use Round Robin service for team assignment (#4237)
Co-authored-by: Pranav Raj S <pranav@chatwoot.com>
2022-03-28 14:38:07 +05:30

82 lines
2.4 KiB
Ruby

# If allowed_member_ids are supplied round robin service will only fetch a member from member id
# This is used in case of team assignment
class RoundRobin::ManageService
pattr_initialize [:inbox!, { allowed_member_ids: [] }]
# called on inbox delete
def clear_queue
::Redis::Alfred.delete(round_robin_key)
end
# called on inbox member create
def add_agent_to_queue(user_id)
::Redis::Alfred.lpush(round_robin_key, user_id)
end
# called on inbox member delete
def remove_agent_from_queue(user_id)
::Redis::Alfred.lrem(round_robin_key, user_id)
end
def available_agent(priority_list: [])
reset_queue unless validate_queue?
user_id = get_member_via_priority_list(priority_list)
# incase priority list was empty or inbox members weren't present
user_id ||= fetch_user_id
inbox.inbox_members.find_by(user_id: user_id)&.user if user_id.present?
end
def reset_queue
clear_queue
add_agent_to_queue(inbox.inbox_members.map(&:user_id))
end
private
def fetch_user_id
if allowed_member_ids_in_str.present?
user_id = queue.intersection(allowed_member_ids_in_str).pop
pop_push_to_queue(user_id)
user_id
else
::Redis::Alfred.rpoplpush(round_robin_key, round_robin_key)
end
end
# priority list is usually the members who are online passed from assignmebt service
def get_member_via_priority_list(priority_list)
return if priority_list.blank?
# when allowed member ids is passed we will be looking to get members from that list alone
priority_list = priority_list.intersection(allowed_member_ids_in_str) if allowed_member_ids_in_str.present?
return if priority_list.blank?
user_id = queue.intersection(priority_list.map(&:to_s)).pop
pop_push_to_queue(user_id)
user_id
end
def pop_push_to_queue(user_id)
return if user_id.blank?
remove_agent_from_queue(user_id)
add_agent_to_queue(user_id)
end
def validate_queue?
return true if inbox.inbox_members.map(&:user_id).sort == queue.map(&:to_i).sort
end
def queue
::Redis::Alfred.lrange(round_robin_key)
end
def round_robin_key
format(::Redis::Alfred::ROUND_ROBIN_AGENTS, inbox_id: inbox.id)
end
def allowed_member_ids_in_str
# NOTE: the values which are returned from redis for priority list are string
@allowed_member_ids_in_str ||= allowed_member_ids.map(&:to_s)
end
end