Skip to content

Commit

Permalink
feat(microapp): 独立化直播小玩法 API 客户端
Browse files Browse the repository at this point in the history
  • Loading branch information
fudiwei committed Mar 5, 2024
1 parent 89ba25b commit 4bb51dc
Show file tree
Hide file tree
Showing 39 changed files with 497 additions and 151 deletions.
12 changes: 11 additions & 1 deletion docs/MicroApp/Basic_ModelDefinition.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

再有,每个对象的命名与官方文档的接口地址大体保持一致。例如刚刚提到的发送订阅消息,它的接口地址是 `[POST] /apps/message/custom/send`,将其中的反斜杠去掉、并以大驼峰命名法的方式调整它,就可以得到前文提到的几个对象了。如果路由中带有版本信息,那么版本号一般都在结尾处,例如接口 `[POST] /v2/tags/image` 对应的是 `TagsImageV2`

完整的模型定义可以参考项目目录下的 _src/SKIT.FlurlHttpClient.ByteDance.Api/Models__src/SKIT.FlurlHttpClient.ByteDance.Api/SDK/OpenApi/Models__src/SKIT.FlurlHttpClient.ByteDance.Api/SDK/ProductApi/Models__src/SKIT.FlurlHttpClient.ByteDance.Api/SDK/RoleApi/Models_ 目录。
完整的模型定义可以参考项目目录下的 _src/SKIT.FlurlHttpClient.ByteDance.Api/Models__src/SKIT.FlurlHttpClient.ByteDance.Api/ExtendedSdk/OpenApi/Models__src/SKIT.FlurlHttpClient.ByteDance.Api/ExtendedSdk/ProductApi/Models__src/SKIT.FlurlHttpClient.ByteDance.Api/ExtendedSdk/RoleApi/Models__src/SKIT.FlurlHttpClient.ByteDance.Api/ExtendedSdk/Webcast/Models_ 目录。

---

Expand Down Expand Up @@ -76,3 +76,13 @@
|| 代商家入驻抖音开放平台 | |

</details>

#### 4. 直播小玩法

<details>

<summary>[展开查看]</summary>

| | 抖音 API | 备注 |
| :-: | :------: | :--: |
|| 直播能力 | |
15 changes: 14 additions & 1 deletion docs/MicroApp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ else
}
```

### 独立的(服务商平台、泛知识课程库、泛知识角色系统等)扩展客户端
### 独立的扩展客户端(服务商平台、泛知识课程库、泛知识角色系统、直播小玩法等)

部分 API 的接入点、接口模型公共参数等配置项与基础 API 完全不同,需要使用独立的扩展客户端。

Expand Down Expand Up @@ -114,6 +114,19 @@ var options = new DouyinMicroAppRoleApiClientOptions()
var client = DouyinMicroAppRoleApiClientBuilder.Create(options).Build();
```

- 直播小玩法:

```csharp
using SKIT.FlurlHttpClient.ByteDance.MicroApp.SDK.Webcast;

var options = new DouyinMicroAppWebcastClientOptions()
{
AppId = "抖音小程序 AppId",
AppSecret = "抖音小程序 AppSecret"
};
var client = DouyinMicroAppWebcastClientBuilder.Create(options).Build();
```

这些扩展客户端在用法上基础客户端完全相同,只需引入各自的命名空间即可。

---
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,6 @@ public class DouyinMicroAppClient : CommonClientBase, ICommonClient
/// </summary>
public Settings.Credentials Credentials { get; }

/// <summary>
/// 获取当前客户端使用的抖音小程序 API 接入点。
/// </summary>
protected internal string EndpointForDefault { get; }

/// <summary>
/// 获取当前客户端使用的抖音小程序直播小玩法 API 接入点。
/// </summary>
protected internal string EndpointForWebcast { get; }

/// <summary>
/// 用指定的配置项初始化 <see cref="DouyinMicroAppClient"/> 类的新实例。
/// </summary>
Expand All @@ -47,8 +37,6 @@ internal protected DouyinMicroAppClient(DouyinMicroAppClientOptions options, Htt
if (options is null) throw new ArgumentNullException(nameof(options));

Credentials = new Settings.Credentials(options);
EndpointForDefault = options.Endpoint;
EndpointForWebcast = options.EndpointForWebcastAPI;

FlurlClient.BaseUrl = options.Endpoint ?? DouyinMicroAppEndpoints.DEFAULT;
FlurlClient.WithTimeout(options.Timeout <= 0 ? Timeout.InfiniteTimeSpan : TimeSpan.FromMilliseconds(options.Timeout));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,6 @@ public class DouyinMicroAppClientOptions
/// </summary>
public string Endpoint { get; set; } = DouyinMicroAppEndpoints.DEFAULT;

/// <summary>
/// 获取或设置抖音小程序直播小玩法 API 入口点。
/// <para>默认值:<see cref="DouyinMicroAppWebcastEndpoints.DEFAULT"/></para>
/// </summary>
public string EndpointForWebcastAPI { get; set; } = DouyinMicroAppWebcastEndpoints.DEFAULT;

/// <summary>
/// 获取或设置抖音小程序 AppId。
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,4 @@ public static class DouyinMicroAppEndpoints
/// </summary>
public const string SANGBOX = "https://open-sandbox.douyin.com/api";
}

