diff --git a/Source/ZoomNet/IZoomClient.cs b/Source/ZoomNet/IZoomClient.cs index 4bba5eb2..bb0f6fde 100644 --- a/Source/ZoomNet/IZoomClient.cs +++ b/Source/ZoomNet/IZoomClient.cs @@ -57,6 +57,11 @@ public interface IZoomClient [Obsolete("The Data Compliance API is deprecated")] IDataCompliance DataCompliance { get; } + /// + /// Gets the resource which allows you to handle Zoom phone external contacts. + /// + IExternalContacts ExternalContacts { get; } + /// /// Gets the resource that allows you to manage groups. /// diff --git a/Source/ZoomNet/Json/ZoomNetJsonSerializerContext.cs b/Source/ZoomNet/Json/ZoomNetJsonSerializerContext.cs index 4d32b395..c6e8fd2e 100644 --- a/Source/ZoomNet/Json/ZoomNetJsonSerializerContext.cs +++ b/Source/ZoomNet/Json/ZoomNetJsonSerializerContext.cs @@ -34,7 +34,6 @@ namespace ZoomNet.Json [JsonSerializable(typeof(ZoomNet.Models.CallHandlingSettings.CustomHoursChildSubsettings), TypeInfoPropertyName = "CallHandlingSettingsCustomHoursChildSubsettings")] [JsonSerializable(typeof(ZoomNet.Models.CallHandlingSettings.CustomHoursSubsettings), TypeInfoPropertyName = "CallHandlingSettingsCustomHoursSubsettings")] [JsonSerializable(typeof(ZoomNet.Models.CallHandlingSettings.CustomHoursType), TypeInfoPropertyName = "CallHandlingSettingsCustomHoursType")] - [JsonSerializable(typeof(ZoomNet.Models.CallHandlingSettings.ExternalContact), TypeInfoPropertyName = "CallHandlingSettingsExternalContact")] [JsonSerializable(typeof(ZoomNet.Models.CallHandlingSettings.HolidaySubsettings), TypeInfoPropertyName = "CallHandlingSettingsHolidaySubsettings")] [JsonSerializable(typeof(ZoomNet.Models.CallHandlingSettings.RingModeType), TypeInfoPropertyName = "CallHandlingSettingsRingModeType")] [JsonSerializable(typeof(ZoomNet.Models.CallingPlan))] @@ -113,6 +112,8 @@ namespace ZoomNet.Json [JsonSerializable(typeof(ZoomNet.Models.EmailNotificationUserSettings))] [JsonSerializable(typeof(ZoomNet.Models.EmergencyAddress))] [JsonSerializable(typeof(ZoomNet.Models.EncryptionType))] + [JsonSerializable(typeof(ZoomNet.Models.ExternalContact))] + [JsonSerializable(typeof(ZoomNet.Models.ExternalContactDetails))] [JsonSerializable(typeof(ZoomNet.Models.FeatureUserSettings))] [JsonSerializable(typeof(ZoomNet.Models.ImMetric))] [JsonSerializable(typeof(ZoomNet.Models.InstantMeeting))] @@ -353,7 +354,6 @@ namespace ZoomNet.Json [JsonSerializable(typeof(ZoomNet.Models.CallHandlingSettings.CustomHoursChildSubsettings[]), TypeInfoPropertyName = "CallHandlingSettingsCustomHoursChildSubsettingsArray")] [JsonSerializable(typeof(ZoomNet.Models.CallHandlingSettings.CustomHoursSubsettings[]), TypeInfoPropertyName = "CallHandlingSettingsCustomHoursSubsettingsArray")] [JsonSerializable(typeof(ZoomNet.Models.CallHandlingSettings.CustomHoursType[]), TypeInfoPropertyName = "CallHandlingSettingsCustomHoursTypeArray")] - [JsonSerializable(typeof(ZoomNet.Models.CallHandlingSettings.ExternalContact[]), TypeInfoPropertyName = "CallHandlingSettingsExternalContactArray")] [JsonSerializable(typeof(ZoomNet.Models.CallHandlingSettings.HolidaySubsettings[]), TypeInfoPropertyName = "CallHandlingSettingsHolidaySubsettingsArray")] [JsonSerializable(typeof(ZoomNet.Models.CallHandlingSettings.RingModeType[]), TypeInfoPropertyName = "CallHandlingSettingsRingModeTypeArray")] [JsonSerializable(typeof(ZoomNet.Models.CallingPlan[]))] @@ -432,6 +432,8 @@ namespace ZoomNet.Json [JsonSerializable(typeof(ZoomNet.Models.EmailNotificationUserSettings[]))] [JsonSerializable(typeof(ZoomNet.Models.EmergencyAddress[]))] [JsonSerializable(typeof(ZoomNet.Models.EncryptionType[]))] + [JsonSerializable(typeof(ZoomNet.Models.ExternalContact[]))] + [JsonSerializable(typeof(ZoomNet.Models.ExternalContactDetails[]))] [JsonSerializable(typeof(ZoomNet.Models.FeatureUserSettings[]))] [JsonSerializable(typeof(ZoomNet.Models.ImMetric[]))] [JsonSerializable(typeof(ZoomNet.Models.InstantMeeting[]))] diff --git a/Source/ZoomNet/Models/CallHandlingSettings/ExternalContact.cs b/Source/ZoomNet/Models/CallHandlingSettings/ExternalContact.cs deleted file mode 100644 index 8ea29e15..00000000 --- a/Source/ZoomNet/Models/CallHandlingSettings/ExternalContact.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Text.Json.Serialization; - -namespace ZoomNet.Models.CallHandlingSettings -{ - /// - /// External contact object. It's only required for . - /// - public class ExternalContact - { - /// - /// Gets or sets the external contact's ID. - /// - [JsonPropertyName("external_contact_id")] - public string ExternalContactId { get; set; } - } -} diff --git a/Source/ZoomNet/Models/ExternalContact.cs b/Source/ZoomNet/Models/ExternalContact.cs new file mode 100644 index 00000000..6d72538f --- /dev/null +++ b/Source/ZoomNet/Models/ExternalContact.cs @@ -0,0 +1,23 @@ +using System.Text.Json.Serialization; + +namespace ZoomNet.Models +{ + /// + /// Zoom phone external contact model. + /// + public class ExternalContact + { + /// + /// Gets or sets the Zoom-generated external contact Id. + /// Don't set it on external contact creation, it will be generated automatically. + /// + [JsonPropertyName("external_contact_id")] + public string ExternalContactId { get; set; } + + /// + /// Gets or sets the external contact's username or extension display name. + /// + [JsonPropertyName("name")] + public string Name { get; set; } + } +} diff --git a/Source/ZoomNet/Models/ExternalContactDetails.cs b/Source/ZoomNet/Models/ExternalContactDetails.cs new file mode 100644 index 00000000..9163742d --- /dev/null +++ b/Source/ZoomNet/Models/ExternalContactDetails.cs @@ -0,0 +1,54 @@ +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace ZoomNet.Models +{ + /// + /// Zoom phone external contact details model. + /// + public class ExternalContactDetails : ExternalContact + { + /// + /// Gets or sets the external contact's description. + /// + [JsonPropertyName("description")] + public string Description { get; set; } + + /// + /// Gets or sets the external contact's email address. + /// + [JsonPropertyName("email")] + public string Email { get; set; } + + /// + /// Gets or sets the external contact's extension number. + /// + [JsonPropertyName("extension_number")] + public string ExtensionNumber { get; set; } + + /// + /// Gets or sets the customer-configured external contact ID. + /// If it is not set id will be generated automatically. + /// + [JsonPropertyName("id")] + public string Id { get; set; } + + /// + /// Gets or sets the external contact's phone numbers. + /// + [JsonPropertyName("phone_numbers")] + public List PhoneNumbers { get; set; } + + /// + /// Gets or sets the external contact's SIP group, to define the call routing path. This is for customers that use SIP trunking. + /// + [JsonPropertyName("routing_path")] + public string RoutingPath { get; set; } + + /// + /// Gets or sets a value indicating whether to allow the automatic call recording. + /// + [JsonPropertyName("auto_call_recorded")] + public bool AutoCallRecorded { get; set; } + } +} diff --git a/Source/ZoomNet/Resources/ExternalContacts.cs b/Source/ZoomNet/Resources/ExternalContacts.cs new file mode 100644 index 00000000..981949dd --- /dev/null +++ b/Source/ZoomNet/Resources/ExternalContacts.cs @@ -0,0 +1,94 @@ +using Pathoschild.Http.Client; +using System; +using System.Threading; +using System.Threading.Tasks; +using ZoomNet; +using ZoomNet.Models; + +namespace ZoomNet.Resources +{ + /// + public class ExternalContacts : IExternalContacts + { + private readonly IClient _client; + + /// + /// Initializes a new instance of the class. + /// + /// The HTTP client. + internal ExternalContacts(IClient client) + { + _client = client; + } + + /// + public Task> GetAllAsync(int pageSize = 30, string nextPageToken = null, CancellationToken cancellationToken = default) + { + if (pageSize < 1 || pageSize > 300) + { + throw new ArgumentOutOfRangeException(nameof(pageSize), "Page size must be between 1 and 300"); + } + + return _client + .GetAsync("phone/external_contacts") + .WithArgument("page_size", pageSize) + .WithArgument("next_page_token", nextPageToken) + .WithCancellationToken(cancellationToken) + .AsPaginatedResponseWithToken("external_contacts"); + } + + /// + public Task GetDetailsAsync(string externalContactId, CancellationToken cancellationToken = default) + { + if (string.IsNullOrEmpty(externalContactId)) + { + throw new ArgumentException(nameof(externalContactId), "External contact id is not set."); + } + + return _client + .GetAsync($"phone/external_contacts/{externalContactId}") + .WithCancellationToken(cancellationToken) + .AsObject(); + } + + /// + public Task AddAsync(ExternalContactDetails externalContact, CancellationToken cancellationToken = default) + { + return _client + .PostAsync("phone/external_contacts") + .WithJsonBody(externalContact) + .WithCancellationToken(cancellationToken) + .AsObject(); + } + + /// + public Task DeleteAsync(string externalContactId, CancellationToken cancellationToken = default) + { + if (string.IsNullOrEmpty(externalContactId)) + { + throw new ArgumentException(nameof(externalContactId), "External contact id is not set."); + } + + return _client + .DeleteAsync($"phone/external_contacts/{externalContactId}") + .WithCancellationToken(cancellationToken) + .AsMessage(); + } + + /// + public Task UpdateAsync( + ExternalContactDetails externalContact, CancellationToken cancellationToken = default) + { + if (string.IsNullOrEmpty(externalContact.ExternalContactId)) + { + throw new ArgumentException(nameof(externalContact.ExternalContactId), "External contact id is not set."); + } + + return _client + .PatchAsync($"phone/external_contacts/{externalContact.ExternalContactId}") + .WithJsonBody(externalContact) + .WithCancellationToken(cancellationToken) + .AsMessage(); + } + } +} diff --git a/Source/ZoomNet/Resources/IExternalContacts.cs b/Source/ZoomNet/Resources/IExternalContacts.cs new file mode 100644 index 00000000..7925a111 --- /dev/null +++ b/Source/ZoomNet/Resources/IExternalContacts.cs @@ -0,0 +1,69 @@ +using System.Threading; +using System.Threading.Tasks; +using ZoomNet.Models; + +namespace ZoomNet.Resources +{ + /// + /// Allows you to access Zoom Phone API endpoints responsible for setting and retrieving data of external contacts. + /// + /// + /// See + /// Zoom API documentation for more information. + /// + public interface IExternalContacts + { + /// + /// Retrieves a list of all of an account's external contacts. + /// + /// The number of records returned from a single API call. Default is 30. + /// + /// The next page token paginates through a large set of results. + /// A next page token is returned whenever the set of available results exceeds the current page size. + /// + /// A cancellation token that can be used to cancel the asynchronous operation. + /// + /// A task representing the asynchronous operation. The task result contains an array of external contacts in type of . + /// + Task> GetAllAsync( + int pageSize = 30, + string nextPageToken = null, + CancellationToken cancellationToken = default); + + /// + /// Gets an external contact's information. + /// + /// The external contact id. + /// A cancellation token that can be used to cancel the asynchronous operation. + /// A task representing the asynchronous operation. The task result contains external contact details. + Task GetDetailsAsync( + string externalContactId, CancellationToken cancellationToken = default); + + /// + /// Adds an external contact. + /// + /// The external contact information. + /// A cancellation token that can be used to cancel the asynchronous operation. + /// A task representing the asynchronous operation. The task result contains external contact details. + Task AddAsync( + ExternalContactDetails externalContact, CancellationToken cancellationToken = default); + + /// + /// Removes an external contact. + /// + /// The external contact id. + /// A cancellation token that can be used to cancel the asynchronous operation. + /// A task representing the asynchronous operation. + Task DeleteAsync( + string externalContactId, CancellationToken cancellationToken = default); + + /// + /// Update an external contact information by . + /// + /// External contact information. + /// A cancellation token that can be used to cancel the asynchronous operation. + /// A task representing the asynchronous operation. + Task UpdateAsync( + ExternalContactDetails externalContact, CancellationToken cancellationToken = default); + } +} diff --git a/Source/ZoomNet/ZoomClient.cs b/Source/ZoomNet/ZoomClient.cs index 3f8812d6..ac16175b 100644 --- a/Source/ZoomNet/ZoomClient.cs +++ b/Source/ZoomNet/ZoomClient.cs @@ -91,6 +91,9 @@ public static string Version [Obsolete("The Data Compliance API is deprecated")] public IDataCompliance DataCompliance { get; private set; } + /// + public IExternalContacts ExternalContacts { get; private set; } + /// public IGroups Groups { get; private set; } @@ -219,6 +222,7 @@ private ZoomClient(IConnectionInfo connectionInfo, HttpClient httpClient, bool d Contacts = new Contacts(_fluentClient); Dashboards = new Dashboards(_fluentClient); DataCompliance = new DataCompliance(_fluentClient); + ExternalContacts = new ExternalContacts(_fluentClient); Groups = new Groups(_fluentClient); Meetings = new Meetings(_fluentClient); PastMeetings = new PastMeetings(_fluentClient);