Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RED-2110] Add Support to Omnichannel -> Agent Availabilities API #575

Merged
merged 3 commits into from
Jul 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## v3.0.6

Adding support to the agent availabilities API endpoints

Adding multiple Gemfile and Gemfile.lock files for differen Ruby versions so that Snyk can scan the repo for vulnerabilities.

## v3.0.5
Expand Down
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,37 @@ ticket.requester # => #<ZendeskAPI::User id=...>
Currently, this feature is limited to only a few resources and their associations.
They are documented on [developer.zendesk.com](https://developer.zendesk.com/rest_api/docs/support/side_loading#supported-endpoints).

#### Recommended Approach

For better control over your data and to avoid large response sizes, consider fetching related resources explicitly. This approach can help you manage data loading more precisely and can lead to optimized performance for complex applications.

```ruby
ticket = ZendeskAPI::Ticket.find(id: 1)
requester = ZendeskAPI::User.find(id: ticket.requester_id)
```

By explicitly fetching associated resources, you can ensure that your application only processes the data it needs, improving overall efficiency.

### Omnichannel

Support for the [Agent Availability API](https://developer.zendesk.com/api-reference/agent-availability/agent-availability-api/introduction/)

An agent’s availability includes their state (such as online) for each channel (such as messaging), and their unified state across channels. It also includes the work items assigned to them.

```ruby
# All agent availabilities
client.agent_availabilities.fetch

# fetch availability for one agent, their channels and work items
agent_availability = ZendeskAPI::AgentAvailability.find(client, 386390041152)
agent_availability.channels
agent_availability.channels.first.work_items

# Using the agent availability filter
ZendeskAPI::AgentAvailability.search(client, { select_channel: 'support' })
ZendeskAPI::AgentAvailability.search(client, { channel_status: 'support:online' })
```

### Search

Searching is done through the client. Returned is an instance of `ZendeskAPI::Collection`:
Expand Down
52 changes: 52 additions & 0 deletions lib/zendesk_api/resources.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,58 @@ class Locale < ReadResource; end

class CustomRole < DataResource; end

class WorkItem < Resource; end

class Channel < Resource
def work_items
@work_items ||= attributes.fetch('relationships', {}).fetch('work_items', {}).fetch('data', []).map do |work_item_attributes|
WorkItem.new(@client, work_item_attributes)
end
end
end

# client.agent_availabilities.fetch
# client.agent_availabilities.find 20401208368
# both return consistently - ZendeskAPI::AgentAvailability
class AgentAvailability < DataResource
def self.model_key
"data"
end

def initialize(client, attributes = {})
nested_attributes = attributes.delete('attributes')
super(client, attributes.merge(nested_attributes))
end

def self.find(client, id)
attributes = client.connection.get("#{resource_path}/#{id}").body.fetch(model_key, {})
new(client, attributes)
end

# Examples:
# ZendeskAPI::AgentAvailability.search(client, { channel_status: 'support:online' })
# ZendeskAPI::AgentAvailability.search(client, { agent_status_id: 1 })
# Just pass a hash that includes the key and value you want to search for, it gets turned into a query string
# on the format of filter[key]=value
# Returns a collection of AgentAvailability objects
def self.search(client, args_hash)
query_string = args_hash.map { |k, v| "filter[#{k}]=#{v}" }.join("&")
client.connection.get("#{resource_path}?#{query_string}").body.fetch(model_key, []).map do |attributes|
new(client, attributes)
end
end

def channels
@channels ||= begin
channel_attributes_array = @client.connection.get(attributes['links']['self']).body.fetch('included')
channel_attributes_array.map do |channel_attributes|
nested_attributes = channel_attributes.delete('attributes')
Channel.new(@client, channel_attributes.merge(nested_attributes))
end
end
end
end

class Role < DataResource
def to_param
name
Expand Down
23 changes: 23 additions & 0 deletions spec/live/cbp_support_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -222,4 +222,27 @@
end
end
end

describe ZendeskAPI::AgentAvailability do
describe '/agent_availabilities' do
let(:collection_fetched) do
VCR.use_cassette("cbp_#{described_class}_collection") do
client.agent_availabilities.fetch
client.agent_availabilities
end
end

let(:response_body) { collection_fetched.response.body }
let(:collection_fetched_results) { collection_fetched.to_a }
it 'returns a CBP response with all the correct keys' do
expect(response_body).to have_key('meta')
expect(response_body).to have_key('links')
expect(response_body['meta'].keys).to include('has_more')
end

it 'returns a list of AgentAvailability objects' do
expect(collection_fetched_results).to all(be_a(described_class))
end
end
end
end
Loading