/// <summary>
/// 抖音小程序直播小玩法 API 接口域名。
/// </summary>
public static class DouyinMicroAppWebcastEndpoints
{
/// <summary>
/// 主域名(默认)。
/// </summary>
public const string DEFAULT = "https://webcast.bytedance.com/api";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ public abstract class DouyinMicroAppRequest : CommonRequestBase, ICommonRequest
{
/// <summary>
/// 获取或设置抖音小程序的 AccessToken。
/// <para>注意:部分第三方平台的接口中该字段表示授权方的 AuthorizerAccessToken。</para>
/// <para>
/// 注意:部分第三方平台的接口中该字段表示授权方的 AuthorizerAccessToken。
/// </para>
/// </summary>
[Newtonsoft.Json.JsonIgnore]
[System.Text.Json.Serialization.JsonIgnore]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Flurl.Http;

namespace SKIT.FlurlHttpClient.ByteDance.MicroApp.ExtendedSDK.Webcast
{
/// <summary>
/// 一个抖音小程序直播小玩法 API HTTP 客户端。
/// </summary>
public class DouyinMicroAppWebcastClient : CommonClientBase, ICommonClient
{
/// <summary>
/// 获取当前客户端使用的抖音小程序凭证。
/// </summary>
public Settings.Credentials Credentials { get; }

/// <summary>
/// 用指定的配置项初始化 <see cref="DouyinMicroAppWebcastClient"/> 类的新实例。
/// </summary>
/// <param name="options">配置项。</param>
public DouyinMicroAppWebcastClient(DouyinMicroAppWebcastClientOptions options)
: this(options, null)
{
}

/// <summary>
///
/// </summary>
/// <param name="options"></param>
/// <param name="httpClient"></param>
/// <param name="disposeClient"></param>
internal protected DouyinMicroAppWebcastClient(DouyinMicroAppWebcastClientOptions options, HttpClient? httpClient, bool disposeClient = true)
: base(httpClient, disposeClient)
{
if (options is null) throw new ArgumentNullException(nameof(options));

Credentials = new Settings.Credentials(options);

FlurlClient.BaseUrl = options.Endpoint ?? DouyinMicroAppWebcastEndpoints.DEFAULT;
FlurlClient.WithTimeout(options.Timeout <= 0 ? Timeout.InfiniteTimeSpan : TimeSpan.FromMilliseconds(options.Timeout));
}

/// <summary>
/// 使用当前客户端生成一个新的 <see cref="IFlurlRequest"/> 对象。
/// </summary>
/// <param name="request"></param>
/// <param name="httpMethod"></param>
/// <param name="urlSegments"></param>
/// <returns></returns>
public IFlurlRequest CreateFlurlRequest(DouyinMicroAppWebcastRequest request, HttpMethod httpMethod, params object[] urlSegments)
{
IFlurlRequest flurlRequest = base.CreateFlurlRequest(request, httpMethod, urlSegments);

return flurlRequest;
}

/// <summary>
/// 异步发起请求。
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="flurlRequest"></param>
/// <param name="httpContent"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<T> SendFlurlRequestAsync<T>(IFlurlRequest flurlRequest, HttpContent? httpContent = null, CancellationToken cancellationToken = default)
where T : DouyinMicroAppWebcastResponse, new()
{
if (flurlRequest is null) throw new ArgumentNullException(nameof(flurlRequest));

using IFlurlResponse flurlResponse = await base.SendFlurlRequestAsync(flurlRequest, httpContent, cancellationToken).ConfigureAwait(false);
return await WrapFlurlResponseAsJsonAsync<T>(flurlResponse, cancellationToken).ConfigureAwait(false);
}

/// <summary>
/// 异步发起请求。
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="flurlRequest"></param>
/// <param name="data"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<T> SendFlurlRequestAsJsonAsync<T>(IFlurlRequest flurlRequest, object? data = null, CancellationToken cancellationToken = default)
where T : DouyinMicroAppWebcastResponse, new()
{
if (flurlRequest is null) throw new ArgumentNullException(nameof(flurlRequest));

bool isSimpleRequest = data is null ||
flurlRequest.Verb == HttpMethod.Get ||
flurlRequest.Verb == HttpMethod.Head ||
flurlRequest.Verb == HttpMethod.Options;
using IFlurlResponse flurlResponse = isSimpleRequest ?
await base.SendFlurlRequestAsync(flurlRequest, null, cancellationToken) :
await base.SendFlurlRequestAsJsonAsync(flurlRequest, data, cancellationToken).ConfigureAwait(false);
return await WrapFlurlResponseAsJsonAsync<T>(flurlResponse, cancellationToken).ConfigureAwait(false);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
using System;
using System.Collections.Generic;
using System.Net.Http;

namespace SKIT.FlurlHttpClient.ByteDance.MicroApp.ExtendedSDK.Webcast
{
/// <summary>
/// 用于构造 <see cref="DouyinMicroAppWebcastClient"/> 实例的构造器。
/// </summary>
public partial class DouyinMicroAppWebcastClientBuilder : ICommonClientBuilder<DouyinMicroAppWebcastClient>
{
private readonly DouyinMicroAppWebcastClientOptions _options;
private readonly IList<Action<CommonClientSettings>> _configures;
private readonly IList<HttpInterceptor> _interceptors;
private HttpClient? _httpClient;
private bool? _disposeClient;

private DouyinMicroAppWebcastClientBuilder(DouyinMicroAppWebcastClientOptions options)
{
_options = options;
_configures = new List<Action<CommonClientSettings>>();
_interceptors = new List<HttpInterceptor>();
}

ICommonClientBuilder<DouyinMicroAppWebcastClient> ICommonClientBuilder<DouyinMicroAppWebcastClient>.ConfigureSettings(Action<CommonClientSettings> configure)
{
return ConfigureSettings(configure);
}

ICommonClientBuilder<DouyinMicroAppWebcastClient> ICommonClientBuilder<DouyinMicroAppWebcastClient>.UseInterceptor(HttpInterceptor interceptor)
{
return UseInterceptor(interceptor);
}

ICommonClientBuilder<DouyinMicroAppWebcastClient> ICommonClientBuilder<DouyinMicroAppWebcastClient>.UseHttpClient(HttpClient httpClient, bool disposeClient)
{
return UseHttpClient(httpClient, disposeClient);
}

public DouyinMicroAppWebcastClientBuilder ConfigureSettings(Action<CommonClientSettings> configure)
{
if (configure is null) throw new ArgumentNullException(nameof(configure));

_configures.Add(configure);
return this;
}

public DouyinMicroAppWebcastClientBuilder UseInterceptor(HttpInterceptor interceptor)
{
if (interceptor is null) throw new ArgumentNullException(nameof(interceptor));

_interceptors.Add(interceptor);
return this;
}

public DouyinMicroAppWebcastClientBuilder UseHttpClient(HttpClient httpClient, bool disposeClient = true)
{
if (httpClient is null) throw new ArgumentNullException(nameof(httpClient));

_httpClient = httpClient;
_disposeClient = disposeClient;
return this;
}

public DouyinMicroAppWebcastClient Build()
{
DouyinMicroAppWebcastClient client = _disposeClient.HasValue
? new DouyinMicroAppWebcastClient(_options, _httpClient, _disposeClient.Value)
: new DouyinMicroAppWebcastClient(_options, _httpClient);

foreach (Action<CommonClientSettings> configure in _configures)
{
client.Configure(configure);
}

foreach (HttpInterceptor interceptor in _interceptors)
{
client.Interceptors.Add(interceptor);
}

return client;
}
}

partial class DouyinMicroAppWebcastClientBuilder
{
public static DouyinMicroAppWebcastClientBuilder Create(DouyinMicroAppWebcastClientOptions options)
{
if (options is null) throw new ArgumentNullException(nameof(options));

return new DouyinMicroAppWebcastClientBuilder(options);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
namespace SKIT.FlurlHttpClient.ByteDance.MicroApp.ExtendedSDK.Webcast
{
/// <summary>
/// 一个用于构造 <see cref="DouyinMicroAppWebcastClient"/> 时使用的配置项。
/// </summary>
public class DouyinMicroAppWebcastClientOptions
{
/// <summary>
/// 获取或设置请求超时时间(单位:毫秒)。
/// <para>默认值:30000</para>
/// </summary>
public int Timeout { get; set; } = 30 * 1000;

/// <summary>
/// 获取或设置抖音小程序直播小玩法 API 入口点。
/// <para>默认值:<see cref="DouyinMicroAppWebcastEndpoints.DEFAULT"/></para>
/// </summary>
public string Endpoint { get; set; } = DouyinMicroAppWebcastEndpoints.DEFAULT;

/// <summary>
/// 获取或设置抖音小程序 AppId。
/// </summary>
public string AppId { get; set; } = default!;

/// <summary>
/// 获取或设置抖音小程序 AppSecret。
/// </summary>
public string AppSecret { get; set; } = default!;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace SKIT.FlurlHttpClient.ByteDance.MicroApp.ExtendedSDK.Webcast
{
/// <summary>
/// 抖音小程序直播小玩法 API 接口域名。
/// </summary>
public static class DouyinMicroAppWebcastEndpoints
{
/// <summary>
/// 主域名(默认)。
/// </summary>
public const string DEFAULT = "https://webcast.bytedance.com/api";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace SKIT.FlurlHttpClient.ByteDance.MicroApp.ExtendedSDK.Webcast
{
/// <summary>
/// 抖音小程序直播小玩法 API 请求的基类。
/// </summary>
public abstract class DouyinMicroAppWebcastRequest : CommonRequestBase, ICommonRequest
{
/// <summary>
/// 获取或设置抖音小程序的 AccessToken。
/// </summary>
[Newtonsoft.Json.JsonIgnore]
[System.Text.Json.Serialization.JsonIgnore]
public virtual string? AccessToken { get; set; }
}
}
Loading

0 comments on commit 4bb51dc

Please sign in to comment.