From a64fba610f5c3e6b320f3cee8c298cb506e5f66d Mon Sep 17 00:00:00 2001 From: Fabien Lavocat <4154532+FabienLavocat@users.noreply.github.com> Date: Fri, 2 Aug 2024 14:56:36 -0700 Subject: [PATCH 1/4] Remove CAPI --- .github/workflows/build-package.yml | 8 +- .github/workflows/codeql-analysis.yml | 8 +- .github/workflows/publish-package.yml | 8 +- DolbyIO-REST-APIs.sln | 6 - DolbyIO.Rest.Tests/AuthenticationTests.cs | 48 --- .../Communications/AuthenticationTests.cs | 40 --- DolbyIO.Rest.Tests/DolbyIO.Rest.Tests.csproj | 44 --- DolbyIO.Rest.Tests/Usings.cs | 1 - DolbyIO.Rest/AssemblyInfo.cs | 3 - DolbyIO.Rest/Authentication.cs | 101 ------ DolbyIO.Rest/Communications/Authentication.cs | 91 ----- DolbyIO.Rest/Communications/Capi.cs | 29 -- DolbyIO.Rest/Communications/Conferences.cs | 196 ----------- .../Communications/Models/Conferences.cs | 321 ------------------ .../Models/Monitoring.Conferences.cs | 273 --------------- .../Models/Monitoring.Recordings.cs | 190 ----------- .../Models/Monitoring.Webhooks.cs | 101 ------ .../Communications/Models/Monitoring.cs | 63 ---- .../Communications/Models/Recording.cs | 9 - DolbyIO.Rest/Communications/Models/Remix.cs | 41 --- .../Communications/Models/Streaming.cs | 31 -- .../Communications/Monitor/Conferences.cs | 196 ----------- .../Communications/Monitor/Monitoring.cs | 20 -- .../Communications/Monitor/Recordings.cs | 136 -------- .../Communications/Monitor/Webhooks.cs | 91 ----- DolbyIO.Rest/Communications/Recording.cs | 65 ---- DolbyIO.Rest/Communications/Remix.cs | 64 ---- DolbyIO.Rest/Communications/Streaming.cs | 125 ------- DolbyIO.Rest/DolbyIO.Rest.csproj | 4 +- DolbyIO.Rest/DolbyIOClient.cs | 7 - DolbyIO.Rest/Internal/Extensions.cs | 6 +- DolbyIO.Rest/Media/Analyze.cs | 5 - DolbyIO.Rest/Media/AnalyzeMusic.cs | 7 - DolbyIO.Rest/Media/AnalyzeSpeech.cs | 7 - DolbyIO.Rest/Media/Authentication.cs | 47 +++ DolbyIO.Rest/Media/Diagnose.cs | 7 - DolbyIO.Rest/Media/Enhance.cs | 1 - DolbyIO.Rest/Media/Internal/Extensions.cs | 3 +- DolbyIO.Rest/Media/Io.cs | 7 +- DolbyIO.Rest/Media/Jobs.cs | 5 +- DolbyIO.Rest/Media/Mapi.cs | 3 + DolbyIO.Rest/Media/Mastering.cs | 1 - DolbyIO.Rest/{ => Media}/Models/JwtToken.cs | 10 +- DolbyIO.Rest/Media/Transcode.cs | 1 - DolbyIO.Rest/Media/Webhooks.cs | 7 +- DolbyIO.Rest/Urls.cs | 6 +- LICENSE | 2 +- README.md | 103 +----- 48 files changed, 87 insertions(+), 2461 deletions(-) delete mode 100644 DolbyIO.Rest.Tests/AuthenticationTests.cs delete mode 100644 DolbyIO.Rest.Tests/Communications/AuthenticationTests.cs delete mode 100644 DolbyIO.Rest.Tests/DolbyIO.Rest.Tests.csproj delete mode 100644 DolbyIO.Rest.Tests/Usings.cs delete mode 100644 DolbyIO.Rest/AssemblyInfo.cs delete mode 100644 DolbyIO.Rest/Authentication.cs delete mode 100644 DolbyIO.Rest/Communications/Authentication.cs delete mode 100644 DolbyIO.Rest/Communications/Capi.cs delete mode 100644 DolbyIO.Rest/Communications/Conferences.cs delete mode 100644 DolbyIO.Rest/Communications/Models/Conferences.cs delete mode 100644 DolbyIO.Rest/Communications/Models/Monitoring.Conferences.cs delete mode 100644 DolbyIO.Rest/Communications/Models/Monitoring.Recordings.cs delete mode 100644 DolbyIO.Rest/Communications/Models/Monitoring.Webhooks.cs delete mode 100644 DolbyIO.Rest/Communications/Models/Monitoring.cs delete mode 100644 DolbyIO.Rest/Communications/Models/Recording.cs delete mode 100644 DolbyIO.Rest/Communications/Models/Remix.cs delete mode 100644 DolbyIO.Rest/Communications/Models/Streaming.cs delete mode 100644 DolbyIO.Rest/Communications/Monitor/Conferences.cs delete mode 100644 DolbyIO.Rest/Communications/Monitor/Monitoring.cs delete mode 100644 DolbyIO.Rest/Communications/Monitor/Recordings.cs delete mode 100644 DolbyIO.Rest/Communications/Monitor/Webhooks.cs delete mode 100644 DolbyIO.Rest/Communications/Recording.cs delete mode 100644 DolbyIO.Rest/Communications/Remix.cs delete mode 100644 DolbyIO.Rest/Communications/Streaming.cs create mode 100644 DolbyIO.Rest/Media/Authentication.cs rename DolbyIO.Rest/{ => Media}/Models/JwtToken.cs (72%) diff --git a/.github/workflows/build-package.yml b/.github/workflows/build-package.yml index 11ce61b..f8e3808 100644 --- a/.github/workflows/build-package.yml +++ b/.github/workflows/build-package.yml @@ -10,16 +10,14 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout 🛎️ - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: persist-credentials: false - - uses: actions/setup-dotnet@v3 + - uses: actions/setup-dotnet@v4 with: dotnet-version: '6.x' - name: Build the solution 🔨 run: dotnet build - - name: Run Unit Tests 🍴 - run: dotnet test - name: Create NuGet package 🌎 run: dotnet pack DolbyIO.Rest/DolbyIO.Rest.csproj -p:Configuration=Release - name: Sign NuGet Package @@ -29,7 +27,7 @@ jobs: dotnet nuget sign DolbyIO.Rest.*.nupkg --certificate-path ./certificate.pfx --certificate-password ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD}} --timestamper http://timestamp.digicert.com/ rm certificate.pfx - name: Upload artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: nuget-package path: DolbyIO.Rest/bin/Release diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 78eca8a..b2f4617 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -38,11 +38,11 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -55,7 +55,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v2 + uses: github/codeql-action/autobuild@v3 # ℹ️ Command-line programs to run using the OS shell. # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun @@ -68,6 +68,6 @@ jobs: # ./location_of_script_within_repo/buildscript.sh - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 with: category: '/language:${{matrix.language}}' diff --git a/.github/workflows/publish-package.yml b/.github/workflows/publish-package.yml index 45f06af..c42e983 100644 --- a/.github/workflows/publish-package.yml +++ b/.github/workflows/publish-package.yml @@ -12,16 +12,14 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout 🛎️ - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: persist-credentials: false - - uses: actions/setup-dotnet@v3 + - uses: actions/setup-dotnet@v4 with: dotnet-version: '6.x' - name: Build the solution 🔨 run: dotnet build -p:Version=${{ env.VERSION }} - - name: Run Unit Tests 🍴 - run: dotnet test - name: Create NuGet package 🌎 run: dotnet pack DolbyIO.Rest/DolbyIO.Rest.csproj -p:Configuration=Release -p:Version=${{ env.VERSION }} - name: Sign NuGet Package @@ -31,7 +29,7 @@ jobs: dotnet nuget sign DolbyIO.Rest.*.nupkg --certificate-path ./certificate.pfx --certificate-password ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD}} --timestamper http://timestamp.digicert.com/ rm certificate.pfx - name: Upload artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: nuget-package path: DolbyIO.Rest/bin/Release diff --git a/DolbyIO-REST-APIs.sln b/DolbyIO-REST-APIs.sln index f9e65fc..a0b76fe 100644 --- a/DolbyIO-REST-APIs.sln +++ b/DolbyIO-REST-APIs.sln @@ -5,8 +5,6 @@ VisualStudioVersion = 25.0.1703.5 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DolbyIO.Rest", "DolbyIO.Rest\DolbyIO.Rest.csproj", "{6EA9D0CC-8A04-4AF4-8E24-598377802881}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DolbyIO.Rest.Tests", "DolbyIO.Rest.Tests\DolbyIO.Rest.Tests.csproj", "{1A6EEC23-1691-42CB-B3B6-FFCF0DEA8C31}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -17,10 +15,6 @@ Global {6EA9D0CC-8A04-4AF4-8E24-598377802881}.Debug|Any CPU.Build.0 = Debug|Any CPU {6EA9D0CC-8A04-4AF4-8E24-598377802881}.Release|Any CPU.ActiveCfg = Release|Any CPU {6EA9D0CC-8A04-4AF4-8E24-598377802881}.Release|Any CPU.Build.0 = Release|Any CPU - {1A6EEC23-1691-42CB-B3B6-FFCF0DEA8C31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1A6EEC23-1691-42CB-B3B6-FFCF0DEA8C31}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1A6EEC23-1691-42CB-B3B6-FFCF0DEA8C31}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1A6EEC23-1691-42CB-B3B6-FFCF0DEA8C31}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/DolbyIO.Rest.Tests/AuthenticationTests.cs b/DolbyIO.Rest.Tests/AuthenticationTests.cs deleted file mode 100644 index 83a8ba7..0000000 --- a/DolbyIO.Rest.Tests/AuthenticationTests.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System.Text; -using DolbyIO.Rest.Models; -using Newtonsoft.Json; -using RichardSzalay.MockHttp; - -namespace DolbyIO.Rest.Tests; - -[Collection("SDK")] -public class AuthenticationTests -{ - [Fact] - public async Task Test_Authentication_GetApiAccessTokenAsync() - { - var jwtToken = new JwtToken - { - AccessToken = "abcdef", - TokenType = "Bearer", - ExpiresIn = 123, - Scope = "comms:client_access_token:create" - }; - - const string appKey = "app_key"; - const string appSecret = "app_secret"; - string authz = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{appKey}:{appSecret}")); - - var messageHandler = new MockHttpMessageHandler(); - messageHandler - .Expect("https://api.dolby.io/v1/auth/token") - .WithHeaders("Authorization", $"Basic {authz}") - .WithFormData(new Dictionary() { - { "grant_type", "client_credentials" }, - { "expires_in", jwtToken.ExpiresIn.ToString() } - }) - .Respond("application/json", JsonConvert.SerializeObject(jwtToken)); - - JwtToken jwt; - using (DolbyIOClient client = new DolbyIOClient(messageHandler.ToHttpClient())) - { - jwt = await client.Authentication.GetApiAccessTokenAsync(appKey, appSecret, jwtToken.ExpiresIn, new string[] { "comms:client_access_token:create" }); - } - - Assert.NotEqual(jwtToken, jwt); - Assert.Equal(jwtToken.AccessToken, jwt.AccessToken); - Assert.Equal(jwtToken.TokenType, jwt.TokenType); - Assert.Equal(jwtToken.ExpiresIn, jwt.ExpiresIn); - Assert.Equal(jwtToken.Scope, jwt.Scope); - } -} diff --git a/DolbyIO.Rest.Tests/Communications/AuthenticationTests.cs b/DolbyIO.Rest.Tests/Communications/AuthenticationTests.cs deleted file mode 100644 index 5affa88..0000000 --- a/DolbyIO.Rest.Tests/Communications/AuthenticationTests.cs +++ /dev/null @@ -1,40 +0,0 @@ -using DolbyIO.Rest.Models; -using Newtonsoft.Json; -using RichardSzalay.MockHttp; - -namespace DolbyIO.Rest.Tests.Communications; - -[Collection("Communications")] -public class AuthenticationTests -{ - [Fact] - public async Task Test_Authentication_GetClientAccessTokenV2Async() - { - var jwtToken = new JwtToken - { - AccessToken = "abcdef", - TokenType = "Bearer", - ExpiresIn = 123, - Scope = "*" - }; - - var messageHandler = new MockHttpMessageHandler(); - messageHandler - .Expect("https://comms.api.dolby.io/v2/client-access-token") - .WithHeaders("Authorization", $"Bearer {jwtToken.AccessToken}") - .Respond("application/json", JsonConvert.SerializeObject(jwtToken)); - - JwtToken jwt; - using (DolbyIOClient client = new DolbyIOClient(messageHandler.ToHttpClient())) - { - jwt = await client.Communications.Authentication.GetClientAccessTokenV2Async(jwtToken, new string[] {"*"}, expiresIn: 123); - } - - Assert.NotNull(jwt); - Assert.NotEqual(jwtToken, jwt); - Assert.Equal(jwtToken.AccessToken, jwt.AccessToken); - Assert.Equal(jwtToken.TokenType, jwt.TokenType); - Assert.Equal(jwtToken.ExpiresIn, jwt.ExpiresIn); - Assert.Equal(jwtToken.Scope, jwt.Scope); - } -} diff --git a/DolbyIO.Rest.Tests/DolbyIO.Rest.Tests.csproj b/DolbyIO.Rest.Tests/DolbyIO.Rest.Tests.csproj deleted file mode 100644 index 8519ec0..0000000 --- a/DolbyIO.Rest.Tests/DolbyIO.Rest.Tests.csproj +++ /dev/null @@ -1,44 +0,0 @@ - - - - net6.0 - enable - enable - - false - - - - latestmajor - - - latestmajor - - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - - - - - - - - - - - - - - - - diff --git a/DolbyIO.Rest.Tests/Usings.cs b/DolbyIO.Rest.Tests/Usings.cs deleted file mode 100644 index 9df1d42..0000000 --- a/DolbyIO.Rest.Tests/Usings.cs +++ /dev/null @@ -1 +0,0 @@ -global using Xunit; diff --git a/DolbyIO.Rest/AssemblyInfo.cs b/DolbyIO.Rest/AssemblyInfo.cs deleted file mode 100644 index 7d34120..0000000 --- a/DolbyIO.Rest/AssemblyInfo.cs +++ /dev/null @@ -1,3 +0,0 @@ -using System.Runtime.CompilerServices; - -[assembly: InternalsVisibleToAttribute("DolbyIO.Rest.Tests")] diff --git a/DolbyIO.Rest/Authentication.cs b/DolbyIO.Rest/Authentication.cs deleted file mode 100644 index ba520e5..0000000 --- a/DolbyIO.Rest/Authentication.cs +++ /dev/null @@ -1,101 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Text; -using System.Threading.Tasks; -using DolbyIO.Rest.Models; - -namespace DolbyIO.Rest; - -public sealed class Authentication -{ - private readonly HttpClient _httpClient; - - internal Authentication(HttpClient httpClient) - { - _httpClient = httpClient; - } - - /// - /// Generates an API token. - /// To make any API call, you must acquire a JWT (JSON Web Token) format API token.
- /// See:
- /// See: - ///
- /// Your Dolby.io App Key. - /// Your Dolby.io App Secret. - /// API token expiration time in seconds. If no value is specified, the default is 1800, indicating 30 minutes. The maximum value is 86,400, indicating 24 hours. - /// A list of case-sensitive strings allowing you to control what scope of access the API token should have. If not specified, the API token will possess unrestricted access to all resources and actions. The API supports the following scopes: - /// - /// - /// comms:client_access_token:create - /// Allows requesting a client access token. - /// - /// - /// comms:conf:create - /// Allows creating a new conference. - /// - /// - /// comms:conf:admin - /// Allows administrating a conference, including actions such as Invite, Kick, Send Message, Set Spatial Listener's Audio, and Update Permissions. - /// - /// - /// comms:conf:destroy - /// Allows terminating a live conference. - /// - /// - /// comms:monitor:delete - /// Allows deleting data from the Monitor API, for example, deleting recordings. - /// - /// - /// comms:monitor:read - /// Allows reading data through the Monitor API. - /// - /// - /// comms:monitor:download - /// Allows generating download URLs for data (e.g.recording) through the Monitor API. - /// - /// - /// comms:stream:write - /// Allows starting and stopping RTMP or Real-Time streaming. - /// - /// - /// comms:remix:write - /// Allows remixing recordings. - /// - /// - /// comms:remix:read - /// Allows reading the remix status. - /// - /// - /// comms:record:write - /// Allows starting and stopping recordings. - /// - /// - /// Incorrect values are omitted.If you want to give the token access to all Communications REST APIs, you can use a wildcard, such as comms:* - /// The property returns the newly created . - public async Task GetApiAccessTokenAsync(string appKey, string appSecret, int expiresIn = 1800, string[] scope = null) - { - var nvc = new Dictionary() { - { "grant_type", "client_credentials" }, - { "expires_in", expiresIn.ToString() } - }; - if (scope != null && scope.Length > 0) - { - nvc.Add("scope", string.Join(' ', scope)); - } - - const string url = Urls.API_BASE_URL + "/v1/auth/token"; - string authz = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{appKey}:{appSecret}")); - using (var request = new HttpRequestMessage(HttpMethod.Post, url)) - { - request.Headers.Authorization = new AuthenticationHeaderValue("Basic", authz); - request.Headers.CacheControl = new CacheControlHeaderValue() { NoCache = true }; - - request.Content = new FormUrlEncodedContent(nvc); - - return await _httpClient.SendAsync(request); - } - } -} diff --git a/DolbyIO.Rest/Communications/Authentication.cs b/DolbyIO.Rest/Communications/Authentication.cs deleted file mode 100644 index e851087..0000000 --- a/DolbyIO.Rest/Communications/Authentication.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Text; -using System.Threading.Tasks; -using DolbyIO.Rest.Models; - -namespace DolbyIO.Rest.Communications; - -public sealed class Authentication -{ - private readonly HttpClient _httpClient; - - internal Authentication(HttpClient httpClient) - { - _httpClient = httpClient; - } - - /// - /// Gets a client access token to authenticate a session.
- /// See: - ///
- /// Your Dolby.io App Key. - /// Your Dolby.io App Secret. - /// Access token expiration time in seconds. The maximum value is 86,400, indicating 24 hours. If no value is specified, the default is 3,600, indicating one hour. - /// The property returns the newly created . - [Obsolete("This function is now deprecated and will be removed in the next release of this SDK. Please start using GetClientAccessTokenV2Async instead.")] - public async Task GetClientAccessTokenAsync(string appKey, string appSecret, int expiresIn = 3600) - { - var nvc = new Dictionary() { - { "grant_type", "client_credentials" }, - { "expires_in", expiresIn.ToString() } - }; - - const string url = Urls.SESSION_BASE_URL + "/v1/oauth2/token"; - string authz = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{appKey}:{appSecret}")); - using (var request = new HttpRequestMessage(HttpMethod.Post, url)) - { - request.Headers.Authorization = new AuthenticationHeaderValue("Basic", authz); - request.Headers.CacheControl = new CacheControlHeaderValue() { NoCache = true }; - - request.Content = new FormUrlEncodedContent(nvc); - - return await _httpClient.SendAsync(request); - } - } - - /// - /// Gets a client access token to authenticate a session.
- /// See: - ///
- /// Access token to use for authentication. - /// A list of case-sensitive strings allowing you to control what scope of access the client access token should have. The API supports the following scopes: - /// - /// - /// conf:create - /// Allows creating a new conference. - /// - /// - /// notifications:set - /// Allows the client to subscribe to events. - /// - /// - /// file:convert - /// Allows converting files. - /// - /// - /// session:update - /// Allows updating the participant's name and avatar URL. - /// - /// - /// Incorrect values are omitted.If you want to give the token access to all scopes, you can use a wildcard, such as *. - /// The unique identifier of the participant who requests the token. - /// Access token expiration time in seconds. If no value is specified, the default is 3,600, indicating one hour. The maximum value is 86,400, indicating 24 hours. - /// The property returns the newly created . - public async Task GetClientAccessTokenV2Async(JwtToken accessToken, string[] sessionScope, string externalId = null, int expiresIn = 3600) - { - var nvc = new Dictionary() { - { "grant_type", "client_credentials" }, - { "expires_in", expiresIn.ToString() } - }; - if (sessionScope != null && sessionScope.Length > 0) - { - nvc.Add("sessionScope", string.Join(' ', sessionScope)); - } - - const string url = Urls.CAPI_BASE_URL + "/v2/client-access-token"; - return await _httpClient.SendPostAsync(url, accessToken, nvc); - } -} diff --git a/DolbyIO.Rest/Communications/Capi.cs b/DolbyIO.Rest/Communications/Capi.cs deleted file mode 100644 index cb3e174..0000000 --- a/DolbyIO.Rest/Communications/Capi.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Net.Http; -using DolbyIO.Rest.Communications.Monitor; - -namespace DolbyIO.Rest.Communications; - -public sealed class Capi -{ - public Authentication Authentication { get; } - - public Conferences Conferences { get; } - - public Monitoring Monitor { get; } - - public Recording Recording { get; } - - public Remix Remix { get; } - - public Streaming Streaming { get; } - - internal Capi(HttpClient httpClient) - { - Authentication = new Authentication(httpClient); - Conferences = new Conferences(httpClient); - Monitor = new Monitoring(httpClient); - Recording = new Recording(httpClient); - Remix = new Remix(httpClient); - Streaming = new Streaming(httpClient); - } -} diff --git a/DolbyIO.Rest/Communications/Conferences.cs b/DolbyIO.Rest/Communications/Conferences.cs deleted file mode 100644 index 186c957..0000000 --- a/DolbyIO.Rest/Communications/Conferences.cs +++ /dev/null @@ -1,196 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net.Http; -using System.Threading.Tasks; -using DolbyIO.Rest.Communications.Models; -using DolbyIO.Rest.Models; - -namespace DolbyIO.Rest.Communications; - -public sealed class Conferences -{ - private readonly HttpClient _httpClient; - - internal Conferences(HttpClient httpClient) - { - _httpClient = httpClient; - } - - /// - /// Creates a conference.
- /// See: - ///
- /// Access token to use for authentication. - /// Options to create the conference. - /// The property returns the newly created . - public async Task CreateAsync(JwtToken accessToken, CreateConferenceOptions options) - { - var requestObject = new CreateConferenceRequest - { - Alias = options.Alias, - OwnerExternalId = options.OwnerExternalId, - Parameters = new CreateConferenceParametersRequest - { - PinCode = options.PinCode, - DolbyVoice = options.DolbyVoice, - LiveRecording = options.LiveRecording, - RTCPMode = Enum.GetName(typeof(RTCPMode), options.RTCPMode).ToLowerInvariant(), - Ttl = options.Ttl, - VideoCodec = Enum.GetName(typeof(VideoCodec), options.VideoCodec), - AudioOnly = options.AudioOnly, - RecordingFormats = options.RecordingFormats, - }, - Participants = options.Participants?.ToDictionary(p => p.ExternalId, p => new CreateConferenceParticipantRequest - { - Permissions = p.Permissions?.Select(pe => Enum.GetName(typeof(Permission), pe)), - Notification = p.Notify - }) - }; - - string url = $"{Urls.CAPI_BASE_URL}/v2/conferences/create"; - if (!string.IsNullOrWhiteSpace(options.Region)) - url = url.Replace("https://", $"https://{options.Region}."); - - return await _httpClient.SendPostAsync(url, accessToken, requestObject); - } - - /// - /// Invites participants to an ongoing conference. - /// This API can also be used to generate new conference access tokens for an ongoing conference. - /// If the invite request includes participants that are already in the conference, - /// a new conference access token is not generated and an invitation is not sent.
- /// See: - ///
- /// Access token to use for authentication. - /// Identifier of the conference. - /// List of participants to invite to the conference. - /// The property returns the list of user tokens for each participants. - public async Task> InviteAsync(JwtToken accessToken, string conferenceId, IEnumerable participants) - { - var body = new - { - participants = participants.ToDictionary(p => p.ExternalId, p => new CreateConferenceParticipantRequest - { - Permissions = p.Permissions?.Select(pe => Enum.GetName(typeof(Permission), pe)), - Notification = p.Notify - }) - }; - - string url = $"{Urls.CAPI_BASE_URL}/v2/conferences/{conferenceId}/invite"; - return await _httpClient.SendPostAsync>(url, accessToken, body); - } - - /// - /// Kicks participants from an ongoing conference.
- /// See: - ///
- /// Access token to use for authentication. - /// Identifier of the conference. - /// External identifiers of the participants to kick our of the conference. - /// A that represents the asynchronous operation. - public async Task KickAsync(JwtToken accessToken, string conferenceId, IEnumerable externalIds) - { - var body = new { externalIds = externalIds }; - string url = $"{Urls.CAPI_BASE_URL}/v2/conferences/{conferenceId}/kick"; - await _httpClient.SendPostAsync(url, accessToken, body); - } - - /// - /// Sends a message to some or all participants in a conference.
- /// See: - ///
- /// Access token to use for authentication. - /// Identifier of the conference. - /// The external ID of the author of the message. - /// A list of external IDs that will receive the message. If empty, the message will be broadcasted to all participants in the conference. - /// The message to send. - /// A that represents the asynchronous operation. - public async Task SendMessageAsync(JwtToken accessToken, string conferenceId, string fromExternalId, IEnumerable toExternalIds, string message) - { - var body = new { - from = fromExternalId, - message = message, - to = toExternalIds - }; - - string url = $"{Urls.CAPI_BASE_URL}/v2/conferences/{conferenceId}/message"; - await _httpClient.SendPostAsync(url, accessToken, body); - } - - /// - /// Sets the spatial audio scene for all listeners in an ongoing conference. - /// This sets the spatial audio environment, the position and direction for all listeners with the spatialAudio flag enabled. - /// The calls are not cumulative, and each call sets all the spatial listener values. - /// Participants who do not have a position set are muted.
- /// See: - ///
- /// Access token to use for authentication. - /// Identifier of the conference. - /// The spatial environment of an application, so the audio renderer understands which directions the application considers forward, up, and right and which units it uses for distance. - /// The listener's audio position and direction, defined using Cartesian coordinates. - /// The users' audio positions, defined using Cartesian coordinates. - /// A that represents the asynchronous operation. - public async Task SetSpatialListenersAudioAsync(JwtToken accessToken, string conferenceId, SpatialEnvironment environment, SpatialListener listener, IDictionary users) - { - var body = new - { - environment = environment, - listener = listener, - users = users - }; - - string url = $"{Urls.CAPI_BASE_URL}/v2/conferences/{conferenceId}/spatial-listeners-audio"; - await _httpClient.SendPutAsync(url, accessToken, body); - } - - /// - /// Update permissions for participants in a conference. When a participant's permissions are updated, the new token is sent directly to the SDK. - /// The SDK automatically receives, stores, and manages the new token and a permissionsUpdated event is sent.
- /// See: - ///
- /// Access token to use for authentication. - /// Identifier of the conference. - /// List of the participants with their new permissions. - /// The property returns the list of user tokens for each participants. - public async Task> UpdatePermissionsAsync(JwtToken accessToken, string conferenceId, IEnumerable participants) - { - var body = new - { - participants = participants.ToDictionary(p => p.ExternalId, p => new CreateConferenceParticipantRequest - { - Permissions = p.Permissions?.Select(pe => Enum.GetName(typeof(Permission), pe)), - Notification = p.Notify - }) - }; - - string url = $"{Urls.CAPI_BASE_URL}/v2/conferences/{conferenceId}/permissions"; - return await _httpClient.SendPostAsync>(url, accessToken, body); - } - - /// - /// Returns the current participant list.
- /// See: - ///
- /// Access token to use for authentication. - /// Identifier of the conference. - /// The property returns the list of participants in the conference. - public async Task ParticipantsAsync(JwtToken accessToken, string conferenceId) - { - string url = $"{Urls.CAPI_BASE_URL}/v2/conferences/{conferenceId}/participants"; - return await _httpClient.SendGetAsync(url, accessToken); - } - - /// - /// Terminates an ongoing conference and removes all remaining participants from the conference.
- /// See: - ///
- /// Access token to use for authentication. - /// Identifier of the conference. - /// A that represents the asynchronous operation. - public async Task TerminateAsync(JwtToken accessToken, string conferenceId) - { - string url = $"{Urls.CAPI_BASE_URL}/v2/conferences/{conferenceId}"; - await _httpClient.SendDeleteAsync(url, accessToken); - } -} diff --git a/DolbyIO.Rest/Communications/Models/Conferences.cs b/DolbyIO.Rest/Communications/Models/Conferences.cs deleted file mode 100644 index 738ca8b..0000000 --- a/DolbyIO.Rest/Communications/Models/Conferences.cs +++ /dev/null @@ -1,321 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace DolbyIO.Rest.Communications.Models; - -public sealed class CreateConferenceOptions -{ - /// - /// Gets or sets the conference owner's external ID. - /// - public string OwnerExternalId { get; set; } - - /// - /// Gets or sets the conference alias, provided by the customer as a way to identify one or more conferences. - /// - public string Alias { get; set; } - - /// - /// Gets or sets the PIN code of the conference. This applies to conferences using PSTN (telephony network). - /// - public string PinCode { get; set; } - - /// - /// Gets or sets if Dolby Voice is enabled for the conference. The true value creates the conference with Dolby Voice enabled. - /// - public bool? DolbyVoice { get; set; } - - /// - /// Gets or sets if live recording is enabled for the conference. When set to true, the recorded file is available at the end of the call and can be downloaded immediately. - /// - public bool? LiveRecording { get; set; } - - /// - /// Gets or sets the bitrate adaptation mode for the video transmission. - /// - public RTCPMode RTCPMode { get; set; } - - /// - /// Gets or sets the time to live that enables customizing the waiting time (in seconds) and terminating empty conferences. - /// - public int? Ttl { get; set; } - - /// - /// Gets or sets the video codec (VP8 or H264) for the conference. - /// - public VideoCodec VideoCodec { get; set; } - - /// - /// Gets or sets if the conference does not allow participants to enable video. - /// - public bool? AudioOnly { get; set; } - - /// - /// Gets or sets the list of participants. - /// - public IEnumerable Participants { get; set; } - - /// - /// Gets or sets the recording format. Valid values are mp3 and mp4. - /// - public IEnumerable RecordingFormats { get; set; } - - /// - /// Gets or sets the conference region. Can be one of: - /// - /// - /// au - /// Australia - /// - /// - /// ca - /// Canada - /// - /// - /// eu - /// Europe - /// - /// - /// in - /// India - /// - /// - /// us - /// United States - /// - /// - /// - public string Region { get; set; } -} - -public enum RTCPMode -{ - /// - /// Adjusts the transmission bitrate to the receiver who has the worst network conditions. - /// - Worst, - /// - /// Averages the available bandwidth of all the receivers and adjusts the transmission bitrate to this value. - /// - Average, - /// - /// Does not adjust the transmission bitrate to the receiver’s bandwidth. - /// - Max -} - -public enum VideoCodec -{ - VP8, - H264 -} - -public sealed class Participant -{ - public string ExternalId { get; set; } - - public IEnumerable Permissions { get; set; } - - public bool Notify { get; set; } -} - -public enum Permission -{ - /// - /// Allows a participant to invite participants to a conference. - /// - INVITE, - - /// - /// Allows a participant to join a conference. - /// - JOIN, - - /// - /// Allows a participant to send an audio stream during a conference. - /// - SEND_AUDIO, - - /// - /// Allows a participant to send a video stream during a conference. - /// - SEND_VIDEO, - - /// - /// Allows a participant to share their screen during a conference. - /// - SHARE_SCREEN, - - /// - /// Allows a participant to share a video during a conference. - /// - SHARE_VIDEO, - - /// - /// Allows a participant to share a file during a conference. - /// - SHARE_FILE, - - /// - /// Allows a participant to send a message to other participants during a conference. - /// - SEND_MESSAGE, - - /// - /// Allows a participant to record a conference. - /// - RECORD, - - /// - /// Allows a participant to stream a conference. - /// - STREAM, - - /// - /// Allows a participant to kick other participants from a conference. - /// - KICK, - - /// - /// Allows a participant to update other participants' permissions. - /// - UPDATE_PERMISSIONS, -} - -internal sealed class CreateConferenceRequest -{ - [JsonProperty("alias")] - public string Alias { get; set; } - - [JsonProperty("ownerExternalId")] - public string OwnerExternalId { get; set; } - - [JsonProperty("parameters")] - public CreateConferenceParametersRequest Parameters { get; set; } - - [JsonProperty("participants")] - public IDictionary Participants { get; set; } -} - -internal sealed class CreateConferenceParametersRequest -{ - [JsonProperty("pinCode")] - public string PinCode { get; set; } - - [JsonProperty("dolbyVoice")] - public bool? DolbyVoice { get; set; } - - [JsonProperty("liveRecording")] - public bool? LiveRecording { get; set; } - - [JsonProperty("rtcpMode")] - public string RTCPMode { get; set; } - - [JsonProperty("ttl")] - public int? Ttl { get; set; } - - [JsonProperty("videoCodec")] - public string VideoCodec { get; set; } - - [JsonProperty("audioOnly")] - public bool? AudioOnly { get; set; } - - [JsonProperty("recording")] - public IEnumerable RecordingFormats { get; set; } -} - -internal sealed class CreateConferenceParticipantRequest -{ - [JsonProperty("permissions")] - public IEnumerable Permissions { get; set; } - - [JsonProperty("notification")] - public bool? Notification { get; set; } -} - -public sealed class Conference -{ - [JsonProperty("conferenceId")] - public string Id { get; set; } - - [JsonProperty("conferenceAlias")] - public string Alias { get; set; } - - [JsonProperty("conferencePincode")] - public string Pincode { get; set; } - - [JsonProperty("isProtected")] - public string IsProtected { get; set; } - - [JsonProperty("ownerToken")] - public string OwnerToken { get; set; } -} - -public sealed class CartesianCoordinates -{ - [JsonProperty("x")] - public float X { get; set; } - - [JsonProperty("y")] - public float Y { get; set; } - - [JsonProperty("z")] - public float Z { get; set; } -} - -public sealed class SpatialEnvironment -{ - [JsonProperty("scale")] - public CartesianCoordinates Scale { get; set; } - - [JsonProperty("forward")] - public CartesianCoordinates Forward { get; set; } - - [JsonProperty("up")] - public CartesianCoordinates Up { get; set; } - - [JsonProperty("right")] - public CartesianCoordinates Right { get; set; } -} - -public sealed class SpatialListener -{ - [JsonProperty("position")] - public CartesianCoordinates Position { get; set; } - - [JsonProperty("direction")] - public CartesianCoordinates Direction { get; set; } -} - -public sealed class ListConferenceParticipant -{ - [JsonProperty("userId")] - public string UserId { get; set; } - - [JsonProperty("externalId")] - public string ExternalId { get; set; } - - [JsonProperty("name")] - public string Name { get; set; } - - [JsonProperty("avatarUrl")] - public string AvatarUrl { get; set; } - - [JsonProperty("ipAddress")] - public string IpAddress { get; set; } - - [JsonProperty("userAgent")] - public string UserAgent { get; set; } - - [JsonProperty("lastJoinTimestamp")] - public int LastJoinTimestamp { get; set; } - - [JsonProperty("nbSession")] - public int NbSession { get; set; } -} - -public sealed class ListParticipantsResponse -{ - [JsonProperty("participants")] - public IEnumerable Participants { get; set; } -} diff --git a/DolbyIO.Rest/Communications/Models/Monitoring.Conferences.cs b/DolbyIO.Rest/Communications/Models/Monitoring.Conferences.cs deleted file mode 100644 index 304f275..0000000 --- a/DolbyIO.Rest/Communications/Models/Monitoring.Conferences.cs +++ /dev/null @@ -1,273 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Newtonsoft.Json; - -namespace DolbyIO.Rest.Communications.Models; - -public sealed class ListConferencesOptions : PagedOptions -{ - /// - /// Search conferences using Alias. Use regular expression to search for conferences with similar aliases. For example: - /// - /// - /// foobar - /// gets all conferences with alias foobar. - /// - /// - /// .*foobar - /// gets all conferences with alias ending with foobar. - /// - /// - /// foobar.* - /// gets all conferences with alias starting with foobar. - /// - /// - /// .*foobar.* - /// gets all conferences with alias containing foobar. - /// - /// - /// .*2021.*|.*2022.* - /// gets all conferences with alias containing either 2021 or 2022. - /// - /// - /// - public string Alias { get; set; } - - /// - /// Search for ongoing references (true) or all conferences (false). - /// - public bool Active { get; set; } - - /// - /// Gets or sets the external ID of the participant who created the conference. - /// - public string ExternalId { get; set; } - - /// - /// For live conferences, the number of user, listener, and pstn participants. - /// - public bool LiveStats { get; set; } -} - -public sealed class ListAllConferencesOptions : AllElementsOptions -{ - /// - /// Search conferences using Alias. Use regular expression to search for conferences with similar aliases. For example: - /// - /// - /// foobar - /// gets all conferences with alias foobar. - /// - /// - /// .*foobar - /// gets all conferences with alias ending with foobar. - /// - /// - /// foobar.* - /// gets all conferences with alias starting with foobar. - /// - /// - /// .*foobar.* - /// gets all conferences with alias containing foobar. - /// - /// - /// .*2021.*|.*2022.* - /// gets all conferences with alias containing either 2021 or 2022. - /// - /// - /// - public string Alias { get; set; } - - /// - /// Search for ongoing references (true) or all conferences (false). - /// - public bool Active { get; set; } - - /// - /// Gets or sets the external ID of the participant who created the conference. - /// - public string ExternalId { get; set; } - - /// - /// For live conferences, the number of user, listener, and pstn participants. - /// - public bool LiveStats { get; set; } -} - -public sealed class ConferenceInfo -{ - [JsonProperty("confId")] - public string Id { get; set; } - - [JsonProperty("alias")] - public string Alias { get; set; } - - [JsonProperty("region")] - public string Region { get; set; } - - [JsonProperty("dolbyVoice")] - public bool DolbyVoice { get; set; } - - [JsonProperty("start")] - public long Start { get; set; } - - [JsonProperty("live")] - public bool Live { get; set; } - - [JsonProperty("end")] - public long End { get; set; } - - [JsonProperty("duration")] - public long Duration { get; set; } - - [JsonProperty("type")] - public string Type { get; set; } - - [JsonProperty("presenceDuration")] - public long PresenceDuration { get; set; } - - [JsonProperty("recordingDuration")] - public long RecordingDuration { get; set; } - - [JsonProperty("mixerLiveRecording")] - public long MixerLiveRecording { get; set; } - - [JsonProperty("mixerHlsStreaming")] - public long MixerHlsStreaming { get; set; } - - [JsonProperty("mixerRtmpStreaming")] - public long MixerRtmpStreaming { get; set; } - - [JsonProperty("nbUsers")] - public int NbUsers { get; set; } - - [JsonProperty("nbListeners")] - public int NbListeners { get; set; } - - [JsonProperty("nbPstn")] - public int bPstn { get; set; } - - [JsonProperty("owner")] - public ConferenceOwner Owner { get; set; } - - [JsonProperty("statistics")] - public ConferenceStatistics Statistics { get; set; } - - [JsonProperty("streamingAPIUsage")] - public ConferenceStreamingAPIUsage StreamingAPIUsage { get; set; } -} - -public sealed class ConferenceOwner -{ - [JsonProperty("userId")] - public string UserId { get; set; } - - [JsonProperty("metadata")] - public ParticipantMetadata Metadata { get; set; } -} - -public sealed class ParticipantMetadata -{ - [JsonProperty("externalName")] - public string ExternalName { get; set; } - - [JsonProperty("externalId")] - public string ExternalId { get; set; } - - [JsonProperty("externalPhotoUrl")] - public string ExternalPhotoUrl { get; set; } - - [JsonProperty("ipAddress")] - public string IpAddress { get; set; } -} - -public sealed class MaxParticipants -{ - [JsonProperty("USER")] - public int User { get; set; } - - [JsonProperty("LISTENER")] - public int Listener { get; set; } - - [JsonProperty("MIXER")] - public int Mixer { get; set; } - - [JsonProperty("PSTN")] - public int Pstn { get; set; } -} - -public sealed class ConferenceStatistics -{ - [JsonProperty("maxParticipants")] - public MaxParticipants MaxParticipants { get; set; } - - [JsonProperty("network")] - public object Network { get; set; } -} - -public sealed class ConferenceStreamingAPIUsage -{ - [JsonProperty("bytesIn")] - public long? BytesIn { get; set; } - - [JsonProperty("bytesOut")] - public long? BytesOut { get; set; } - - [JsonProperty("publishDurationSec")] - public int? PublishDurationSec { get; set; } - - [JsonProperty("publishes")] - public int? Publishes { get; set; } - - [JsonProperty("viewDurationSec")] - public int? ViewDurationSec { get; set; } - - [JsonProperty("views")] - public int? Views { get; set; } -} - -public sealed class ListConferencesResponse : PagedResponse -{ - /// - /// Gets or sets the list of conferences. - /// - [JsonProperty("conferences")] - public IEnumerable Conferences { get; set; } -} - -public sealed class GetConferenceParticipantsOptions : PagedOptions -{ - public string ConferenceId { get; set; } - - public string UserId { get; set; } - - public string Type { get; set; } -} - -public sealed class GetAllConferenceParticipantsOptions : AllElementsOptions -{ - public string ConferenceId { get; set; } - - public string UserId { get; set; } - - public string Type { get; set; } -} - -public sealed class ConferenceParticipant -{ - [JsonProperty("connections")] - public IEnumerable Connections { get; set; } - - [JsonProperty("stats")] - public object Stats { get; set; } -} - -public sealed class GetConferenceParticipantsResponse : PagedResponse -{ - /// - /// Gets or sets the list of participants. - /// - [JsonProperty("participants")] - public Dictionary Participants { get; set; } -} diff --git a/DolbyIO.Rest/Communications/Models/Monitoring.Recordings.cs b/DolbyIO.Rest/Communications/Models/Monitoring.Recordings.cs deleted file mode 100644 index 873bb49..0000000 --- a/DolbyIO.Rest/Communications/Models/Monitoring.Recordings.cs +++ /dev/null @@ -1,190 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace DolbyIO.Rest.Communications.Models; - -public sealed class GetRecordingsOptions : PagedOptions -{ -} - -public sealed class GetAllRecordingsOptions : AllElementsOptions -{ -} - -public sealed class GetRecordingOptions : PagedOptions -{ - /// - /// Gets or sets the identifier of the conference. - /// - public string ConferenceId { get; set; } -} - -public sealed class Recording -{ - /// - /// Gets or sets the ID for the conference. - /// - [JsonProperty("confId")] - public string ConferenceId { get; set; } - - /// - /// Gets or sets the alias of the conference. - /// - [JsonProperty("alias")] - public string Alias { get; set; } - - /// - /// Gets or sets the estimated duration of the recording. - /// - [JsonProperty("duration")] - public long Duration { get; set; } - - /// - /// Gets or sets the epoch time of the end of the recording. - /// - [JsonProperty("ts")] - public long Ts { get; set; } - - /// - /// Gets or sets the region code in which the recording took place. - /// - [JsonProperty("region")] - public string Region { get; set; } - - /// - /// Gets or sets the list of video or non-Dolby Voice audio mix recordings. - /// - [JsonProperty("mix")] - public MixRecording Mix { get; set; } - - /// - /// Gets or sets the list of Dolby Voice-based audio recordings. - /// - [JsonProperty("audio")] - public AudioRecording Audio { get; set; } -} - -public sealed class MixRecording -{ - /// - /// Gets or sets the size of the MP4 recording (in bytes). - /// The MP4 recording is available only if you have requested the MP4 format in the recording settings. - /// For more information, see the Recording document. - /// - [JsonProperty("mp4")] - public long Mp4 { get; set; } - - /// - /// Gets or sets the size of the MP3 recording (in bytes). - /// The MP3 recording is available only if you have requested the MP3 format in the recording settings. - /// For more information, see the Recording document. - /// - [JsonProperty("mp3")] - public long Mp3 { get; set; } - - /// - /// Gets or sets the region code in which the mix recording took place. - /// - [JsonProperty("region")] - public string Region { get; set; } -} - -public sealed class RecordingFile -{ - /// - /// Gets or sets the time when the conference started, in milliseconds since epoch. - /// - [JsonProperty("startTime")] - public long StartTime { get; set; } - - /// - /// Gets or sets the estimated duration of the recording. - /// - [JsonProperty("duration")] - public long Duration { get; set; } - - /// - /// Gets or sets the size of the recording (in bytes). - /// - [JsonProperty("size")] - public long Size { get; set; } - - /// - /// Gets or sets the unique name of the recording file. - /// - [JsonProperty("fileName")] - public string FileName { get; set; } - - /// - /// Gets or sets the presigned URL, with limited validity, where you can download the recording file with a GET. - /// The URL only applies when accessing specific audio recording data. - /// - [JsonProperty("url")] - public string Url { get; set; } - - /// - /// Gets or sets the list of split audio recordings. - /// - [JsonProperty("splits")] - public IEnumerable Splits { get; set; } -} - -public sealed class AudioRecording -{ - /// - /// Gets or sets the region code in which the mix recording took place. - /// - [JsonProperty("region")] - public string Region { get; set; } - - /// - /// Gets or sets the list of audio recordings. - /// - [JsonProperty("records")] - public IEnumerable Records { get; set; } -} - -public sealed class GetRecordingsResponse : PagedResponse -{ - /// - /// Gets or sets the list of recordings. - /// - [JsonProperty("recordings")] - public IEnumerable Recordings { get; set; } -} - -public sealed class ConferenceDetails -{ - /// - /// Gets or sets the conference identifier. - /// - [JsonProperty("confId")] - public string Id { get; set; } - - /// - /// Gets or sets the conference alias, provided by the customer. - /// - [JsonProperty("confAlias")] - public string Alias { get; set; } -} - -public sealed class DolbyVoiceRecording -{ - /// - /// Gets or sets the region code in which the mix recording took place. - /// - [JsonProperty("region")] - public string Region { get; set; } - - /// - /// Gets or sets the conference details. - /// - [JsonProperty("conference")] - public ConferenceDetails Conference { get; set; } - - /// - /// Gets or sets the list of audio recordings. - /// - [JsonProperty("records")] - public IEnumerable Records { get; set; } -} diff --git a/DolbyIO.Rest/Communications/Models/Monitoring.Webhooks.cs b/DolbyIO.Rest/Communications/Models/Monitoring.Webhooks.cs deleted file mode 100644 index 3d5183f..0000000 --- a/DolbyIO.Rest/Communications/Models/Monitoring.Webhooks.cs +++ /dev/null @@ -1,101 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace DolbyIO.Rest.Communications.Models; - -public sealed class GetWebhooksOptions : PagedOptions -{ - /// - /// Gets or sets the identifier of the conference. - /// - public string ConferenceId { get; set; } - - /// - /// Gets or sets the Webhook event type or an expression of its type (for example `Recording.Live.InProgress` or `Rec.*`). - /// The default value of the type parameter returns all types of Webhooks. - /// - public string Type { get; set; } -} - -public sealed class GetAllWebhooksOptions : AllElementsOptions -{ - /// - /// Gets or sets the identifier of the conference. - /// - public string ConferenceId { get; set; } - - /// - /// Gets or sets the Webhook event type or an expression of its type (for example `Recording.Live.InProgress` or `Rec.*`). - /// The default value of the type parameter returns all types of Webhooks. - /// - public string Type { get; set; } -} - -public sealed class WebHook -{ - /// - /// Gets or sets the ID for the webhook event. - /// - [JsonProperty("id")] - public string Id { get; set; } - - /// - /// Gets or sets the string encoding the webhook JSON body. - /// - [JsonProperty("webhook")] - public string Webhook { get; set; } - - /// - /// Gets or sets the URL (configured on the developer portal) to which the webhook is sent. - /// - [JsonProperty("url")] - public string Url { get; set; } - - /// - /// Gets or sets the ID of the conference that emitted the webhook event. - /// - [JsonProperty("confId")] - public string ConferenceId { get; set; } - - /// - /// Gets or sets the app key of the application associated with the conference that emitted the webhook. - /// - [JsonProperty("thirdPartyId")] - public string AppKey { get; set; } - - /// - /// Gets or sets the epoch time of the webhook event. - /// - [JsonProperty("ts")] - public string Ts { get; set; } - - /// - /// Gets or sets the response from the endpoint at which the webhook event is posted. - /// - [JsonProperty("response")] - public WebHookResponse Response { get; set; } -} - -public sealed class WebHookResponse -{ - /// - /// Gets or sets the HTTP status code and the returned string after posting the webhook (for example "200 OK"). - /// - [JsonProperty("status")] - public string Status { get; set; } - - /// - /// Gets or sets the key - a value of the map of headers of the endpoint response returned after posting the webhook. - /// - [JsonProperty("headers")] - public object Headers { get; set; } -} - -public sealed class GetWebHookResponse : PagedResponse -{ - /// - /// Gets or sets the list of webhooks. - /// - [JsonProperty("webhooks")] - public IEnumerable Webhooks { get; set; } -} diff --git a/DolbyIO.Rest/Communications/Models/Monitoring.cs b/DolbyIO.Rest/Communications/Models/Monitoring.cs deleted file mode 100644 index 2c796f5..0000000 --- a/DolbyIO.Rest/Communications/Models/Monitoring.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace DolbyIO.Rest.Communications.Models; - -public abstract class AllElementsOptions -{ - /// - /// Gets or sets the beginning of the time range (in milliseconds that have elapsed since epoch). - /// - public int? From { get; set; } - - /// - /// Gets or sets the end of the time range (in milliseconds that have elapsed since epoch). - /// - public int? To { get; set; } - - /// - /// Gets or sets the maximum number of elements to return per page. We recommend setting the proper value of this parameter to shorten the response time. - /// - public int? PageSize { get; set; } -} - -public abstract class PagedOptions -{ - /// - /// Gets or sets the beginning of the time range (in milliseconds that have elapsed since epoch). - /// - public int? From { get; set; } - - /// - /// Gets or sets the end of the time range (in milliseconds that have elapsed since epoch). - /// - public int? To { get; set; } - - /// - /// Gets or sets the maximum number of displayed results. We recommend setting the proper value of this parameter to shorten the response time. - /// - public int? Max { get; set; } - - /// - /// Gets or sets when the results span multiple pages, use this option to navigate through pages. By default, only the max number of results is displayed. - /// To see the next results, set the start parameter to the value of the next key returned in the previous response. - /// - public string Start { get; set; } -} - -public abstract class PagedResponse -{ - /// - /// Gets or sets the token representing the first page of displayed results. - /// Use this token as a value of the start parameter to return to the first page of the displayed results. - /// - [JsonProperty("first")] - public string First { get; set; } - - /// - /// Gets or sets the token representing the next page of displayed results. - /// Use this token as a value of the start parameter to access the next page of results. - /// - [JsonProperty("next")] - public string Next { get; set; } -} diff --git a/DolbyIO.Rest/Communications/Models/Recording.cs b/DolbyIO.Rest/Communications/Models/Recording.cs deleted file mode 100644 index a00c8f9..0000000 --- a/DolbyIO.Rest/Communications/Models/Recording.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Newtonsoft.Json; - -namespace DolbyIO.Rest.Communications.Models; - -internal sealed class StartRecordingRequest -{ - [JsonProperty("layoutUrl")] - public string LayoutUrl { get; set; } -} diff --git a/DolbyIO.Rest/Communications/Models/Remix.cs b/DolbyIO.Rest/Communications/Models/Remix.cs deleted file mode 100644 index 583c1d1..0000000 --- a/DolbyIO.Rest/Communications/Models/Remix.cs +++ /dev/null @@ -1,41 +0,0 @@ -using Newtonsoft.Json; - -namespace DolbyIO.Rest.Communications.Models; - -public sealed class RemixStatus -{ - /// - /// Gets or sets the status of the current remix job. - /// - /// - /// The possible values are: - /// - /// - /// UNKNOWN - /// - /// - /// ERROR - /// - /// - /// IN_PROGRESS - /// - /// - /// COMPLETED - /// - /// - /// - [JsonProperty("status")] - public string Status { get; set; } - - /// - /// Gets or sets the two-letter code identifying the region where the conference is hosted. - /// - [JsonProperty("region")] - public string Region { get; set; } - - /// - /// Gets or sets the conference alias, provided by the customer as a way to identify one or more conferences. - /// - [JsonProperty("alias")] - public string Alias { get; set; } -} diff --git a/DolbyIO.Rest/Communications/Models/Streaming.cs b/DolbyIO.Rest/Communications/Models/Streaming.cs deleted file mode 100644 index 63edbdb..0000000 --- a/DolbyIO.Rest/Communications/Models/Streaming.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace DolbyIO.Rest.Communications.Models; - -internal sealed class StartRtmpRequest -{ - [JsonProperty("uri")] - public string Uri { get; set; } - - [JsonProperty("layoutUrl")] - public string LayoutUrl { get; set; } - - [JsonProperty("layoutName")] - public string LayoutName { get; set; } -} - -internal sealed class StartRtsRequest -{ - [JsonProperty("streamName")] - public string StreamName { get; set; } - - [JsonProperty("publishingToken")] - public string PublishingToken { get; set; } - - [JsonProperty("layoutUrl")] - public string LayoutUrl { get; set; } - - [JsonProperty("layoutName")] - public string LayoutName { get; set; } -} diff --git a/DolbyIO.Rest/Communications/Monitor/Conferences.cs b/DolbyIO.Rest/Communications/Monitor/Conferences.cs deleted file mode 100644 index f006d2b..0000000 --- a/DolbyIO.Rest/Communications/Monitor/Conferences.cs +++ /dev/null @@ -1,196 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Net.Http; -using System.Threading.Tasks; -using DolbyIO.Rest.Communications.Models; -using DolbyIO.Rest.Models; - -namespace DolbyIO.Rest.Communications.Monitor; - -public sealed class Conferences -{ - private readonly HttpClient _httpClient; - - internal Conferences(HttpClient httpClient) - { - _httpClient = httpClient; - } - - /// - /// Get a list of conferences that were started in a specific time range, including ongoing conferences.
- /// Note: Only terminated conferences include a complete summary.
- /// The summary of ongoing conferences includes the following fields in the response: - /// confId, alias, region, dolbyVoice, start, live, owner.
- /// See: - ///
- /// Access token to use for authentication. - /// Options to request the conferences. - /// The property returns the object. - public async Task ListConferencesAsync(JwtToken accessToken, ListConferencesOptions options) - { - var uriBuilder = new UriBuilder(Urls.CAPI_BASE_URL); - uriBuilder.Path = "/v1/monitor/conferences"; - - var nvc = new NameValueCollection(); - nvc.Add("from", (options.From ?? 0).ToString()); - nvc.Add("to", (options.To ?? 9999999999999).ToString()); - nvc.Add("max", (options.Max ?? 100).ToString()); - nvc.Add("active", options.Active.ToString()); - nvc.Add("livestats", options.LiveStats.ToString()); - if (!string.IsNullOrWhiteSpace(options.Start)) - nvc.Add("start", options.Start); - if (!string.IsNullOrWhiteSpace(options.Alias)) - nvc.Add("alias", options.Alias); - if (!string.IsNullOrWhiteSpace(options.ExternalId)) - nvc.Add("exid", options.ExternalId); - - uriBuilder.Query = nvc.ToString(); - - return await _httpClient.SendPostAsync(uriBuilder.Uri.ToString(), accessToken); - } - - /// - /// Get a list of all the conferences that were started in a specific time range, including ongoing conferences.
- /// Note: Only terminated conferences include a complete summary.
- /// The summary of ongoing conferences includes the following fields in the response: - /// confId, alias, region, dolbyVoice, start, live, owner.
- /// See: - ///
- /// Access token to use for authentication. - /// Options to request the conferences. - /// The property returns the list of objects. - public async Task> ListAllConferencesAsync(JwtToken accessToken, ListAllConferencesOptions options) - { - var uriBuilder = new UriBuilder(Urls.CAPI_BASE_URL); - uriBuilder.Path = "/v1/monitor/conferences"; - - var nvc = new NameValueCollection(); - nvc.Add("from", (options.From ?? 0).ToString()); - nvc.Add("to", (options.To ?? 9999999999999).ToString()); - nvc.Add("max", (options.PageSize ?? 100).ToString()); - nvc.Add("active", options.Active.ToString()); - nvc.Add("livestats", options.LiveStats.ToString()); - if (!string.IsNullOrWhiteSpace(options.Alias)) - nvc.Add("alias", options.Alias); - if (!string.IsNullOrWhiteSpace(options.ExternalId)) - nvc.Add("exid", options.ExternalId); - - uriBuilder.Query = nvc.ToString(); - - List result = new List(); - - ListConferencesResponse response; - do - { - response = await _httpClient.SendPostAsync(uriBuilder.Uri.ToString(), accessToken); - result.AddRange(response.Conferences); - - nvc.Add("start", response.Next); - uriBuilder.Query = nvc.ToString(); - } while (!string.IsNullOrWhiteSpace(response.Next)); - - return result; - } - - /// - /// Get a summary of a conference.
- /// Note: Only terminated conferences include a complete summary.
- /// The summary of ongoing conferences includes the following fields in the response: - /// confId, alias, region, dolbyVoice, start, live, owner.
- /// See: - ///
- /// Access token to use for authentication. - /// The conference identifier. - /// For live conferences, the number of `user`, `listener`, and `pstn` participants. - /// The property returns the object. - public async Task GetConferenceAsync(JwtToken accessToken, string conferenceId, bool liveStats = false) - { - string url = $"{Urls.CAPI_BASE_URL}/v1/monitor/conferences/${conferenceId}?livestats=${liveStats}"; - return await _httpClient.SendGetAsync(url, accessToken); - } - - /// - /// Get statistics of a terminated conference. - /// The statistics include the maximum number of participants present during a conference - /// and the maximum number of the transmitted and received packets, bytes, and streams. - /// Note: Only terminated conferences include a complete summary.
- /// See: - ///
- /// Access token to use for authentication. - /// The conference identifier. - /// The property returns the object. - public async Task GetConferenceStatisticsAsync(JwtToken accessToken, string conferenceId) - { - string url = $"{Urls.CAPI_BASE_URL}/v1/monitor/conferences/${conferenceId}/statistics"; - return await _httpClient.SendGetAsync(url, accessToken); - } - - /// - /// Get statistics and connection details of all participants in a conference. - /// Optionally limit the search result with a specific time range.
- /// See: - ///
- /// Access token to use for authentication. - /// Options to request the conference participants. - /// The property returns the object. - public async Task GetConferenceParticipantsAsync(JwtToken accessToken, GetConferenceParticipantsOptions options) - { - var uriBuilder = new UriBuilder(Urls.CAPI_BASE_URL); - uriBuilder.Path = $"/v1/monitor/conferences/{options.ConferenceId}/participants"; - if (!string.IsNullOrWhiteSpace(options.UserId)) - uriBuilder.Path += $"/{options.UserId}"; - - var nvc = new NameValueCollection(); - nvc.Add("from", (options.From ?? 0).ToString()); - nvc.Add("to", (options.To ?? 9999999999999).ToString()); - nvc.Add("max", (options.Max ?? 100).ToString()); - if (!string.IsNullOrWhiteSpace(options.Type)) - nvc.Add("type", options.Type); - if (!string.IsNullOrWhiteSpace(options.Start)) - nvc.Add("start", options.Start); - - uriBuilder.Query = nvc.ToString(); - - return await _httpClient.SendPostAsync(uriBuilder.Uri.ToString(), accessToken); - } - - /// - /// Get statistics and connection details of all participants in a conference. - /// Optionally limit the search result with a specific time range.
- /// See: - ///
- /// Access token to use for authentication. - /// Options to request the conference participants. - /// The property returns the list of objects. - public async Task> GetAllConferenceParticipantsAsync(JwtToken accessToken, GetAllConferenceParticipantsOptions options) - { - var uriBuilder = new UriBuilder(Urls.CAPI_BASE_URL); - uriBuilder.Path = $"/v1/monitor/conferences/{options.ConferenceId}/participants"; - if (!string.IsNullOrWhiteSpace(options.UserId)) - uriBuilder.Path += $"/{options.UserId}"; - - var nvc = new NameValueCollection(); - nvc.Add("from", (options.From ?? 0).ToString()); - nvc.Add("to", (options.To ?? 9999999999999).ToString()); - nvc.Add("max", (options.PageSize ?? 100).ToString()); - if (!string.IsNullOrWhiteSpace(options.Type)) - nvc.Add("type", options.Type); - - uriBuilder.Query = nvc.ToString(); - - List result = new List(); - - GetConferenceParticipantsResponse response; - do - { - response = await _httpClient.SendPostAsync(uriBuilder.Uri.ToString(), accessToken); - result.AddRange(response.Participants.Values); - - nvc.Add("start", response.Next); - uriBuilder.Query = nvc.ToString(); - } while (!string.IsNullOrWhiteSpace(response.Next)); - - return result; - } -} diff --git a/DolbyIO.Rest/Communications/Monitor/Monitoring.cs b/DolbyIO.Rest/Communications/Monitor/Monitoring.cs deleted file mode 100644 index 3b4c9d2..0000000 --- a/DolbyIO.Rest/Communications/Monitor/Monitoring.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Net.Http; - -namespace DolbyIO.Rest.Communications.Monitor; - -public sealed class Monitoring -{ - public Conferences Conferences { get; } - - public Recordings Recordings { get; } - - public Webhooks Webhooks { get; } - - internal Monitoring(HttpClient httpClient) - { - Conferences = new Conferences(httpClient); - Recordings = new Recordings(httpClient); - Webhooks = new Webhooks(httpClient); - } -} diff --git a/DolbyIO.Rest/Communications/Monitor/Recordings.cs b/DolbyIO.Rest/Communications/Monitor/Recordings.cs deleted file mode 100644 index df18f2d..0000000 --- a/DolbyIO.Rest/Communications/Monitor/Recordings.cs +++ /dev/null @@ -1,136 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Net.Http; -using System.Threading.Tasks; -using DolbyIO.Rest.Communications.Models; -using DolbyIO.Rest.Models; - -namespace DolbyIO.Rest.Communications.Monitor; - -public sealed class Recordings -{ - private readonly HttpClient _httpClient; - - internal Recordings(HttpClient httpClient) - { - _httpClient = httpClient; - } - - /// - /// Get a list of the recorded conference metadata, such as duration or size of the recording. - /// This API checks only the recordings that have ended during a specific time range. - /// Recordings are indexed based on the ending time.
- /// See: - ///
- /// Access token to use for authentication. - /// Options to request the recordings. - /// The property returns the object. - public async Task GetRecordingsAsync(JwtToken accessToken, GetRecordingsOptions options) - { - var uriBuilder = new UriBuilder(Urls.CAPI_BASE_URL); - uriBuilder.Path = "/v1/monitor/recordings"; - - var nvc = new NameValueCollection(); - nvc.Add("from", (options.From ?? 0).ToString()); - nvc.Add("to", (options.To ?? 9999999999999).ToString()); - nvc.Add("max", (options.Max ?? 100).ToString()); - if (!string.IsNullOrWhiteSpace(options.Start)) - nvc.Add("start", options.Start); - - uriBuilder.Query = nvc.ToString(); - - return await _httpClient.SendPostAsync(uriBuilder.Uri.ToString(), accessToken); - } - - /// - /// Get a list of the recorded conference metadata, such as duration or size of the recording. - /// This API checks only the recordings that have ended during a specific time range. - /// Recordings are indexed based on the ending time.
- /// See: - ///
- /// Access token to use for authentication. - /// Options to request the recordings. - /// The property returns the list of objects. - public async Task> GetAllRecordingsAsync(JwtToken accessToken, GetAllRecordingsOptions options) - { - var uriBuilder = new UriBuilder(Urls.CAPI_BASE_URL); - uriBuilder.Path = "/v1/monitor/recordings"; - - var nvc = new NameValueCollection(); - nvc.Add("from", (options.From ?? 0).ToString()); - nvc.Add("to", (options.To ?? 9999999999999).ToString()); - nvc.Add("max", (options.PageSize ?? 100).ToString()); - - uriBuilder.Query = nvc.ToString(); - - List result = new List(); - - GetRecordingsResponse response; - do - { - response = await _httpClient.SendPostAsync(uriBuilder.Uri.ToString(), accessToken); - result.AddRange(response.Recordings); - - nvc.Add("start", response.Next); - uriBuilder.Query = nvc.ToString(); - } while (!string.IsNullOrWhiteSpace(response.Next)); - - return result; - } - - /// - /// Get a list of the recorded conference metadata, such as duration or size of the recording. - /// This API checks the recordings that have ended during a specific time range. - /// Recordings are indexed based on the ending time.
- /// See: - ///
- /// Access token to use for authentication. - /// Options to request the recording. - /// The property returns the list of objects. - public async Task> GetRecordingAsync(JwtToken accessToken, GetRecordingOptions options) - { - var uriBuilder = new UriBuilder(Urls.CAPI_BASE_URL); - uriBuilder.Path = $"/v1/monitor/conferences/{options.ConferenceId}/recordings"; - - var nvc = new NameValueCollection(); - nvc.Add("from", (options.From ?? 0).ToString()); - nvc.Add("to", (options.To ?? 9999999999999).ToString()); - nvc.Add("max", (options.Max ?? 100).ToString()); - if (!string.IsNullOrWhiteSpace(options.Start)) - nvc.Add("start", options.Start); - - uriBuilder.Query = nvc.ToString(); - - GetRecordingsResponse response = await _httpClient.SendPostAsync(uriBuilder.Uri.ToString(), accessToken); - return response.Recordings; - } - - /// - /// Delete all recording data related to a specific conference.
- /// Warning: After deleting the recording, it is not possible to restore the recording data.
- /// See: - ///
- /// Access token to use for authentication. - /// Identifier of the conference. - /// A that represents the asynchronous operation. - public async Task DeleteRecordingAsync(JwtToken accessToken, string conferenceId) - { - string url = $"{Urls.CAPI_BASE_URL}/v1/monitor/conferences/{conferenceId}/recordings"; - await _httpClient.SendDeleteAsync(url, accessToken); - } - - /// - /// Get details of all Dolby Voice-based audio recordings, and associated split recordings, - /// for a given conference and download the conference recording in the MP3 audio format.
- /// See: - ///
- /// Access token to use for authentication. - /// Identifier of the conference. - /// The property returns the object. - public async Task GetDolbyVoiceRecordingAsync(JwtToken accessToken, string conferenceId) - { - string url = $"{Urls.CAPI_BASE_URL}/v1/monitor/conferences/{conferenceId}/recordings/audio"; - return await _httpClient.SendGetAsync(url, accessToken); - } -} diff --git a/DolbyIO.Rest/Communications/Monitor/Webhooks.cs b/DolbyIO.Rest/Communications/Monitor/Webhooks.cs deleted file mode 100644 index 3700f53..0000000 --- a/DolbyIO.Rest/Communications/Monitor/Webhooks.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Net.Http; -using System.Threading.Tasks; -using DolbyIO.Rest.Communications.Models; -using DolbyIO.Rest.Models; - -namespace DolbyIO.Rest.Communications.Monitor; - -public sealed class Webhooks -{ - private readonly HttpClient _httpClient; - - internal Webhooks(HttpClient httpClient) - { - _httpClient = httpClient; - } - - /// - /// Gets a list of Webhook events sent, during a specific time range. - /// The list includes associated endpoint response codes and headers.
- /// See: - ///
- /// Access token to use for authentication. - /// Options to request the webhooks. - /// The property returns the object. - public async Task GetEventsAsync(JwtToken accessToken, GetWebhooksOptions options) - { - var uriBuilder = new UriBuilder(Urls.CAPI_BASE_URL); - - uriBuilder.Path = "/v1/monitor/"; - if (!string.IsNullOrWhiteSpace(options.ConferenceId)) - uriBuilder.Path += $"conferences/{options.ConferenceId}/"; - uriBuilder.Path += "webhooks"; - - var nvc = new NameValueCollection(); - nvc.Add("from", (options.From ?? 0).ToString()); - nvc.Add("to", (options.To ?? 9999999999999).ToString()); - nvc.Add("max", (options.Max ?? 100).ToString()); - if (!string.IsNullOrWhiteSpace(options.Type)) - nvc.Add("type", options.Type); - if (!string.IsNullOrWhiteSpace(options.Start)) - nvc.Add("start", options.Start); - - uriBuilder.Query = nvc.ToString(); - - return await _httpClient.SendPostAsync(uriBuilder.Uri.ToString(), accessToken); - } - - /// - /// Gets a list of all Webhook events sent, during a specific time range. - /// The list includes associated endpoint response codes and headers.
- /// See: - ///
- /// Access token to use for authentication. - /// Options to request the webhooks. - /// The property returns the list of objects. - public async Task> GetAllEventsAsync(JwtToken accessToken, GetAllWebhooksOptions options) - { - var uriBuilder = new UriBuilder(Urls.CAPI_BASE_URL); - - uriBuilder.Path = "/v1/monitor/"; - if (!string.IsNullOrWhiteSpace(options.ConferenceId)) - uriBuilder.Path += $"conferences/{options.ConferenceId}/"; - uriBuilder.Path += "webhooks"; - - var nvc = new NameValueCollection(); - nvc.Add("from", (options.From ?? 0).ToString()); - nvc.Add("to", (options.To ?? 9999999999999).ToString()); - nvc.Add("max", (options.PageSize ?? 100).ToString()); - if (!string.IsNullOrWhiteSpace(options.Type)) - nvc.Add("type", options.Type); - - uriBuilder.Query = nvc.ToString(); - - List result = new List(); - - GetWebHookResponse response; - do - { - response = await _httpClient.SendPostAsync(uriBuilder.Uri.ToString(), accessToken); - result.AddRange(response.Webhooks); - - nvc.Add("start", response.Next); - uriBuilder.Query = nvc.ToString(); - } while (!string.IsNullOrWhiteSpace(response.Next)); - - return result; - } -} diff --git a/DolbyIO.Rest/Communications/Recording.cs b/DolbyIO.Rest/Communications/Recording.cs deleted file mode 100644 index 07534ec..0000000 --- a/DolbyIO.Rest/Communications/Recording.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System.Net.Http; -using System.Threading.Tasks; -using DolbyIO.Rest.Communications.Models; -using DolbyIO.Rest.Models; - -namespace DolbyIO.Rest.Communications; - -public sealed class Recording -{ - private readonly HttpClient _httpClient; - - internal Recording(HttpClient httpClient) - { - _httpClient = httpClient; - } - - /// - /// Starts recording for the specified conference. - /// You can specify a custom layout URL per recording request. - /// The layoutURL parameter overrides the layout URL configured in the dashboard.
- /// See: - ///
- /// Access token to use for authentication. - /// Identifier of the conference. - /// - /// Overwrites the layout URL configuration. - /// This field is ignored if it is not relevant regarding recording configuration, - /// for example if live_recording set to false or if the recording is MP3 only. - /// - /// - /// null - /// uses the layout URL configured in the dashboard (if no URL is set in the dashboard, then uses the Dolby.io default). - /// - /// - /// default - /// uses the Dolby.io default layout. - /// - /// - /// URL string - /// uses this layout URL. - /// - /// - /// - /// A that represents the asynchronous operation. - public async Task StartAsync(JwtToken accessToken, string conferenceId, string layoutUrl = null) - { - var requestObject = new StartRecordingRequest { LayoutUrl = layoutUrl }; - - string url = $"{Urls.CAPI_BASE_URL}/v2/conferences/mix/{conferenceId}/recording/start"; - await _httpClient.SendPostAsync(url, accessToken, requestObject); - } - - /// - /// Stops the recording of the specified conference.
- /// See: - ///
- /// Access token to use for authentication. - /// Identifier of the conference. - /// A that represents the asynchronous operation. - public async Task StopAsync(JwtToken accessToken, string conferenceId) - { - string url = $"{Urls.CAPI_BASE_URL}/v2/conferences/mix/{conferenceId}/recording/stop"; - await _httpClient.SendPostAsync(url, accessToken); - } -} diff --git a/DolbyIO.Rest/Communications/Remix.cs b/DolbyIO.Rest/Communications/Remix.cs deleted file mode 100644 index 7b84e63..0000000 --- a/DolbyIO.Rest/Communications/Remix.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System.Net.Http; -using System.Threading.Tasks; -using DolbyIO.Rest.Communications.Models; -using DolbyIO.Rest.Models; - -namespace DolbyIO.Rest.Communications; - -public sealed class Remix -{ - private readonly HttpClient _httpClient; - - internal Remix(HttpClient httpClient) - { - _httpClient = httpClient; - } - - /// - /// Creates a conference.
- /// See: - ///
- /// Access token to use for authentication. - /// Identifier of the conference. - /// - /// Overwrites the layout URL configuration: - /// - /// - /// null - /// uses the layout URL configured in the dashboard (if no URL is set in the dashboard, then uses the Dolby.io default). - /// - /// - /// default - /// uses the Dolby.io default layout. - /// - /// - /// URL string - /// uses this layout URL. - /// - /// - /// - /// Defines a name for the given layout URL, which makes layout identification easier for customers especially when the layout URL is not explicit. - /// The property returns the object. - public async Task StartAsync(JwtToken accessToken, string conferenceId, string layoutUrl = null, string layoutName = null) - { - var body = new { - layoutUrl = layoutUrl, - layoutName = layoutName - }; - string url = $"{Urls.CAPI_BASE_URL}/v2/conferences/mix/{conferenceId}/remix/start"; - return await _httpClient.SendPostAsync(url, accessToken, body); - } - - /// - /// Gets the status of a current mixing job.
- /// See: - ///
- /// Access token to use for authentication. - /// Identifier of the conference. - /// The property returns the object. - public async Task GetStatusAsync(JwtToken accessToken, string conferenceId) - { - string url = $"{Urls.CAPI_BASE_URL}/v2/conferences/mix/{conferenceId}/remix/start"; - return await _httpClient.SendGetAsync(url, accessToken); - } -} diff --git a/DolbyIO.Rest/Communications/Streaming.cs b/DolbyIO.Rest/Communications/Streaming.cs deleted file mode 100644 index a86560b..0000000 --- a/DolbyIO.Rest/Communications/Streaming.cs +++ /dev/null @@ -1,125 +0,0 @@ -using System.Collections.Generic; -using System.Net.Http; -using System.Threading.Tasks; -using DolbyIO.Rest.Communications.Models; -using DolbyIO.Rest.Models; - -namespace DolbyIO.Rest.Communications; - -public sealed class Streaming -{ - private readonly HttpClient _httpClient; - - internal Streaming(HttpClient httpClient) - { - _httpClient = httpClient; - } - - /// - /// Starts the RTMP live stream for the specified conference. - /// Once the Dolby.io Communication API service started streaming to the target url, - /// a Stream.Rtmp.InProgress Webhook event will be sent.
- /// See: - ///
- /// Access token to use for authentication. - /// Identifier of the conference. - /// RTMP endpoint where to send the RTMP stream to. - /// - /// Overwrites the layout URL configuration: - /// - /// - /// null - /// uses the layout URL configured in the dashboard (if no URL is set in the dashboard, then uses the Dolby.io default). - /// - /// - /// default - /// uses the Dolby.io default layout. - /// - /// - /// URL string - /// uses this layout URL. - /// - /// - /// - /// Defines a name for the given layout URL, which makes layout identification easier for customers especially when the layout URL is not explicit. - /// A that represents the asynchronous operation. - public async Task StartRtmpAsync(JwtToken accessToken, string conferenceId, string rtmpUrl, string layoutUrl = null, string layoutName = null) - { - var requestObject = new StartRtmpRequest - { - Uri = rtmpUrl, - LayoutUrl = layoutUrl, - LayoutName = layoutName - }; - - string url = $"{Urls.CAPI_BASE_URL}/v2/conferences/mix/{conferenceId}/rtmp/start"; - await _httpClient.SendPostAsync(url, accessToken, requestObject); - } - - /// - /// Stops the RTMP stream of the specified conference.
- /// See: - ///
- /// Access token to use for authentication. - /// Identifier of the conference. - /// A that represents the asynchronous operation. - public async Task StopRtmpAsync(JwtToken accessToken, string conferenceId) - { - string url = $"{Urls.CAPI_BASE_URL}/v2/conferences/mix/{conferenceId}/rtmp/stop"; - await _httpClient.SendPostAsync(url, accessToken); - } - - /// - /// Starts real-time streaming using Dolby.io Real-time Streaming services (formerly Millicast).
- /// See: - ///
- /// Access token to use for authentication. - /// Identifier of the conference. - /// - /// - /// - /// Overwrites the layout URL configuration: - /// - /// - /// null - /// uses the layout URL configured in the dashboard (if no URL is set in the dashboard, then uses the Dolby.io default). - /// - /// - /// default - /// uses the Dolby.io default layout. - /// - /// - /// URL string - /// uses this layout URL. - /// - /// - /// - /// Defines a name for the given layout URL, which makes layout identification easier for customers especially when the layout URL is not explicit. - /// A that represents the asynchronous operation. - public async Task StartRtsAsync(JwtToken accessToken, string conferenceId, string streamName, string publishingToken, string layoutUrl = null, string layoutName = null) - { - var requestObject = new StartRtsRequest - { - StreamName = streamName, - PublishingToken = publishingToken, - LayoutUrl = layoutUrl, - LayoutName = layoutName - }; - - string url = $"{Urls.CAPI_BASE_URL}/v2/conferences/mix/{conferenceId}/rts/start"; - await _httpClient.SendPostAsync(url, accessToken, requestObject); - } - - /// - /// Stops real-time streaming to Dolby.io Real-time Streaming services.
- /// See: - ///
- /// Access token to use for authentication. - /// Identifier of the conference. - /// A that represents the asynchronous operation. - public async Task StopRtsAsync(JwtToken accessToken, string conferenceId) - { - string url = $"{Urls.CAPI_BASE_URL}/v2/conferences/mix/{conferenceId}/rts/stop"; - await _httpClient.SendPostAsync(url, accessToken); - } -} diff --git a/DolbyIO.Rest/DolbyIO.Rest.csproj b/DolbyIO.Rest/DolbyIO.Rest.csproj index ed68b36..1f75e8a 100644 --- a/DolbyIO.Rest/DolbyIO.Rest.csproj +++ b/DolbyIO.Rest/DolbyIO.Rest.csproj @@ -6,8 +6,8 @@ Fabien Lavocat Dolby.io Dolby.io REST APIs Client for .NET - .NET wrapper for the dolby.io REST Communications and Media APIs. - .NET wrapper for the dolby.io REST Communications and Media APIs. + .NET wrapper for the Dolby Millicast and Media APIs. + .NET wrapper for the Dolby Millicast and Media APIs. DolbyIO.Rest README.md LICENSE diff --git a/DolbyIO.Rest/DolbyIOClient.cs b/DolbyIO.Rest/DolbyIOClient.cs index 8d8b13c..8a566ba 100644 --- a/DolbyIO.Rest/DolbyIOClient.cs +++ b/DolbyIO.Rest/DolbyIOClient.cs @@ -1,6 +1,5 @@ using System; using System.Net.Http; -using DolbyIO.Rest.Communications; using DolbyIO.Rest.Media; using DolbyIO.Rest.Streaming; @@ -10,10 +9,6 @@ public sealed class DolbyIOClient : IDisposable { private readonly HttpClient _httpClient; - public Authentication Authentication { get; } - - public Capi Communications { get; } - public Mapi Media { get; } public Sapi Streaming { get; } @@ -27,8 +22,6 @@ internal DolbyIOClient(HttpClient httpClient) { _httpClient = httpClient; - Authentication = new Authentication(_httpClient); - Communications = new Capi(_httpClient); Media = new Mapi(_httpClient); Streaming = new Sapi(_httpClient); } diff --git a/DolbyIO.Rest/Internal/Extensions.cs b/DolbyIO.Rest/Internal/Extensions.cs index 405ea4f..b7540ef 100644 --- a/DolbyIO.Rest/Internal/Extensions.cs +++ b/DolbyIO.Rest/Internal/Extensions.cs @@ -1,15 +1,15 @@ -using System; +using System; using System.Net.Http; using System.Net.Http.Headers; using System.Reflection; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; -using DolbyIO.Rest.Models; +using DolbyIO.Rest.Media.Models; using Newtonsoft.Json; namespace DolbyIO.Rest; - + internal static class Extensions { public static async Task SendPostAsync(this HttpClient httpClient, string url, JwtToken accessToken, string content = "{}") diff --git a/DolbyIO.Rest/Media/Analyze.cs b/DolbyIO.Rest/Media/Analyze.cs index 875f66f..c023d04 100644 --- a/DolbyIO.Rest/Media/Analyze.cs +++ b/DolbyIO.Rest/Media/Analyze.cs @@ -1,7 +1,6 @@ using System.Net.Http; using System.Threading.Tasks; using DolbyIO.Rest.Media.Models; -using DolbyIO.Rest.Models; namespace DolbyIO.Rest.Media; @@ -22,10 +21,6 @@ internal Analyze(HttpClient httpClient) /// See: /// /// - /// Beta API
- /// This API is being made available as an early preview. - /// If you have feedback on how you'd like to use the API please reach out to share your feedback with our team. - ///
/// Content Length - Media content with duration less than 2 seconds will not be processed.The API will return an ERROR in this case. ///
/// Access token to use for authentication. diff --git a/DolbyIO.Rest/Media/AnalyzeMusic.cs b/DolbyIO.Rest/Media/AnalyzeMusic.cs index 83afbd7..f3de6a8 100644 --- a/DolbyIO.Rest/Media/AnalyzeMusic.cs +++ b/DolbyIO.Rest/Media/AnalyzeMusic.cs @@ -1,7 +1,6 @@ using System.Net.Http; using System.Threading.Tasks; using DolbyIO.Rest.Media.Models; -using DolbyIO.Rest.Models; namespace DolbyIO.Rest.Media; @@ -20,12 +19,6 @@ internal AnalyzeMusic(HttpClient httpClient) /// This is an asynchronous operation so you will receive a job identifier to be used to get the job status and result. /// See: /// - /// - /// Beta API
- /// This API is being made available as an early preview. - /// If you have feedback on how you'd like to use the API please reach out to share your feedback with our team. - ///
- ///
/// Access token to use for authentication. /// Content of the job description as a JSON payload. /// You can find the definition at this URL: diff --git a/DolbyIO.Rest/Media/AnalyzeSpeech.cs b/DolbyIO.Rest/Media/AnalyzeSpeech.cs index c58e0ef..e8d0c49 100644 --- a/DolbyIO.Rest/Media/AnalyzeSpeech.cs +++ b/DolbyIO.Rest/Media/AnalyzeSpeech.cs @@ -1,7 +1,6 @@ using System.Net.Http; using System.Threading.Tasks; using DolbyIO.Rest.Media.Models; -using DolbyIO.Rest.Models; namespace DolbyIO.Rest.Media; @@ -20,12 +19,6 @@ internal AnalyzeSpeech(HttpClient httpClient) /// This is an asynchronous operation so you will receive a job identifier to be used to get the job status and result. /// See: /// - /// - /// Beta API
- /// This API is being made available as an early preview. - /// If you have feedback on how you'd like to use the API please reach out to share your feedback with our team. - ///
- ///
/// Access token to use for authentication. /// Content of the job description as a JSON payload. /// You can find the definition at this URL: diff --git a/DolbyIO.Rest/Media/Authentication.cs b/DolbyIO.Rest/Media/Authentication.cs new file mode 100644 index 0000000..c723e70 --- /dev/null +++ b/DolbyIO.Rest/Media/Authentication.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Text; +using System.Threading.Tasks; +using DolbyIO.Rest.Media.Models; + +namespace DolbyIO.Rest.Media; + +public sealed class Authentication +{ + private readonly HttpClient _httpClient; + + internal Authentication(HttpClient httpClient) + { + _httpClient = httpClient; + } + + /// + /// Generates an API token. + /// To make any API call, you must acquire a JWT (JSON Web Token) format API token.
+ /// See: + ///
+ /// Your Dolby.io App Key. + /// Your Dolby.io App Secret. + /// API token expiration time in seconds. If no value is specified, the default is 1800, indicating 30 minutes. The maximum value is 86,400, indicating 24 hours. + /// The property returns the newly created . + public async Task GetApiAccessTokenAsync(string appKey, string appSecret, int expiresIn = 1800) + { + var nvc = new Dictionary() { + { "grant_type", "client_credentials" }, + { "expires_in", expiresIn.ToString() } + }; + + const string url = Urls.API_BASE_URL + "/v1/auth/token"; + string authz = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{appKey}:{appSecret}")); + + using var request = new HttpRequestMessage(HttpMethod.Post, url); + request.Headers.Authorization = new AuthenticationHeaderValue("Basic", authz); + request.Headers.CacheControl = new CacheControlHeaderValue() { NoCache = true }; + + request.Content = new FormUrlEncodedContent(nvc); + + return await _httpClient.SendAsync(request); + } +} diff --git a/DolbyIO.Rest/Media/Diagnose.cs b/DolbyIO.Rest/Media/Diagnose.cs index 366f8f3..9175481 100644 --- a/DolbyIO.Rest/Media/Diagnose.cs +++ b/DolbyIO.Rest/Media/Diagnose.cs @@ -1,7 +1,6 @@ using System.Net.Http; using System.Threading.Tasks; using DolbyIO.Rest.Media.Models; -using DolbyIO.Rest.Models; namespace DolbyIO.Rest.Media; @@ -20,12 +19,6 @@ internal Diagnose(HttpClient httpClient) /// This is an asynchronous operation so you will receive a job identifier to be used to get the job status and result.
/// See: /// - /// - /// Beta API
- /// This API is being made available as an early preview. - /// If you have feedback on how you'd like to use the API please reach out to share your feedback with our team. - ///
- ///
/// Access token to use for authentication. /// Content of the job description as a JSON payload. /// You can find the definition at this URL: diff --git a/DolbyIO.Rest/Media/Enhance.cs b/DolbyIO.Rest/Media/Enhance.cs index eea3387..641787f 100644 --- a/DolbyIO.Rest/Media/Enhance.cs +++ b/DolbyIO.Rest/Media/Enhance.cs @@ -1,7 +1,6 @@ using System.Net.Http; using System.Threading.Tasks; using DolbyIO.Rest.Media.Models; -using DolbyIO.Rest.Models; using Newtonsoft.Json; namespace DolbyIO.Rest.Media; diff --git a/DolbyIO.Rest/Media/Internal/Extensions.cs b/DolbyIO.Rest/Media/Internal/Extensions.cs index 01c08ab..651acab 100644 --- a/DolbyIO.Rest/Media/Internal/Extensions.cs +++ b/DolbyIO.Rest/Media/Internal/Extensions.cs @@ -3,10 +3,9 @@ using System.Net.Http; using System.Threading.Tasks; using DolbyIO.Rest.Media.Models; -using DolbyIO.Rest.Models; namespace DolbyIO.Rest.Media; - + internal static class Extensions { public static async Task StartJobAsync(this HttpClient httpClient, JwtToken accessToken, string urlPath, string jobDescription) diff --git a/DolbyIO.Rest/Media/Io.cs b/DolbyIO.Rest/Media/Io.cs index 9155c9f..b12ffdb 100644 --- a/DolbyIO.Rest/Media/Io.cs +++ b/DolbyIO.Rest/Media/Io.cs @@ -1,10 +1,9 @@ using System.Net.Http; using System.Threading.Tasks; using DolbyIO.Rest.Media.Models; -using DolbyIO.Rest.Models; namespace DolbyIO.Rest.Media; - + public sealed class Io { private readonly HttpClient _httpClient; @@ -31,7 +30,7 @@ internal Io(HttpClient httpClient) public async Task GetUploadUrlAsync(JwtToken accessToken, string dlbUrl) { var body = new { url = dlbUrl }; - const string requestUrl = Urls.CAPI_BASE_URL + "/media/input"; + const string requestUrl = Urls.MAPI_BASE_URL + "/media/input"; GetUploadUrlResponse result = await _httpClient.SendPostAsync(requestUrl, accessToken, body); return result.Url; } @@ -48,7 +47,7 @@ public async Task GetUploadUrlAsync(JwtToken accessToken, string dlbUrl) public async Task GetDownloadUrlAsync(JwtToken accessToken, string dlbUrl) { var body = new { url = dlbUrl }; - const string requestUrl = Urls.CAPI_BASE_URL + "/media/output"; + const string requestUrl = Urls.MAPI_BASE_URL + "/media/output"; GetDownloadUrlResponse result = await _httpClient.SendPostAsync(requestUrl, accessToken, body); return result.Url; } diff --git a/DolbyIO.Rest/Media/Jobs.cs b/DolbyIO.Rest/Media/Jobs.cs index 2337c2d..2f9b578 100644 --- a/DolbyIO.Rest/Media/Jobs.cs +++ b/DolbyIO.Rest/Media/Jobs.cs @@ -1,10 +1,9 @@ -using System; +using System; using System.Collections.Generic; -using System.Collections.Specialized; +using System.Collections.Specialized; using System.Net.Http; using System.Threading.Tasks; using DolbyIO.Rest.Media.Models; -using DolbyIO.Rest.Models; namespace DolbyIO.Rest.Media; diff --git a/DolbyIO.Rest/Media/Mapi.cs b/DolbyIO.Rest/Media/Mapi.cs index 6397798..aea3b2a 100644 --- a/DolbyIO.Rest/Media/Mapi.cs +++ b/DolbyIO.Rest/Media/Mapi.cs @@ -10,6 +10,8 @@ public sealed class Mapi public AnalyzeSpeech AnalyzeSpeech { get; } + public Authentication Authentication { get; } + public Diagnose Diagnose { get; } public Enhance Enhance { get; } @@ -29,6 +31,7 @@ internal Mapi(HttpClient httpClient) Analyze = new Analyze(httpClient); AnalyzeMusic = new AnalyzeMusic(httpClient); AnalyzeSpeech = new AnalyzeSpeech(httpClient); + Authentication = new Authentication(httpClient); Diagnose = new Diagnose(httpClient); Enhance = new Enhance(httpClient); Io = new Io(httpClient); diff --git a/DolbyIO.Rest/Media/Mastering.cs b/DolbyIO.Rest/Media/Mastering.cs index 3db8e69..00a8ddc 100644 --- a/DolbyIO.Rest/Media/Mastering.cs +++ b/DolbyIO.Rest/Media/Mastering.cs @@ -1,7 +1,6 @@ using System.Net.Http; using System.Threading.Tasks; using DolbyIO.Rest.Media.Models; -using DolbyIO.Rest.Models; using Newtonsoft.Json; namespace DolbyIO.Rest.Media; diff --git a/DolbyIO.Rest/Models/JwtToken.cs b/DolbyIO.Rest/Media/Models/JwtToken.cs similarity index 72% rename from DolbyIO.Rest/Models/JwtToken.cs rename to DolbyIO.Rest/Media/Models/JwtToken.cs index 5021047..9a2bcff 100644 --- a/DolbyIO.Rest/Models/JwtToken.cs +++ b/DolbyIO.Rest/Media/Models/JwtToken.cs @@ -1,6 +1,6 @@ using Newtonsoft.Json; -namespace DolbyIO.Rest.Models; +namespace DolbyIO.Rest.Media.Models; public sealed class JwtToken { @@ -21,12 +21,4 @@ public sealed class JwtToken /// [JsonProperty("token_type")] public string TokenType { get; internal set; } - -#nullable enable - /// - /// Gets the scope of access token. - /// - [JsonProperty("scope")] - public string? Scope { get; internal set; } -#nullable disable } diff --git a/DolbyIO.Rest/Media/Transcode.cs b/DolbyIO.Rest/Media/Transcode.cs index f397b5c..1b25130 100644 --- a/DolbyIO.Rest/Media/Transcode.cs +++ b/DolbyIO.Rest/Media/Transcode.cs @@ -1,7 +1,6 @@ using System.Net.Http; using System.Threading.Tasks; using DolbyIO.Rest.Media.Models; -using DolbyIO.Rest.Models; namespace DolbyIO.Rest.Media; diff --git a/DolbyIO.Rest/Media/Webhooks.cs b/DolbyIO.Rest/Media/Webhooks.cs index e4ab80b..6512aec 100644 --- a/DolbyIO.Rest/Media/Webhooks.cs +++ b/DolbyIO.Rest/Media/Webhooks.cs @@ -3,10 +3,9 @@ using System.Net.Http; using System.Threading.Tasks; using DolbyIO.Rest.Media.Models; -using DolbyIO.Rest.Models; namespace DolbyIO.Rest.Media; - + public sealed class Webhooks { private readonly HttpClient _httpClient; @@ -32,7 +31,7 @@ public async Task RegisterAsync(JwtToken accessToken, string url, NameVa headers = headers } }; - const string requestUrl = Urls.CAPI_BASE_URL + "/media/webhooks"; + const string requestUrl = Urls.MAPI_BASE_URL + "/media/webhooks"; WebhookCreationResult result = await _httpClient.SendPostAsync(requestUrl, accessToken, body); return result.WebhookId; } @@ -54,7 +53,7 @@ public async Task UpdateAsync(JwtToken accessToken, UpdateWebhookOptions options headers = options.Headers } }; - const string requestUrl = Urls.CAPI_BASE_URL + "/media/webhooks"; + const string requestUrl = Urls.MAPI_BASE_URL + "/media/webhooks"; await _httpClient.SendPutAsync(requestUrl, accessToken, body); } diff --git a/DolbyIO.Rest/Urls.cs b/DolbyIO.Rest/Urls.cs index a2f664d..888c0f7 100644 --- a/DolbyIO.Rest/Urls.cs +++ b/DolbyIO.Rest/Urls.cs @@ -3,9 +3,7 @@ namespace DolbyIO.Rest; internal static class Urls { public const string API_BASE_URL = "https://api.dolby.io"; - public const string SESSION_BASE_URL = "https://session.voxeet.com"; - public const string CAPI_BASE_URL = "https://comms.api.dolby.io"; public const string MAPI_BASE_URL = "https://api.dolby.com"; - public const string SAPI_BASE_URL = "https://api.millicast.com"; - public const string SAPI_DIRECTOR_BASE_URL = "https://director.millicast.com"; + public const string STREAMING_BASE_URL = "https://api.millicast.com"; + public const string STREAMING_DIRECTOR_BASE_URL = "https://director.millicast.com"; } diff --git a/LICENSE b/LICENSE index 16813b1..609d1e6 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2023 Dolby.io +Copyright (c) 2024 Dolby.io Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index ab46bfb..a7cdcd5 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ # Dolby.io REST APIs Client for .NET -.NET wrapper for the dolby.io REST [Communications](https://docs.dolby.io/communications-apis/reference/authentication-api), [Streaming](https://docs.dolby.io/streaming-apis/reference) and [Media](https://docs.dolby.io/media-processing/reference/media-enhance-overview) APIs. +.NET wrapper for the [Dolby Millicast](https://docs.dolby.io/streaming-apis/reference) and [Media](https://docs.dolby.io/media-processing/reference/media-enhance-overview) APIs. ## Install this SDK @@ -16,95 +16,6 @@ If you want to use NuGet, use the following command: dotnet add package DolbyIO.Rest ``` -## Authentication - -To get an access token that will be used by your server to perform backend operations like creating a conference, use the following code. This is only for the Communications and Media APIs. - -```csharp -using DolbyIO.Rest; - -const string APP_KEY = "app_key"; -const string APP_SECRET = "app_secret"; - -using DolbyIOClient client = new DolbyIOClient(); - -JwtToken jwt = await client.Authentication.GetApiAccessTokenAsync(APP_KEY, APP_SECRET); -``` - -To request a particular scope for this access token: - -```csharp -using DolbyIO.Rest; - -const string APP_KEY = "app_key"; -const string APP_SECRET = "app_secret"; - -using DolbyIOClient client = new DolbyIOClient(); - -JwtToken jwt = await client.Authentication.GetApiAccessTokenAsync( - APP_KEY, - APP_SECRET, - 3600, - new string[] { "comms:client_access_token:create" } -); -``` - -## Communications Examples - -### Get a Client Access Token - -To get an access token that will be used by the client SDK for an end user to open a session against dolby.io, use the following code: - -```csharp -using DolbyIO.Rest; -using DolbyIO.Rest.Models; - -const string APP_KEY = "app_key"; -const string APP_SECRET = "app_secret"; - -using DolbyIOClient client = new DolbyIOClient(); - -JwtToken apiToken = await client.Authentication.GetApiAccessTokenAsync( - APP_KEY, - APP_SECRET, - 3600, - new string[] { "comms:client_access_token:create" } -); - -JwtToken cat = await client.Communications.Authentication - .GetClientAccessTokenV2Async(apiToken, new string[] {"*"}); -``` - -### Create a conference - -To create a Dolby Voice conference, you first must retrieve an API Access Token, then use the following code to create the conference. - -```csharp -using DolbyIO.Rest; -using DolbyIO.Rest.Communications.Models; -using DolbyIO.Rest.Models; - -const string APP_KEY = "app_key"; -const string APP_SECRET = "app_secret"; - -using DolbyIOClient client = new DolbyIOClient(); - -JwtToken jwt = await client.Authentication.GetApiAccessTokenAsync( - APP_KEY, - APP_SECRET, - 3600, - new string[] { "comms:conf:create" } -); - -CreateConferenceOptions options = new CreateConferenceOptions -{ - Alias = "Conference Name", - OwnerExternalId = "Fabien" -}; - -Conference conference = await client.Conferences.CreateAsync(jwt, options); -``` - ## Real-time Streaming Examples ### Create a publish token @@ -115,6 +26,8 @@ using DolbyIO.Rest; using DolbyIO.Rest.Streaming.Models; using Newtonsoft.Json; +const string API_SECRET = "api_secret"; + using DolbyIOClient client = new DolbyIOClient(); CreatePublishToken create = new CreatePublishToken @@ -128,7 +41,7 @@ CreatePublishToken create = new CreatePublishToken } } }; -PublishToken token = await client.Streaming.PublishToken.CreateAsync("api_secret", create); +PublishToken token = await client.Streaming.PublishToken.CreateAsync(API_SECRET, create); ``` ### Create a subscribe token @@ -139,6 +52,8 @@ using DolbyIO.Rest; using DolbyIO.Rest.Streaming.Models; using Newtonsoft.Json; +const string API_SECRET = "api_secret"; + using DolbyIOClient client = new DolbyIOClient(); CreateSubscribeToken create = new CreateSubscribeToken @@ -152,7 +67,7 @@ CreateSubscribeToken create = new CreateSubscribeToken } } }; -SubscribeToken token = await client.Streaming.SubscribeToken.CreateAsync("api_secret", create); +SubscribeToken token = await client.Streaming.SubscribeToken.CreateAsync(API_SECRET, create); ``` ## Media Examples @@ -164,7 +79,7 @@ To start an enhance job, use the following code: ```csharp using System; using DolbyIO.Rest; -using DolbyIO.Rest.Models; +using DolbyIO.Rest.Media.Models; using Newtonsoft.Json; const string APP_KEY = "app_key"; @@ -172,7 +87,7 @@ const string APP_SECRET = "app_secret"; using DolbyIOClient client = new DolbyIOClient(); -JwtToken jwt = await client.Authentication.GetApiAccessTokenAsync(APP_KEY, APP_SECRET); +JwtToken jwt = await client.Media.Authentication.GetApiAccessTokenAsync(APP_KEY, APP_SECRET); string jobDescription = JsonConvert.SerializeObject(new { content = new { type = "podcast" }, From 6e03d3145a14afe2e6130a1f71e29d7b7d173872 Mon Sep 17 00:00:00 2001 From: Fabien Lavocat <4154532+FabienLavocat@users.noreply.github.com> Date: Fri, 2 Aug 2024 14:56:50 -0700 Subject: [PATCH 2/4] Update Streaming APIs --- DolbyIO.Rest/Streaming/Account.cs | 53 +++++++++++++++++++ DolbyIO.Rest/Streaming/Cluster.cs | 6 +-- DolbyIO.Rest/Streaming/Director.cs | 4 +- DolbyIO.Rest/Streaming/Geo.cs | 38 ------------- .../Streaming/Models/{Geo.cs => Account.cs} | 30 ++++++++--- DolbyIO.Rest/Streaming/PublishTokens.cs | 8 +-- DolbyIO.Rest/Streaming/Sapi.cs | 7 ++- DolbyIO.Rest/Streaming/Stream.cs | 4 +- DolbyIO.Rest/Streaming/SubscribeTokens.cs | 4 +- DolbyIO.Rest/Streaming/Whep.cs | 2 +- DolbyIO.Rest/Streaming/Whip.cs | 2 +- 11 files changed, 95 insertions(+), 63 deletions(-) create mode 100644 DolbyIO.Rest/Streaming/Account.cs delete mode 100644 DolbyIO.Rest/Streaming/Geo.cs rename DolbyIO.Rest/Streaming/Models/{Geo.cs => Account.cs} (52%) diff --git a/DolbyIO.Rest/Streaming/Account.cs b/DolbyIO.Rest/Streaming/Account.cs new file mode 100644 index 0000000..6603d9c --- /dev/null +++ b/DolbyIO.Rest/Streaming/Account.cs @@ -0,0 +1,53 @@ +using System.Collections.Generic; +using System.Net.Http; +using System.Threading.Tasks; +using DolbyIO.Rest.Streaming.Models; +using Newtonsoft.Json; + +namespace DolbyIO.Rest.Streaming; + +public sealed class Account +{ + private readonly HttpClient _httpClient; + + internal Account(HttpClient httpClient) + { + _httpClient = httpClient; + } + + public async Task ReadGeoCascadeAsync(string apiSecret) + { + const string url = Urls.STREAMING_BASE_URL + "/api/account/geo_cascade"; + using HttpRequestMessage request = Extensions.BuildHttpRequestMessageBase(HttpMethod.Get, url, apiSecret); + return await _httpClient.GetResponseAsync(request); + } + + public async Task UpdateGeoCascadeAsync(string apiSecret, UpdateGeoCascade rules) + { + const string url = Urls.STREAMING_BASE_URL + "/api/account/geo_cascade"; + string content = JsonConvert.SerializeObject(rules); + using HttpRequestMessage request = Extensions.BuildHttpRequestMessage(HttpMethod.Put, url, apiSecret, content); + return await _httpClient.GetResponseAsync(request); + } + + public async Task ReadGeoRestrictionsAsync(string apiSecret) + { + const string url = Urls.STREAMING_BASE_URL + "/api/geo/account"; + using HttpRequestMessage request = Extensions.BuildHttpRequestMessageBase(HttpMethod.Get, url, apiSecret); + return await _httpClient.GetResponseAsync(request); + } + + public async Task UpdateGeoRestrictionsAsync(string apiSecret, IEnumerable allowedCountries, IEnumerable deniedCountries) + { + const string url = Urls.STREAMING_BASE_URL + "/api/geo/account"; + var body = new UpdateGeoRestrictions + { + UpdateAllowedCountries = allowedCountries, + UpdateDeniedCountries = deniedCountries + }; + + string content = JsonConvert.SerializeObject(body); + using HttpRequestMessage request = Extensions.BuildHttpRequestMessage(HttpMethod.Post, url, apiSecret, content); + return await _httpClient.GetResponseAsync(request); + } +} diff --git a/DolbyIO.Rest/Streaming/Cluster.cs b/DolbyIO.Rest/Streaming/Cluster.cs index e076478..eae848e 100644 --- a/DolbyIO.Rest/Streaming/Cluster.cs +++ b/DolbyIO.Rest/Streaming/Cluster.cs @@ -17,7 +17,7 @@ internal Cluster(HttpClient httpClient) public async Task ReadAsync(string apiSecret) { - const string url = Urls.SAPI_BASE_URL + "/api/cluster"; + const string url = Urls.STREAMING_BASE_URL + "/api/cluster"; using var request = new HttpRequestMessage(HttpMethod.Get, url); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", apiSecret); @@ -29,11 +29,11 @@ public async Task ReadAsync(string apiSecret) public async Task UpdateAsync(string apiSecret, string defaultCluster) { - const string url = Urls.SAPI_BASE_URL + "/api/cluster"; + const string url = Urls.STREAMING_BASE_URL + "/api/cluster"; var body = new { - defaultCluster = defaultCluster + defaultCluster }; string content = JsonConvert.SerializeObject(body); diff --git a/DolbyIO.Rest/Streaming/Director.cs b/DolbyIO.Rest/Streaming/Director.cs index b6ef00e..ae3327c 100644 --- a/DolbyIO.Rest/Streaming/Director.cs +++ b/DolbyIO.Rest/Streaming/Director.cs @@ -22,7 +22,7 @@ internal Director(HttpClient httpClient) /// The property returns the object. public async Task PublishAsync(string publishingToken, string streamName) { - const string url = Urls.SAPI_DIRECTOR_BASE_URL + "/api/director/publish"; + const string url = Urls.STREAMING_DIRECTOR_BASE_URL + "/api/director/publish"; var body = new { @@ -43,7 +43,7 @@ public async Task PublishAsync(string publishingToken, string s /// The property returns the object. public async Task SubscribeAsync(string streamName, string streamAccountId = null, string subscribeToken = null) { - const string url = Urls.SAPI_DIRECTOR_BASE_URL + "/api/director/subscribe"; + const string url = Urls.STREAMING_DIRECTOR_BASE_URL + "/api/director/subscribe"; var body = new { diff --git a/DolbyIO.Rest/Streaming/Geo.cs b/DolbyIO.Rest/Streaming/Geo.cs deleted file mode 100644 index 6db4744..0000000 --- a/DolbyIO.Rest/Streaming/Geo.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System.Collections.Generic; -using System.Net.Http; -using System.Threading.Tasks; -using DolbyIO.Rest.Streaming.Models; -using Newtonsoft.Json; - -namespace DolbyIO.Rest.Streaming; - -public sealed class Geo -{ - private const string URL_BASE = Urls.SAPI_BASE_URL + "/api/geo/account"; - - private readonly HttpClient _httpClient; - - internal Geo(HttpClient httpClient) - { - _httpClient = httpClient; - } - - public async Task ReadAsync(string apiSecret) - { - using HttpRequestMessage request = Extensions.BuildHttpRequestMessageBase(HttpMethod.Get, URL_BASE, apiSecret); - return await _httpClient.GetResponseAsync(request); - } - - public async Task UpdateAsync(string apiSecret, IEnumerable allowedCountries, IEnumerable deniedCountries) - { - var body = new GeoUpdate - { - UpdateAllowedCountries = allowedCountries, - UpdateDeniedCountries = deniedCountries - }; - - string content = JsonConvert.SerializeObject(body); - using HttpRequestMessage request = Extensions.BuildHttpRequestMessage(HttpMethod.Post, URL_BASE, apiSecret, content); - return await _httpClient.GetResponseAsync(request); - } -} diff --git a/DolbyIO.Rest/Streaming/Models/Geo.cs b/DolbyIO.Rest/Streaming/Models/Account.cs similarity index 52% rename from DolbyIO.Rest/Streaming/Models/Geo.cs rename to DolbyIO.Rest/Streaming/Models/Account.cs index c390169..639838e 100644 --- a/DolbyIO.Rest/Streaming/Models/Geo.cs +++ b/DolbyIO.Rest/Streaming/Models/Account.cs @@ -3,16 +3,25 @@ namespace DolbyIO.Rest.Streaming.Models; -public sealed class GeoUpdate +public sealed class GeoCascade { - [JsonProperty("updateAllowedCountries", NullValueHandling = NullValueHandling.Ignore)] - public IEnumerable UpdateAllowedCountries { get; set; } + [JsonProperty("isEnabled")] + public bool IsEnabled { get; internal set; } - [JsonProperty("updateDeniedCountries", NullValueHandling = NullValueHandling.Ignore)] - public IEnumerable UpdateDeniedCountries { get; set; } + [JsonProperty("clusters")] + public IEnumerable Clusters { get; internal set; } +} + +public sealed class UpdateGeoCascade +{ + [JsonProperty("isEnabled", NullValueHandling = NullValueHandling.Ignore)] + public bool? IsEnabled { get; set; } + + [JsonProperty("clusters", NullValueHandling = NullValueHandling.Ignore)] + public IEnumerable Clusters { get; set; } } -public sealed class GeoResponse +public sealed class GeoRestrictions { [JsonProperty("allowedCountries")] public IEnumerable AllowedCountries { get; internal set; } @@ -20,3 +29,12 @@ public sealed class GeoResponse [JsonProperty("deniedCountries")] public IEnumerable DeniedCountries { get; internal set; } } + +public sealed class UpdateGeoRestrictions +{ + [JsonProperty("updateAllowedCountries", NullValueHandling = NullValueHandling.Ignore)] + public IEnumerable UpdateAllowedCountries { get; set; } + + [JsonProperty("updateDeniedCountries", NullValueHandling = NullValueHandling.Ignore)] + public IEnumerable UpdateDeniedCountries { get; set; } +} diff --git a/DolbyIO.Rest/Streaming/PublishTokens.cs b/DolbyIO.Rest/Streaming/PublishTokens.cs index 6ffa25c..d97805e 100644 --- a/DolbyIO.Rest/Streaming/PublishTokens.cs +++ b/DolbyIO.Rest/Streaming/PublishTokens.cs @@ -1,5 +1,5 @@ -using System; -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Collections.Specialized; using System.Net.Http; using System.Threading.Tasks; @@ -10,7 +10,7 @@ namespace DolbyIO.Rest.Streaming; public sealed class PublishTokens { - private const string URL_BASE = Urls.SAPI_BASE_URL + "/api/publish_token"; + private const string URL_BASE = Urls.STREAMING_BASE_URL + "/api/publish_token"; private readonly HttpClient _httpClient; @@ -50,7 +50,7 @@ public enum ListSortBy public async Task> ListAsync(string apiSecret, int page, int itemsOnPage, ListSortBy sortBy = ListSortBy.None, bool isDescending = false) { - var uriBuilder = new UriBuilder(Urls.SAPI_BASE_URL); + var uriBuilder = new UriBuilder(Urls.STREAMING_BASE_URL); uriBuilder.Path = "/api/publish_token/list"; var nvc = new NameValueCollection(); diff --git a/DolbyIO.Rest/Streaming/Sapi.cs b/DolbyIO.Rest/Streaming/Sapi.cs index e6f712f..c623ca9 100644 --- a/DolbyIO.Rest/Streaming/Sapi.cs +++ b/DolbyIO.Rest/Streaming/Sapi.cs @@ -1,13 +1,12 @@ using System.Net.Http; -using DolbyIO.Rest.Streaming.Models; namespace DolbyIO.Rest.Streaming; public sealed class Sapi { - public Cluster Cluster { get; } + public Account Account { get; } - public Geo Geo { get; } + public Cluster Cluster { get; } public PublishTokens PublishToken { get; } @@ -23,8 +22,8 @@ public sealed class Sapi internal Sapi(HttpClient httpClient) { + Account = new Account(httpClient); Cluster = new Cluster(httpClient); - Geo = new Geo(httpClient); PublishToken = new PublishTokens(httpClient); Stream = new Stream(httpClient); SubscribeToken = new SubscribeTokens(httpClient); diff --git a/DolbyIO.Rest/Streaming/Stream.cs b/DolbyIO.Rest/Streaming/Stream.cs index f93f012..ead4f39 100644 --- a/DolbyIO.Rest/Streaming/Stream.cs +++ b/DolbyIO.Rest/Streaming/Stream.cs @@ -22,7 +22,7 @@ internal Stream(HttpClient httpClient) /// Prior to stopping all streams, you must call the function. public async Task StopAsync(string apiSecret, string streamId) { - const string url = Urls.SAPI_BASE_URL + "/api/stream/stop"; + const string url = Urls.STREAMING_BASE_URL + "/api/stream/stop"; var body = new { @@ -42,7 +42,7 @@ public async Task StopAsync(string apiSecret, string streamId) /// Prior to stopping all streams, you must call the function. public async Task StopAllAsync(string apiSecret) { - const string url = Urls.SAPI_BASE_URL + "/api/stream/stop/all"; + const string url = Urls.STREAMING_BASE_URL + "/api/stream/stop/all"; using HttpRequestMessage request = Extensions.BuildHttpRequestMessageBase(HttpMethod.Post, url, apiSecret); await _httpClient.SendRequestAsync(request); } diff --git a/DolbyIO.Rest/Streaming/SubscribeTokens.cs b/DolbyIO.Rest/Streaming/SubscribeTokens.cs index 7134507..1dc9513 100644 --- a/DolbyIO.Rest/Streaming/SubscribeTokens.cs +++ b/DolbyIO.Rest/Streaming/SubscribeTokens.cs @@ -10,7 +10,7 @@ namespace DolbyIO.Rest.Streaming; public sealed class SubscribeTokens { - private const string URL_BASE = Urls.SAPI_BASE_URL + "/api/subscribe_token"; + private const string URL_BASE = Urls.STREAMING_BASE_URL + "/api/subscribe_token"; private readonly HttpClient _httpClient; @@ -50,7 +50,7 @@ public enum ListSortBy public async Task> ListAsync(string apiSecret, int page, int itemsOnPage, ListSortBy sortBy = ListSortBy.None, bool isDescending = false) { - var uriBuilder = new UriBuilder(Urls.SAPI_BASE_URL); + var uriBuilder = new UriBuilder(Urls.STREAMING_BASE_URL); uriBuilder.Path = "/api/subscribe_token/list"; var nvc = new NameValueCollection(); diff --git a/DolbyIO.Rest/Streaming/Whep.cs b/DolbyIO.Rest/Streaming/Whep.cs index 14102f8..d6854b6 100644 --- a/DolbyIO.Rest/Streaming/Whep.cs +++ b/DolbyIO.Rest/Streaming/Whep.cs @@ -26,7 +26,7 @@ internal Whep(HttpClient httpClient) /// This specification is based on the https://www.ietf.org/archive/id/draft-murillo-whep-00.html draft and will be updated to upcoming versions as soon as they are available. public async Task WhepAsync(string publishingToken, string streamAccountId, string streamName, string sourceId, string sdpOffer) { - var uriBuilder = new UriBuilder(Urls.SAPI_DIRECTOR_BASE_URL) + var uriBuilder = new UriBuilder(Urls.STREAMING_DIRECTOR_BASE_URL) { Path = $"/api/whep/{streamAccountId}/{streamName}" }; diff --git a/DolbyIO.Rest/Streaming/Whip.cs b/DolbyIO.Rest/Streaming/Whip.cs index 8309015..4974fc0 100644 --- a/DolbyIO.Rest/Streaming/Whip.cs +++ b/DolbyIO.Rest/Streaming/Whip.cs @@ -25,7 +25,7 @@ internal Whip(HttpClient httpClient) /// The property returns the SDP answer. public async Task WhipAsync(string publishingToken, string streamName, string codec, string sourceId, string sdpOffer) { - var uriBuilder = new UriBuilder(Urls.SAPI_DIRECTOR_BASE_URL) + var uriBuilder = new UriBuilder(Urls.STREAMING_DIRECTOR_BASE_URL) { Path = $"/api/whip/{streamName}" }; From bb042eb6d441375543f5fb53c5de185677031494 Mon Sep 17 00:00:00 2001 From: Fabien Lavocat <4154532+FabienLavocat@users.noreply.github.com> Date: Fri, 16 Aug 2024 15:46:19 -0700 Subject: [PATCH 3/4] Update the Cluster response object description --- DolbyIO.Rest/Streaming/Models/Cluster.cs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/DolbyIO.Rest/Streaming/Models/Cluster.cs b/DolbyIO.Rest/Streaming/Models/Cluster.cs index 9b6dd65..66c42c0 100644 --- a/DolbyIO.Rest/Streaming/Models/Cluster.cs +++ b/DolbyIO.Rest/Streaming/Models/Cluster.cs @@ -3,6 +3,24 @@ namespace DolbyIO.Rest.Streaming.Models; +public sealed class ClusterLocation +{ + [JsonProperty("city")] + public string City { get; internal set; } + + [JsonProperty("region")] + public string Region { get; internal set; } + + [JsonProperty("country")] + public string Country { get; internal set; } +} + +public sealed class ClusterFeatures +{ + [JsonProperty("transcoding")] + public bool Transcoding { get; internal set; } +} + public sealed class ClusterDescription { [JsonProperty("id")] @@ -13,6 +31,12 @@ public sealed class ClusterDescription [JsonProperty("rtmp")] public string Rtmp { get; internal set; } + + [JsonProperty("location")] + public ClusterLocation Location { get; internal set; } + + [JsonProperty("features")] + public ClusterFeatures Features { get; internal set; } } public sealed class ClusterResponse From fc2e99e23e41340962bc64930435330961905fb0 Mon Sep 17 00:00:00 2001 From: Fabien Lavocat <4154532+FabienLavocat@users.noreply.github.com> Date: Fri, 16 Aug 2024 16:29:36 -0700 Subject: [PATCH 4/4] Add Tracking ID to Subscribe token --- DolbyIO.Rest/Streaming/Models/SubscribeToken.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/DolbyIO.Rest/Streaming/Models/SubscribeToken.cs b/DolbyIO.Rest/Streaming/Models/SubscribeToken.cs index a652c32..6dbeeb5 100644 --- a/DolbyIO.Rest/Streaming/Models/SubscribeToken.cs +++ b/DolbyIO.Rest/Streaming/Models/SubscribeToken.cs @@ -1,9 +1,15 @@ -using System; +using System; using System.Collections.Generic; using Newtonsoft.Json; namespace DolbyIO.Rest.Streaming.Models; +public sealed class SubscribeTokenTracking +{ + [JsonProperty("trackingId")] + public string TrackingId { get; set; } +} + public sealed class SubscribeTokenStream { [JsonProperty("streamName")] @@ -53,6 +59,9 @@ public sealed class SubscribeToken [JsonProperty("originCluster")] public string OriginCluster { get; internal set; } + + [JsonProperty("tracking")] + public SubscribeTokenTracking Tracking { get; internal set; } } public sealed class UpdateSubscribeToken @@ -119,4 +128,7 @@ public sealed class CreateSubscribeToken [JsonProperty("originCluster", NullValueHandling = NullValueHandling.Ignore)] public string OriginCluster { get; set; } + + [JsonProperty("tracking", NullValueHandling = NullValueHandling.Ignore)] + public SubscribeTokenTracking Tracking { get; set; } }