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);