-
Notifications
You must be signed in to change notification settings - Fork 52
Add support for retrieving Zoom Phone call queues #468
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
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| using System.Collections.Generic; | ||
| using System.Text.Json.Serialization; | ||
|
|
||
| namespace ZoomNet.Models | ||
| { | ||
| /// <summary> | ||
| /// A Call Queue. | ||
| /// </summary> | ||
| public class CallQueue | ||
| { | ||
| /// <summary> | ||
| /// Gets or sets the extension id. | ||
| /// </summary> | ||
| [JsonPropertyName("extension_id")] | ||
| public string ExtensionId { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// Gets or sets the extension number. | ||
| /// </summary> | ||
| [JsonPropertyName("extension_number")] | ||
| public long? ExtensionNumber { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// Gets or sets the unique identifier of the call queue. | ||
| /// </summary> | ||
| [JsonPropertyName("id")] | ||
| public string Id { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// Gets or sets the name of the call queue. | ||
| /// </summary> | ||
| [JsonPropertyName("name")] | ||
| public string Name { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// Gets or sets the phone numbers assigned to the call queue. | ||
| /// </summary> | ||
| [JsonPropertyName("phone_numbers")] | ||
| public List<CallQueuePhoneNumber> PhoneNumbers { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// Gets or sets the site information. | ||
| /// </summary> | ||
| [JsonPropertyName("site")] | ||
| public CallQueueSite Site { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// Gets or sets the status of the call queue. | ||
| /// </summary> | ||
| [JsonPropertyName("status")] | ||
| public string Status { get; set; } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| using System.Text.Json.Serialization; | ||
|
|
||
| namespace ZoomNet.Models | ||
| { | ||
| /// <summary> | ||
| /// Represents a member of a call queue, which can be a user or a common area. | ||
| /// </summary> | ||
| public class CallQueueMember | ||
| { | ||
| /// <summary> | ||
| /// Gets or sets the member id. | ||
| /// </summary> | ||
| [JsonPropertyName("id")] | ||
| public string Id { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// Gets or sets the level of the member. | ||
| /// </summary> | ||
| [JsonPropertyName("level")] | ||
| public string Level { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// Gets or sets the name of the user or common area. | ||
| /// </summary> | ||
| [JsonPropertyName("name")] | ||
| public string Name { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// Gets or sets a value indicating whether the user can receive calls. It displays if the level is user. | ||
| /// </summary> | ||
| [JsonPropertyName("receive_call")] | ||
| public bool ReceiveCall { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// Gets or sets the extension ID of the user or common area. | ||
| /// </summary> | ||
| [JsonPropertyName("extension_id")] | ||
| public string ExtensionId { get; set; } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.Linq; | ||
| using System.Text; | ||
| using System.Text.Json.Serialization; | ||
| using System.Threading.Tasks; | ||
|
|
||
| namespace ZoomNet.Models | ||
| { | ||
| /// <summary> | ||
| /// Represents a phone number assigned to a call queue. | ||
| /// </summary> | ||
| public class CallQueuePhoneNumber | ||
| { | ||
| /// <summary> | ||
| /// Gets or sets the unique identifier of the phone number. | ||
| /// </summary> | ||
| [JsonPropertyName("id")] | ||
| public string Id { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// Gets or sets the phone number. | ||
| /// </summary> | ||
| [JsonPropertyName("number")] | ||
| public string Number { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// gets or sets the source of the phone number. | ||
| /// </summary> | ||
| [JsonPropertyName("source")] | ||
| public string Source { get; set; } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.Linq; | ||
| using System.Text; | ||
| using System.Text.Json.Serialization; | ||
| using System.Threading.Tasks; | ||
|
|
||
| namespace ZoomNet.Models | ||
| { | ||
| /// <summary> | ||
| /// Represents a site where a Call Queue is assigned. | ||
| /// </summary> | ||
| public class CallQueueSite | ||
| { | ||
| /// <summary> | ||
| /// Gets or sets the Unique identifier of the site where the Call Queue is assigned. | ||
| /// </summary> | ||
| [JsonPropertyName("id")] | ||
| public string Id { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// Gets or sets the name of the site. | ||
| /// </summary> | ||
| [JsonPropertyName("name")] | ||
| public string Name { get; set; } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| using Pathoschild.Http.Client; | ||
| using System.Threading; | ||
| using System.Threading.Tasks; | ||
| using ZoomNet.Models; | ||
| using ZoomNet.Utilities; | ||
|
|
||
| namespace ZoomNet.Resources | ||
| { | ||
| /// <inheritdoc/> | ||
| public class CallQueues : ICallQueues | ||
| { | ||
| private readonly IClient _client; | ||
|
|
||
| /// <summary> | ||
| /// Initializes a new instance of the <see cref="CallQueues" /> class. | ||
| /// </summary> | ||
| /// <param name="client">The HTTP client.</param> | ||
| internal CallQueues(IClient client) | ||
| { | ||
| _client = client; | ||
| } | ||
|
|
||
| /// <inheritdoc/> | ||
| public Task<CallQueue> GetAsync(string callQueueId, CancellationToken cancellationToken = default) | ||
| { | ||
| return _client | ||
| .GetAsync($"phone/call_queues/{callQueueId}") | ||
| .WithCancellationToken(cancellationToken) | ||
| .AsObject<CallQueue>(); | ||
| } | ||
|
|
||
| /// <inheritdoc/> | ||
| public Task<PaginatedResponseWithToken<CallQueue>> GetAllAsync(string department = null, string cost_center = null, string site_id = null, int recordsPerPage = 30, string pagingToken = null, CancellationToken cancellationToken = default) | ||
| { | ||
| Utils.ValidateRecordPerPage(recordsPerPage, max: 100); | ||
|
|
||
| return _client | ||
| .GetAsync($"phone/call_queues") | ||
| .WithArgument("department", department) | ||
| .WithArgument("cost_center", cost_center) | ||
| .WithArgument("site_id", site_id) | ||
| .WithArgument("page_size", recordsPerPage) | ||
| .WithArgument("next_page_token", pagingToken) | ||
| .WithCancellationToken(cancellationToken) | ||
| .AsPaginatedResponseWithToken<CallQueue>("call_queues"); | ||
| } | ||
|
|
||
| /// <inheritdoc/> | ||
| public Task<PaginatedResponseWithToken<CallQueueMember>> GetMembersAsync(string callQueueId, int recordsPerPage = 30, string pagingToken = null, CancellationToken cancellationToken = default) | ||
| { | ||
| Utils.ValidateRecordPerPage(recordsPerPage); | ||
| return _client | ||
| .GetAsync($"phone/call_queues/{callQueueId}/members") | ||
| .WithArgument("page_size", recordsPerPage) | ||
| .WithArgument("next_page_token", pagingToken) | ||
| .WithCancellationToken(cancellationToken) | ||
| .AsPaginatedResponseWithToken<CallQueueMember>("call_queue_members"); | ||
| } | ||
| } | ||
| } | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Genuine question: is it preferable to create a new resource for call queues or would it be better to simply add these three methods under the existing Phone resource? Meaning something along the lines of If we create a new resource for every grouping of methods, we'll end up with a super large number of resources. and how would we decide which methods deserve their own resource and which should be under the Phone resource? My gut feeling tells me to keep all the phone related methods under the Phone resource but my mind is not made up, I'm open to a debate.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So, I thought about this a bit. You're right. These API endpoints are part of the Zoom Phone APIs, so I guess it would make more logical sense to move these into the Phone resource. I'll amend my code to follow that standard for now. I think it would be good to discuss further however, I think it would be beneficial for maintainability, and ease of use for those new to ZoomNet to follow the existing structure of way the Zoom API is built out as seen here:
https://developers.zoom.us/docs/api/#workplace
Your top-level resources following that would be: For instance, For the phone resource the official API has these "categories" within the phone api: My thought is that you could then have I think adherence to that would make use of the library much easier to follow for anyone looking at the Zoom API documentation.
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Perfect, thanks. I'll wait for you to implement this change before merging.
This is an even better suggestion: group methods into "sub-resources" to match the Zoom API documentation. It would be a major breaking change, which would cause some pain to developers to transition but it would absolutely make thinks more discoverable. I will raise a separate issue to track this new feature. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| using System.Threading; | ||
| using System.Threading.Tasks; | ||
| using ZoomNet.Models; | ||
|
|
||
| namespace ZoomNet.Resources | ||
| { | ||
| /// <summary> | ||
| /// Allows you to manage call queues. | ||
| /// </summary> | ||
| public interface ICallQueues | ||
| { | ||
| /// <summary> | ||
| /// Get call queue details. | ||
| /// </summary> | ||
| /// <param name="callQueueId">The ID of the call queue.</param> | ||
| /// <param name="cancellationToken">The cancellation token.</param> | ||
| /// <returns> | ||
| /// Details about a <see cref="CallQueue"/>. | ||
| /// </returns> | ||
| public Task<CallQueue> GetAsync(string callQueueId, CancellationToken cancellationToken = default); | ||
|
|
||
| /// <summary> | ||
| /// Get call queues. | ||
| /// </summary> | ||
| /// <param name="department">Filter by department.</param> | ||
| /// <param name="cost_center">Filter by cost center.</param> | ||
| /// <param name="site_id">Filter by site id.</param> | ||
| /// <param name="recordsPerPage">The number of records to return.</param> | ||
| /// <param name="pagingToken">The paging token.</param> | ||
| /// <param name="cancellationToken">The cancellation token.</param> | ||
| /// <returns> | ||
| /// A paginated response of <see cref="CallQueue"/>. | ||
| /// </returns> | ||
| public Task<PaginatedResponseWithToken<CallQueue>> GetAllAsync(string department = null, string cost_center = null, string site_id = null, int recordsPerPage = 30, string pagingToken = null, CancellationToken cancellationToken = default); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same comment as above. Please avoid underscores.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah my apologies! I thought I had caught these as I was going through afterwards. I'll get these corrected! |
||
|
|
||
| /// <summary> | ||
| /// Get members currently in call queues. | ||
| /// </summary> | ||
| /// <param name="callQueueId">The ID of the call queue.</param> | ||
| /// <param name="recordsPerPage">The number of records to return.</param> | ||
| /// <param name="pagingToken">The paging token.</param> | ||
| /// <param name="cancellationToken">The cancellation token.</param> | ||
| /// <returns>An array of current call queue membership entries.</returns> | ||
| public Task<PaginatedResponseWithToken<CallQueueMember>> GetMembersAsync(string callQueueId, int recordsPerPage = 30, string pagingToken = null, CancellationToken cancellationToken = default); | ||
| } | ||
| } | ||


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please avoid underscore and other "special" characters when naming parameters, Can you rename to
costCenter,siteId, etc.In the mean time, I'll investigate if there's a way to configure StyleCop to let you know that such characters violate our naming convention.