mirror of
https://gitee.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat.git
synced 2025-09-20 18:48:10 +08:00
feat(openai): 新增 NLP 相关接口
This commit is contained in:
3
src/SKIT.FlurlHttpClient.Wechat.OpenAI/AssemblyInfo.cs
Normal file
3
src/SKIT.FlurlHttpClient.Wechat.OpenAI/AssemblyInfo.cs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
[assembly: InternalsVisibleTo("SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests")]
|
@@ -43,7 +43,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
|
|||||||
if (!Utilities.WxBizMsgCryptor.TryParseXml(callbackXml, out string? encryptedXml))
|
if (!Utilities.WxBizMsgCryptor.TryParseXml(callbackXml, out string? encryptedXml))
|
||||||
throw new Exceptions.WechatOpenAIEventSerializationException("Encrypt event failed, because of empty encrypted data.");
|
throw new Exceptions.WechatOpenAIEventSerializationException("Encrypt event failed, because of empty encrypted data.");
|
||||||
|
|
||||||
callbackXml = Utilities.WxBizMsgCryptor.AESDecrypt(cipherText: encryptedXml!, encodingAESKey: client.Credentials.PushEncodingAESKey!, out _);
|
callbackXml = Utilities.WxBizMsgCryptor.AESDecrypt(cipherText: encryptedXml!, encodingAESKey: client.Credentials.EncodingAESKey!, out _);
|
||||||
|
|
||||||
using var reader = new StringReader(callbackXml);
|
using var reader = new StringReader(callbackXml);
|
||||||
|
|
||||||
@@ -106,20 +106,20 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(client.Credentials.PushEncodingAESKey))
|
if (string.IsNullOrEmpty(client.Credentials.EncodingAESKey))
|
||||||
throw new Exceptions.WechatOpenAIEventSerializationException("Encrypt event failed, because there is no encoding AES key.");
|
throw new Exceptions.WechatOpenAIEventSerializationException("Encrypt event failed, because there is no encoding AES key.");
|
||||||
if (string.IsNullOrEmpty(client.Credentials.PushToken))
|
if (string.IsNullOrEmpty(client.Credentials.Token))
|
||||||
throw new Exceptions.WechatOpenAIEventSerializationException("Encrypt event failed, because there is no token.");
|
throw new Exceptions.WechatOpenAIEventSerializationException("Encrypt event failed, because there is no token.");
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string cipher = Utilities.WxBizMsgCryptor.AESEncrypt(
|
string cipher = Utilities.WxBizMsgCryptor.AESEncrypt(
|
||||||
plainText: xml,
|
plainText: xml,
|
||||||
encodingAESKey: client.Credentials.PushEncodingAESKey!,
|
encodingAESKey: client.Credentials.EncodingAESKey!,
|
||||||
appId: client.Credentials.AppId!
|
appId: client.Credentials.AppId!
|
||||||
);
|
);
|
||||||
|
|
||||||
xml = Utilities.WxBizMsgCryptor.WrapXml(sToken: client.Credentials.PushToken!, sMsgEncrypt: cipher);
|
xml = Utilities.WxBizMsgCryptor.WrapXml(sToken: client.Credentials.Token!, sMsgEncrypt: cipher);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@@ -22,7 +22,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
|
|||||||
if (request is null) throw new ArgumentNullException(nameof(request));
|
if (request is null) throw new ArgumentNullException(nameof(request));
|
||||||
|
|
||||||
IFlurlRequest flurlReq = client
|
IFlurlRequest flurlReq = client
|
||||||
.CreateRequest(request, HttpMethod.Post, "openapi", "batchimportskill", client.Credentials.PushToken!);
|
.CreateRequest(request, HttpMethod.Post, "openapi", "batchimportskill", client.Credentials.Token!);
|
||||||
|
|
||||||
return await client.SendRequestWithJsonAsync<Models.OpenApiBatchImportSkillResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
return await client.SendRequestWithJsonAsync<Models.OpenApiBatchImportSkillResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
||||||
}
|
}
|
||||||
@@ -41,7 +41,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
|
|||||||
if (request is null) throw new ArgumentNullException(nameof(request));
|
if (request is null) throw new ArgumentNullException(nameof(request));
|
||||||
|
|
||||||
IFlurlRequest flurlReq = client
|
IFlurlRequest flurlReq = client
|
||||||
.CreateRequest(request, HttpMethod.Post, "openapi", "publish", client.Credentials.PushToken!);
|
.CreateRequest(request, HttpMethod.Post, "openapi", "publish", client.Credentials.Token!);
|
||||||
|
|
||||||
return await client.SendRequestWithJsonAsync<Models.OpenApiPublishResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
return await client.SendRequestWithJsonAsync<Models.OpenApiPublishResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
||||||
}
|
}
|
||||||
@@ -60,7 +60,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
|
|||||||
if (request is null) throw new ArgumentNullException(nameof(request));
|
if (request is null) throw new ArgumentNullException(nameof(request));
|
||||||
|
|
||||||
IFlurlRequest flurlReq = client
|
IFlurlRequest flurlReq = client
|
||||||
.CreateRequest(request, HttpMethod.Post, "openapi", "publish_progress", client.Credentials.PushToken!);
|
.CreateRequest(request, HttpMethod.Post, "openapi", "publish_progress", client.Credentials.Token!);
|
||||||
|
|
||||||
return await client.SendRequestWithJsonAsync<Models.OpenApiPublishProgressResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
return await client.SendRequestWithJsonAsync<Models.OpenApiPublishProgressResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
||||||
}
|
}
|
||||||
@@ -80,7 +80,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
|
|||||||
if (request is null) throw new ArgumentNullException(nameof(request));
|
if (request is null) throw new ArgumentNullException(nameof(request));
|
||||||
|
|
||||||
IFlurlRequest flurlReq = client
|
IFlurlRequest flurlReq = client
|
||||||
.CreateRequest(request, HttpMethod.Post, "openapi", "setautoreply", client.Credentials.PushToken!);
|
.CreateRequest(request, HttpMethod.Post, "openapi", "setautoreply", client.Credentials.Token!);
|
||||||
|
|
||||||
return await client.SendRequestWithJsonAsync<Models.OpenApiSetAutoReplyResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
return await client.SendRequestWithJsonAsync<Models.OpenApiSetAutoReplyResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
||||||
}
|
}
|
||||||
@@ -99,7 +99,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
|
|||||||
if (request is null) throw new ArgumentNullException(nameof(request));
|
if (request is null) throw new ArgumentNullException(nameof(request));
|
||||||
|
|
||||||
IFlurlRequest flurlReq = client
|
IFlurlRequest flurlReq = client
|
||||||
.CreateRequest(request, HttpMethod.Post, "openapi", "label", "batchset", client.Credentials.PushToken!);
|
.CreateRequest(request, HttpMethod.Post, "openapi", "label", "batchset", client.Credentials.Token!);
|
||||||
|
|
||||||
return await client.SendRequestWithJsonAsync<Models.OpenApiLabelBatchSetResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
return await client.SendRequestWithJsonAsync<Models.OpenApiLabelBatchSetResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
||||||
}
|
}
|
||||||
|
@@ -22,7 +22,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
|
|||||||
if (request is null) throw new ArgumentNullException(nameof(request));
|
if (request is null) throw new ArgumentNullException(nameof(request));
|
||||||
|
|
||||||
IFlurlRequest flurlReq = client
|
IFlurlRequest flurlReq = client
|
||||||
.CreateRequest(request, HttpMethod.Post, "openapi", "batchreply", client.Credentials.PushToken!);
|
.CreateRequest(request, HttpMethod.Post, "openapi", "batchreply", client.Credentials.Token!);
|
||||||
|
|
||||||
return await client.SendRequestWithJsonAsync<Models.OpenApiBatchReplyResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
return await client.SendRequestWithJsonAsync<Models.OpenApiBatchReplyResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
||||||
}
|
}
|
||||||
@@ -41,7 +41,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
|
|||||||
if (request is null) throw new ArgumentNullException(nameof(request));
|
if (request is null) throw new ArgumentNullException(nameof(request));
|
||||||
|
|
||||||
IFlurlRequest flurlReq = client
|
IFlurlRequest flurlReq = client
|
||||||
.CreateRequest(request, HttpMethod.Post, "openapi", "generatereport", client.Credentials.PushToken!);
|
.CreateRequest(request, HttpMethod.Post, "openapi", "generatereport", client.Credentials.Token!);
|
||||||
|
|
||||||
return await client.SendRequestWithJsonAsync<Models.OpenApiGenerateReportResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
return await client.SendRequestWithJsonAsync<Models.OpenApiGenerateReportResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
||||||
}
|
}
|
||||||
|
@@ -25,7 +25,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
|
|||||||
if (request is null) throw new ArgumentNullException(nameof(request));
|
if (request is null) throw new ArgumentNullException(nameof(request));
|
||||||
|
|
||||||
IFlurlRequest flurlReq = client
|
IFlurlRequest flurlReq = client
|
||||||
.CreateRequest(request, HttpMethod.Post, "openapi", "getbindlink", client.Credentials.PushToken!);
|
.CreateRequest(request, HttpMethod.Post, "openapi", "getbindlink", client.Credentials.Token!);
|
||||||
|
|
||||||
return await client.SendRequestWithJsonAsync<Models.OpenApiGetBindLinkResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
return await client.SendRequestWithJsonAsync<Models.OpenApiGetBindLinkResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
||||||
}
|
}
|
||||||
@@ -44,7 +44,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
|
|||||||
if (request is null) throw new ArgumentNullException(nameof(request));
|
if (request is null) throw new ArgumentNullException(nameof(request));
|
||||||
|
|
||||||
IFlurlRequest flurlReq = client
|
IFlurlRequest flurlReq = client
|
||||||
.CreateRequest(request, HttpMethod.Post, "openapi", "getbindlist", client.Credentials.PushToken!);
|
.CreateRequest(request, HttpMethod.Post, "openapi", "getbindlist", client.Credentials.Token!);
|
||||||
|
|
||||||
return await client.SendRequestWithJsonAsync<Models.OpenApiGetBindListResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
return await client.SendRequestWithJsonAsync<Models.OpenApiGetBindListResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
||||||
}
|
}
|
||||||
@@ -63,7 +63,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
|
|||||||
if (request is null) throw new ArgumentNullException(nameof(request));
|
if (request is null) throw new ArgumentNullException(nameof(request));
|
||||||
|
|
||||||
IFlurlRequest flurlReq = client
|
IFlurlRequest flurlReq = client
|
||||||
.CreateRequest(request, HttpMethod.Post, "openapi", "unbindmp", client.Credentials.PushToken!);
|
.CreateRequest(request, HttpMethod.Post, "openapi", "unbindmp", client.Credentials.Token!);
|
||||||
|
|
||||||
return await client.SendRequestWithJsonAsync<Models.OpenApiUnbindMpResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
return await client.SendRequestWithJsonAsync<Models.OpenApiUnbindMpResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
||||||
}
|
}
|
||||||
@@ -82,7 +82,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
|
|||||||
if (request is null) throw new ArgumentNullException(nameof(request));
|
if (request is null) throw new ArgumentNullException(nameof(request));
|
||||||
|
|
||||||
IFlurlRequest flurlReq = client
|
IFlurlRequest flurlReq = client
|
||||||
.CreateRequest(request, HttpMethod.Post, "openapi", "geth5link", client.Credentials.PushToken!);
|
.CreateRequest(request, HttpMethod.Post, "openapi", "geth5link", client.Credentials.Token!);
|
||||||
|
|
||||||
return await client.SendRequestWithJsonAsync<Models.OpenApiGetH5LinkResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
return await client.SendRequestWithJsonAsync<Models.OpenApiGetH5LinkResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
||||||
}
|
}
|
||||||
@@ -108,13 +108,13 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
|
|||||||
request.FileContentType = "image/jpeg";
|
request.FileContentType = "image/jpeg";
|
||||||
|
|
||||||
IFlurlRequest flurlReq = client
|
IFlurlRequest flurlReq = client
|
||||||
.CreateRequest(request, HttpMethod.Post, "openapi", "assetsupload", client.Credentials.PushToken!);
|
.CreateRequest(request, HttpMethod.Post, "openapi", "assetsupload", client.Credentials.Token!);
|
||||||
|
|
||||||
using var fileContent = new ByteArrayContent(request.FileBytes ?? new byte[0]);
|
using var fileContent = new ByteArrayContent(request.FileBytes ?? new byte[0]);
|
||||||
using var paramContent = new StringContent(
|
using var paramContent = new StringContent(
|
||||||
Utilities.WxBizMsgCryptor.AESEncrypt(
|
Utilities.WxBizMsgCryptor.AESEncrypt(
|
||||||
plainText: Utilities.XmlUtility.Serialize(request),
|
plainText: Utilities.XmlUtility.Serialize(request),
|
||||||
encodingAESKey: client.Credentials.PushEncodingAESKey!,
|
encodingAESKey: client.Credentials.EncodingAESKey!,
|
||||||
appId: client.Credentials.AppId!
|
appId: client.Credentials.AppId!
|
||||||
),
|
),
|
||||||
Encoding.UTF8
|
Encoding.UTF8
|
||||||
|
@@ -0,0 +1,106 @@
|
|||||||
|
using System;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Flurl.Http;
|
||||||
|
|
||||||
|
namespace SKIT.FlurlHttpClient.Wechat.OpenAI
|
||||||
|
{
|
||||||
|
public static class WechatOpenAIClientExecuteOpenApiNLPExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// <para>异步调用 [POST] /openapi/nlp/tokenize/{TOKEN} 接口。</para>
|
||||||
|
/// <para>REF: https://developers.weixin.qq.com/doc/aispeech/platform/nlp/tokenize.html </para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="client"></param>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static async Task<Models.OpenApiNLPTokenizeResponse> ExecuteOpenApiNLPTokenizeAsync(this WechatOpenAIClient client, Models.OpenApiNLPTokenizeRequest request, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
if (client is null) throw new ArgumentNullException(nameof(client));
|
||||||
|
if (request is null) throw new ArgumentNullException(nameof(request));
|
||||||
|
|
||||||
|
IFlurlRequest flurlReq = client
|
||||||
|
.CreateRequest(request, HttpMethod.Post, "openapi", "nlp", "tokenize", client.Credentials.Token!);
|
||||||
|
|
||||||
|
return await client.SendRequestWithUrlEncodedAsync<Models.OpenApiNLPTokenizeResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <para>异步调用 [POST] /openapi/nlp/ner/{TOKEN} 接口。</para>
|
||||||
|
/// <para>REF: https://developers.weixin.qq.com/doc/aispeech/platform/nlp/ner.html </para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="client"></param>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static async Task<Models.OpenApiNLPNERResponse> ExecuteOpenApiNLPNERAsync(this WechatOpenAIClient client, Models.OpenApiNLPNERRequest request, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
if (client is null) throw new ArgumentNullException(nameof(client));
|
||||||
|
if (request is null) throw new ArgumentNullException(nameof(request));
|
||||||
|
|
||||||
|
IFlurlRequest flurlReq = client
|
||||||
|
.CreateRequest(request, HttpMethod.Post, "openapi", "nlp", "ner", client.Credentials.Token!);
|
||||||
|
|
||||||
|
return await client.SendRequestWithUrlEncodedAsync<Models.OpenApiNLPNERResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <para>异步调用 [POST] /openapi/nlp/sentiment/{TOKEN} 接口。</para>
|
||||||
|
/// <para>REF: https://developers.weixin.qq.com/doc/aispeech/platform/nlp/sentiment.html </para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="client"></param>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static async Task<Models.OpenApiNLPSentimentResponse> ExecuteOpenApiNLPSentimentAsync(this WechatOpenAIClient client, Models.OpenApiNLPSentimentRequest request, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
if (client is null) throw new ArgumentNullException(nameof(client));
|
||||||
|
if (request is null) throw new ArgumentNullException(nameof(request));
|
||||||
|
|
||||||
|
IFlurlRequest flurlReq = client
|
||||||
|
.CreateRequest(request, HttpMethod.Post, "openapi", "nlp", "sentiment", client.Credentials.Token!);
|
||||||
|
|
||||||
|
return await client.SendRequestWithUrlEncodedAsync<Models.OpenApiNLPSentimentResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <para>异步调用 [POST] /openapi/nlp/ner-product/{TOKEN} 接口。</para>
|
||||||
|
/// <para>REF: https://developers.weixin.qq.com/doc/aispeech/platform/nlp/nerproduct.html </para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="client"></param>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static async Task<Models.OpenApiNLPNERProductResponse> ExecuteOpenApiNLPNERProductAsync(this WechatOpenAIClient client, Models.OpenApiNLPNERProductRequest request, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
if (client is null) throw new ArgumentNullException(nameof(client));
|
||||||
|
if (request is null) throw new ArgumentNullException(nameof(request));
|
||||||
|
|
||||||
|
IFlurlRequest flurlReq = client
|
||||||
|
.CreateRequest(request, HttpMethod.Post, "openapi", "nlp", "ner-product", client.Credentials.Token!);
|
||||||
|
|
||||||
|
return await client.SendRequestWithUrlEncodedAsync<Models.OpenApiNLPNERProductResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <para>异步调用 [POST] /openapi/nlp/sensitive/{TOKEN} 接口。</para>
|
||||||
|
/// <para>REF: https://developers.weixin.qq.com/doc/aispeech/platform/nlp/sensitive.html </para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="client"></param>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static async Task<Models.OpenApiNLPSensitiveResponse> ExecuteOpenApiNLPSensitiveAsync(this WechatOpenAIClient client, Models.OpenApiNLPSensitiveRequest request, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
if (client is null) throw new ArgumentNullException(nameof(client));
|
||||||
|
if (request is null) throw new ArgumentNullException(nameof(request));
|
||||||
|
|
||||||
|
IFlurlRequest flurlReq = client
|
||||||
|
.CreateRequest(request, HttpMethod.Post, "openapi", "nlp", "sensitive", client.Credentials.Token!);
|
||||||
|
|
||||||
|
return await client.SendRequestWithUrlEncodedAsync<Models.OpenApiNLPSensitiveResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -22,7 +22,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
|
|||||||
if (request is null) throw new ArgumentNullException(nameof(request));
|
if (request is null) throw new ArgumentNullException(nameof(request));
|
||||||
|
|
||||||
IFlurlRequest flurlReq = client
|
IFlurlRequest flurlReq = client
|
||||||
.CreateRequest(request, HttpMethod.Post, "openapi", "sign", client.Credentials.PushToken!);
|
.CreateRequest(request, HttpMethod.Post, "openapi", "sign", client.Credentials.Token!);
|
||||||
|
|
||||||
return await client.SendRequestWithJsonAsync<Models.OpenApiSignResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
return await client.SendRequestWithJsonAsync<Models.OpenApiSignResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
||||||
}
|
}
|
||||||
@@ -41,7 +41,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
|
|||||||
if (request is null) throw new ArgumentNullException(nameof(request));
|
if (request is null) throw new ArgumentNullException(nameof(request));
|
||||||
|
|
||||||
IFlurlRequest flurlReq = client
|
IFlurlRequest flurlReq = client
|
||||||
.CreateRequest(request, HttpMethod.Post, "openapi", "aibot", client.Credentials.PushToken!);
|
.CreateRequest(request, HttpMethod.Post, "openapi", "aibot", client.Credentials.Token!);
|
||||||
|
|
||||||
return await client.SendRequestWithJsonAsync<Models.OpenApiAIBotResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
return await client.SendRequestWithJsonAsync<Models.OpenApiAIBotResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
||||||
}
|
}
|
||||||
@@ -60,7 +60,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
|
|||||||
if (request is null) throw new ArgumentNullException(nameof(request));
|
if (request is null) throw new ArgumentNullException(nameof(request));
|
||||||
|
|
||||||
IFlurlRequest flurlReq = client
|
IFlurlRequest flurlReq = client
|
||||||
.CreateRequest(request, HttpMethod.Post, "openapi", "gethotquerylist", client.Credentials.PushToken!);
|
.CreateRequest(request, HttpMethod.Post, "openapi", "gethotquerylist", client.Credentials.Token!);
|
||||||
|
|
||||||
return await client.SendRequestWithJsonAsync<Models.OpenApiGetHotQueryListResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
return await client.SendRequestWithJsonAsync<Models.OpenApiGetHotQueryListResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
||||||
}
|
}
|
||||||
|
@@ -26,7 +26,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
|
|||||||
request.AppId = client.Credentials.AppId;
|
request.AppId = client.Credentials.AppId;
|
||||||
|
|
||||||
IFlurlRequest flurlReq = client
|
IFlurlRequest flurlReq = client
|
||||||
.CreateRequest(request, HttpMethod.Post, "openapi", "sendmsg", client.Credentials.PushToken!);
|
.CreateRequest(request, HttpMethod.Post, "openapi", "sendmsg", client.Credentials.Token!);
|
||||||
|
|
||||||
return await client.SendRequestWithJsonAsync<Models.OpenApiSendMessageResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
return await client.SendRequestWithJsonAsync<Models.OpenApiSendMessageResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
|
|||||||
request.AppId = client.Credentials.AppId;
|
request.AppId = client.Credentials.AppId;
|
||||||
|
|
||||||
IFlurlRequest flurlReq = client
|
IFlurlRequest flurlReq = client
|
||||||
.CreateRequest(request, HttpMethod.Post, "openapi", "kefustate", "get", client.Credentials.PushToken!);
|
.CreateRequest(request, HttpMethod.Post, "openapi", "kefustate", "get", client.Credentials.Token!);
|
||||||
|
|
||||||
return await client.SendRequestWithJsonAsync<Models.OpenApiKefuStateGetResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
return await client.SendRequestWithJsonAsync<Models.OpenApiKefuStateGetResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
||||||
}
|
}
|
||||||
@@ -70,7 +70,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
|
|||||||
request.AppId = client.Credentials.AppId;
|
request.AppId = client.Credentials.AppId;
|
||||||
|
|
||||||
IFlurlRequest flurlReq = client
|
IFlurlRequest flurlReq = client
|
||||||
.CreateRequest(request, HttpMethod.Post, "openapi", "kefustate", "change", client.Credentials.PushToken!);
|
.CreateRequest(request, HttpMethod.Post, "openapi", "kefustate", "change", client.Credentials.Token!);
|
||||||
|
|
||||||
return await client.SendRequestWithJsonAsync<Models.OpenApiKefuStateChangeResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
return await client.SendRequestWithJsonAsync<Models.OpenApiKefuStateChangeResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,38 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// <para>表示 [POST] /openapi/nlp/ner-product/{TOKEN} 接口的请求。</para>
|
||||||
|
/// </summary>
|
||||||
|
public class OpenApiNLPNERProductRequest : WechatOpenAIRequest, WechatOpenAIRequest.Serialization.IEncryptedUrlEncodedFormData
|
||||||
|
{
|
||||||
|
public static class Types
|
||||||
|
{
|
||||||
|
public class Data
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置输入文本。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonProperty("q")]
|
||||||
|
[System.Text.Json.Serialization.JsonPropertyName("q")]
|
||||||
|
public string QueryString { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置用户 ID。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonProperty("uid")]
|
||||||
|
[System.Text.Json.Serialization.JsonPropertyName("uid")]
|
||||||
|
public string UserId { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置请求数据。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonProperty("data")]
|
||||||
|
[System.Text.Json.Serialization.JsonPropertyName("data")]
|
||||||
|
public Types.Data Data { get; set; } = new Types.Data();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,264 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
/* @codestyle-disable no-instantiated-property-in-response */
|
||||||
|
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// <para>表示 [POST] /openapi/nlp/ner-product/{TOKEN} 接口的响应。</para>
|
||||||
|
/// </summary>
|
||||||
|
public class OpenApiNLPNERProductResponse : WechatOpenAIResponse<OpenApiNLPNERProductResponse.Types.Data>
|
||||||
|
{
|
||||||
|
public static class Types
|
||||||
|
{
|
||||||
|
public class Data
|
||||||
|
{
|
||||||
|
public static class Types
|
||||||
|
{
|
||||||
|
public class Result
|
||||||
|
{
|
||||||
|
public static class Types
|
||||||
|
{
|
||||||
|
public class ProductProperty
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置商品属性名。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonIgnore]
|
||||||
|
[System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
public string Name { get; set; } = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置商品属性值。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonIgnore]
|
||||||
|
[System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
public string Value { get; set; } = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置起始字符位置。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonIgnore]
|
||||||
|
[System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
public int StartIndex { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置结束字符位置。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonIgnore]
|
||||||
|
[System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
public int EndIndex { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置结果。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonProperty("product")]
|
||||||
|
[Newtonsoft.Json.JsonConverter(typeof(Converters.NewtonsoftJsonProductPropertyArrayConverter))]
|
||||||
|
[System.Text.Json.Serialization.JsonPropertyName("product")]
|
||||||
|
[System.Text.Json.Serialization.JsonConverter(typeof(Converters.SystemTextJsonProductPropertyArrayConverter))]
|
||||||
|
public Types.ProductProperty[] ProductPropertyList { get; set; } = default!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置预处理后的文本。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonProperty("preprocessed_text")]
|
||||||
|
[System.Text.Json.Serialization.JsonPropertyName("preprocessed_text")]
|
||||||
|
public string PreprocessedText { get; set; } = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置抽取结果信息。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonProperty("entities")]
|
||||||
|
[Newtonsoft.Json.JsonConverter(typeof(Converters.NewtonsoftJsonProductPropertyArrayConverter))]
|
||||||
|
[System.Text.Json.Serialization.JsonPropertyName("entities")]
|
||||||
|
[System.Text.Json.Serialization.JsonConverter(typeof(Converters.SystemTextJsonProductPropertyArrayConverter))]
|
||||||
|
public Types.Result Result { get; set; } = default!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class Converters
|
||||||
|
{
|
||||||
|
internal class NewtonsoftJsonProductPropertyArrayConverter : Newtonsoft.Json.JsonConverter<Types.Data.Types.Result.Types.ProductProperty[]?>
|
||||||
|
{
|
||||||
|
public override bool CanRead
|
||||||
|
{
|
||||||
|
get { return true; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CanWrite
|
||||||
|
{
|
||||||
|
get { return true; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Types.Data.Types.Result.Types.ProductProperty[]? ReadJson(Newtonsoft.Json.JsonReader reader, Type objectType, Types.Data.Types.Result.Types.ProductProperty[]? existingValue, bool hasExistingValue, Newtonsoft.Json.JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
if (reader.TokenType == Newtonsoft.Json.JsonToken.Null)
|
||||||
|
{
|
||||||
|
return existingValue;
|
||||||
|
}
|
||||||
|
else if (reader.TokenType == Newtonsoft.Json.JsonToken.StartArray)
|
||||||
|
{
|
||||||
|
reader.Read();
|
||||||
|
|
||||||
|
var tmpList = new List<Types.Data.Types.Result.Types.ProductProperty>();
|
||||||
|
|
||||||
|
while (reader.TokenType != Newtonsoft.Json.JsonToken.EndArray)
|
||||||
|
{
|
||||||
|
if (reader.TokenType == Newtonsoft.Json.JsonToken.StartArray)
|
||||||
|
{
|
||||||
|
reader.Read();
|
||||||
|
|
||||||
|
int offset = 0;
|
||||||
|
var tmpItem = new Types.Data.Types.Result.Types.ProductProperty();
|
||||||
|
|
||||||
|
while (reader.TokenType != Newtonsoft.Json.JsonToken.EndArray)
|
||||||
|
{
|
||||||
|
if (offset == 0)
|
||||||
|
{
|
||||||
|
tmpItem.Value = serializer.Deserialize<string>(reader)!;
|
||||||
|
}
|
||||||
|
else if (offset == 1)
|
||||||
|
{
|
||||||
|
tmpItem.Name = serializer.Deserialize<string>(reader)!;
|
||||||
|
}
|
||||||
|
else if (offset == 2)
|
||||||
|
{
|
||||||
|
tmpItem.StartIndex = serializer.Deserialize<int>(reader);
|
||||||
|
}
|
||||||
|
else if (offset == 3)
|
||||||
|
{
|
||||||
|
tmpItem.EndIndex = serializer.Deserialize<int>(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
offset++;
|
||||||
|
reader.Read();
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpList.Add(tmpItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.Read();
|
||||||
|
}
|
||||||
|
|
||||||
|
return tmpList.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Newtonsoft.Json.JsonReaderException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void WriteJson(Newtonsoft.Json.JsonWriter writer, Types.Data.Types.Result.Types.ProductProperty[]? value, Newtonsoft.Json.JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
if (value != null)
|
||||||
|
{
|
||||||
|
writer.WriteStartArray();
|
||||||
|
|
||||||
|
foreach (var item in value)
|
||||||
|
{
|
||||||
|
writer.WriteStartArray();
|
||||||
|
writer.WriteValue(item.Value);
|
||||||
|
writer.WriteValue(item.Name);
|
||||||
|
writer.WriteValue(item.StartIndex);
|
||||||
|
writer.WriteValue(item.EndIndex);
|
||||||
|
writer.WriteEndArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.WriteEndArray();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writer.WriteNull();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class SystemTextJsonProductPropertyArrayConverter : System.Text.Json.Serialization.JsonConverter<Types.Data.Types.Result.Types.ProductProperty[]?>
|
||||||
|
{
|
||||||
|
public override Types.Data.Types.Result.Types.ProductProperty[]? Read(ref System.Text.Json.Utf8JsonReader reader, Type typeToConvert, System.Text.Json.JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
if (reader.TokenType == System.Text.Json.JsonTokenType.Null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else if (reader.TokenType == System.Text.Json.JsonTokenType.StartArray)
|
||||||
|
{
|
||||||
|
reader.Read();
|
||||||
|
|
||||||
|
var tmpList = new List<Types.Data.Types.Result.Types.ProductProperty>();
|
||||||
|
var tmpOptions = new System.Text.Json.JsonSerializerOptions(options);
|
||||||
|
|
||||||
|
while (reader.TokenType != System.Text.Json.JsonTokenType.EndArray)
|
||||||
|
{
|
||||||
|
if (reader.TokenType == System.Text.Json.JsonTokenType.StartArray)
|
||||||
|
{
|
||||||
|
reader.Read();
|
||||||
|
|
||||||
|
int offset = 0;
|
||||||
|
var tmpItem = new Types.Data.Types.Result.Types.ProductProperty();
|
||||||
|
|
||||||
|
while (reader.TokenType != System.Text.Json.JsonTokenType.EndArray)
|
||||||
|
{
|
||||||
|
if (offset == 0)
|
||||||
|
{
|
||||||
|
tmpItem.Value = System.Text.Json.JsonSerializer.Deserialize<string>(ref reader, tmpOptions)!;
|
||||||
|
}
|
||||||
|
else if (offset == 1)
|
||||||
|
{
|
||||||
|
tmpItem.Name = System.Text.Json.JsonSerializer.Deserialize<string>(ref reader, tmpOptions)!;
|
||||||
|
}
|
||||||
|
else if (offset == 2)
|
||||||
|
{
|
||||||
|
tmpItem.StartIndex = System.Text.Json.JsonSerializer.Deserialize<int>(ref reader, tmpOptions);
|
||||||
|
}
|
||||||
|
else if (offset == 3)
|
||||||
|
{
|
||||||
|
tmpItem.EndIndex = System.Text.Json.JsonSerializer.Deserialize<int>(ref reader, tmpOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
offset++;
|
||||||
|
reader.Read();
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpList.Add(tmpItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.Read();
|
||||||
|
}
|
||||||
|
|
||||||
|
return tmpList.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new System.Text.Json.JsonException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(System.Text.Json.Utf8JsonWriter writer, Types.Data.Types.Result.Types.ProductProperty[]? value, System.Text.Json.JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
if (value != null)
|
||||||
|
{
|
||||||
|
writer.WriteStartArray();
|
||||||
|
|
||||||
|
foreach (var item in value)
|
||||||
|
{
|
||||||
|
writer.WriteStartArray();
|
||||||
|
writer.WriteStringValue(item.Value);
|
||||||
|
writer.WriteStringValue(item.Name);
|
||||||
|
writer.WriteNumberValue(item.StartIndex);
|
||||||
|
writer.WriteNumberValue(item.EndIndex);
|
||||||
|
writer.WriteEndArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.WriteEndArray();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writer.WriteNullValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,38 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// <para>表示 [POST] /openapi/nlp/ner/{TOKEN} 接口的请求。</para>
|
||||||
|
/// </summary>
|
||||||
|
public class OpenApiNLPNERRequest : WechatOpenAIRequest, WechatOpenAIRequest.Serialization.IEncryptedUrlEncodedFormData
|
||||||
|
{
|
||||||
|
public static class Types
|
||||||
|
{
|
||||||
|
public class Data
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置输入文本。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonProperty("q")]
|
||||||
|
[System.Text.Json.Serialization.JsonPropertyName("q")]
|
||||||
|
public string QueryString { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置用户 ID。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonProperty("uid")]
|
||||||
|
[System.Text.Json.Serialization.JsonPropertyName("uid")]
|
||||||
|
public string UserId { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置请求数据。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonProperty("data")]
|
||||||
|
[System.Text.Json.Serialization.JsonPropertyName("data")]
|
||||||
|
public Types.Data Data { get; set; } = new Types.Data();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,45 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// <para>表示 [POST] /openapi/nlp/ner/{TOKEN} 接口的响应。</para>
|
||||||
|
/// </summary>
|
||||||
|
public class OpenApiNLPNERResponse : WechatOpenAIResponse<OpenApiNLPNERResponse.Types.Result[]>
|
||||||
|
{
|
||||||
|
public static class Types
|
||||||
|
{
|
||||||
|
public class Result
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置结果类型。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonProperty("type")]
|
||||||
|
[System.Text.Json.Serialization.JsonPropertyName("type")]
|
||||||
|
public string Type { get; set; } = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置范围列表。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonProperty("span")]
|
||||||
|
[System.Text.Json.Serialization.JsonPropertyName("span")]
|
||||||
|
public int[] SpanList { get; set; } = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置文本。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonProperty("text")]
|
||||||
|
[System.Text.Json.Serialization.JsonPropertyName("text")]
|
||||||
|
public string Text { get; set; } = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置范数。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonProperty("norm")]
|
||||||
|
[System.Text.Json.Serialization.JsonPropertyName("norm")]
|
||||||
|
public object Norm { get; set; } = default!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,45 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// <para>表示 [POST] /openapi/nlp/sensitive/{TOKEN} 接口的请求。</para>
|
||||||
|
/// </summary>
|
||||||
|
public class OpenApiNLPSensitiveRequest : WechatOpenAIRequest, WechatOpenAIRequest.Serialization.IEncryptedUrlEncodedFormData
|
||||||
|
{
|
||||||
|
public static class Types
|
||||||
|
{
|
||||||
|
public class Data
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置输入文本。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonProperty("q")]
|
||||||
|
[System.Text.Json.Serialization.JsonPropertyName("q")]
|
||||||
|
public string QueryString { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置模型。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonProperty("model")]
|
||||||
|
[System.Text.Json.Serialization.JsonPropertyName("model")]
|
||||||
|
public string? Model { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置用户 ID。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonProperty("uid")]
|
||||||
|
[System.Text.Json.Serialization.JsonPropertyName("uid")]
|
||||||
|
public string UserId { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置请求数据。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonProperty("data")]
|
||||||
|
[System.Text.Json.Serialization.JsonPropertyName("data")]
|
||||||
|
public Types.Data Data { get; set; } = new Types.Data();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,208 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
/* @codestyle-disable no-instantiated-property-in-response */
|
||||||
|
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// <para>表示 [POST] /openapi/nlp/sensitive/{TOKEN} 接口的响应。</para>
|
||||||
|
/// </summary>
|
||||||
|
public class OpenApiNLPSensitiveResponse : WechatOpenAIResponse<OpenApiNLPSensitiveResponse.Types.Data>
|
||||||
|
{
|
||||||
|
public static class Types
|
||||||
|
{
|
||||||
|
public class Data
|
||||||
|
{
|
||||||
|
public static class Types
|
||||||
|
{
|
||||||
|
public class Result
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置敏感信息项。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonIgnore]
|
||||||
|
[System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
public string Sensitive { get; set; } = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置分值(范围:0~1)。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonIgnore]
|
||||||
|
[System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
public double Score { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置结果。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonProperty("result")]
|
||||||
|
[Newtonsoft.Json.JsonConverter(typeof(Converters.NewtonsoftJsonResultArrayConverter))]
|
||||||
|
[System.Text.Json.Serialization.JsonPropertyName("result")]
|
||||||
|
[System.Text.Json.Serialization.JsonConverter(typeof(Converters.SystemTextJsonResultArrayConverter))]
|
||||||
|
public Types.Result[] ResultList { get; set; } = default!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class Converters
|
||||||
|
{
|
||||||
|
internal class NewtonsoftJsonResultArrayConverter : Newtonsoft.Json.JsonConverter<Types.Data.Types.Result[]?>
|
||||||
|
{
|
||||||
|
public override bool CanRead
|
||||||
|
{
|
||||||
|
get { return true; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CanWrite
|
||||||
|
{
|
||||||
|
get { return true; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Types.Data.Types.Result[]? ReadJson(Newtonsoft.Json.JsonReader reader, Type objectType, Types.Data.Types.Result[]? existingValue, bool hasExistingValue, Newtonsoft.Json.JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
if (reader.TokenType == Newtonsoft.Json.JsonToken.Null)
|
||||||
|
{
|
||||||
|
return existingValue;
|
||||||
|
}
|
||||||
|
else if (reader.TokenType == Newtonsoft.Json.JsonToken.StartArray)
|
||||||
|
{
|
||||||
|
reader.Read();
|
||||||
|
|
||||||
|
var tmpList = new List<Types.Data.Types.Result>();
|
||||||
|
|
||||||
|
while (reader.TokenType != Newtonsoft.Json.JsonToken.EndArray)
|
||||||
|
{
|
||||||
|
if (reader.TokenType == Newtonsoft.Json.JsonToken.StartArray)
|
||||||
|
{
|
||||||
|
reader.Read();
|
||||||
|
|
||||||
|
int offset = 0;
|
||||||
|
var tmpItem = new Types.Data.Types.Result();
|
||||||
|
|
||||||
|
while (reader.TokenType != Newtonsoft.Json.JsonToken.EndArray)
|
||||||
|
{
|
||||||
|
if (offset == 0)
|
||||||
|
{
|
||||||
|
tmpItem.Sensitive = serializer.Deserialize<string>(reader)!;
|
||||||
|
}
|
||||||
|
else if (offset == 1)
|
||||||
|
{
|
||||||
|
tmpItem.Score = serializer.Deserialize<double>(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
offset++;
|
||||||
|
reader.Read();
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpList.Add(tmpItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.Read();
|
||||||
|
}
|
||||||
|
|
||||||
|
return tmpList.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Newtonsoft.Json.JsonReaderException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void WriteJson(Newtonsoft.Json.JsonWriter writer, Types.Data.Types.Result[]? value, Newtonsoft.Json.JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
if (value != null)
|
||||||
|
{
|
||||||
|
writer.WriteStartArray();
|
||||||
|
|
||||||
|
foreach (var item in value)
|
||||||
|
{
|
||||||
|
writer.WriteStartArray();
|
||||||
|
writer.WriteValue(item.Sensitive);
|
||||||
|
writer.WriteValue(item.Score);
|
||||||
|
writer.WriteEndArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.WriteEndArray();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writer.WriteNull();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class SystemTextJsonResultArrayConverter : System.Text.Json.Serialization.JsonConverter<Types.Data.Types.Result[]?>
|
||||||
|
{
|
||||||
|
public override Types.Data.Types.Result[]? Read(ref System.Text.Json.Utf8JsonReader reader, Type typeToConvert, System.Text.Json.JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
if (reader.TokenType == System.Text.Json.JsonTokenType.Null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else if (reader.TokenType == System.Text.Json.JsonTokenType.StartArray)
|
||||||
|
{
|
||||||
|
reader.Read();
|
||||||
|
|
||||||
|
var tmpList = new List<Types.Data.Types.Result>();
|
||||||
|
var tmpOptions = new System.Text.Json.JsonSerializerOptions(options);
|
||||||
|
|
||||||
|
while (reader.TokenType != System.Text.Json.JsonTokenType.EndArray)
|
||||||
|
{
|
||||||
|
if (reader.TokenType == System.Text.Json.JsonTokenType.StartArray)
|
||||||
|
{
|
||||||
|
reader.Read();
|
||||||
|
|
||||||
|
int offset = 0;
|
||||||
|
var tmpItem = new Types.Data.Types.Result();
|
||||||
|
|
||||||
|
while (reader.TokenType != System.Text.Json.JsonTokenType.EndArray)
|
||||||
|
{
|
||||||
|
if (offset == 0)
|
||||||
|
{
|
||||||
|
tmpItem.Sensitive = System.Text.Json.JsonSerializer.Deserialize<string>(ref reader, tmpOptions)!;
|
||||||
|
}
|
||||||
|
else if (offset == 1)
|
||||||
|
{
|
||||||
|
tmpItem.Score = System.Text.Json.JsonSerializer.Deserialize<double>(ref reader, tmpOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
offset++;
|
||||||
|
reader.Read();
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpList.Add(tmpItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.Read();
|
||||||
|
}
|
||||||
|
|
||||||
|
return tmpList.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new System.Text.Json.JsonException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(System.Text.Json.Utf8JsonWriter writer, Types.Data.Types.Result[]? value, System.Text.Json.JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
if (value != null)
|
||||||
|
{
|
||||||
|
writer.WriteStartArray();
|
||||||
|
|
||||||
|
foreach (var item in value)
|
||||||
|
{
|
||||||
|
writer.WriteStartArray();
|
||||||
|
writer.WriteStringValue(item.Sensitive);
|
||||||
|
writer.WriteNumberValue(item.Score);
|
||||||
|
writer.WriteEndArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.WriteEndArray();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writer.WriteNullValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,45 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// <para>表示 [POST] /openapi/nlp/sentiment/{TOKEN} 接口的请求。</para>
|
||||||
|
/// </summary>
|
||||||
|
public class OpenApiNLPSentimentRequest : WechatOpenAIRequest, WechatOpenAIRequest.Serialization.IEncryptedUrlEncodedFormData
|
||||||
|
{
|
||||||
|
public static class Types
|
||||||
|
{
|
||||||
|
public class Data
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置输入文本。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonProperty("q")]
|
||||||
|
[System.Text.Json.Serialization.JsonPropertyName("q")]
|
||||||
|
public string QueryString { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置模式。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonProperty("mode")]
|
||||||
|
[System.Text.Json.Serialization.JsonPropertyName("mode")]
|
||||||
|
public string? Mode { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置用户 ID。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonProperty("uid")]
|
||||||
|
[System.Text.Json.Serialization.JsonPropertyName("uid")]
|
||||||
|
public string UserId { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置请求数据。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonProperty("data")]
|
||||||
|
[System.Text.Json.Serialization.JsonPropertyName("data")]
|
||||||
|
public Types.Data Data { get; set; } = new Types.Data();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,208 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
/* @codestyle-disable no-instantiated-property-in-response */
|
||||||
|
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// <para>表示 [POST] /openapi/nlp/sentiment/{TOKEN} 接口的响应。</para>
|
||||||
|
/// </summary>
|
||||||
|
public class OpenApiNLPSentimentResponse : WechatOpenAIResponse<OpenApiNLPSentimentResponse.Types.Data>
|
||||||
|
{
|
||||||
|
public static class Types
|
||||||
|
{
|
||||||
|
public class Data
|
||||||
|
{
|
||||||
|
public static class Types
|
||||||
|
{
|
||||||
|
public class Result
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置情感信息项。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonIgnore]
|
||||||
|
[System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
public string Sentiment { get; set; } = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置分值(范围:0~1)。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonIgnore]
|
||||||
|
[System.Text.Json.Serialization.JsonIgnore]
|
||||||
|
public double Score { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置结果。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonProperty("result")]
|
||||||
|
[Newtonsoft.Json.JsonConverter(typeof(Converters.NewtonsoftJsonResultArrayConverter))]
|
||||||
|
[System.Text.Json.Serialization.JsonPropertyName("result")]
|
||||||
|
[System.Text.Json.Serialization.JsonConverter(typeof(Converters.SystemTextJsonResultArrayConverter))]
|
||||||
|
public Types.Result[] ResultList { get; set; } = default!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class Converters
|
||||||
|
{
|
||||||
|
internal class NewtonsoftJsonResultArrayConverter : Newtonsoft.Json.JsonConverter<Types.Data.Types.Result[]?>
|
||||||
|
{
|
||||||
|
public override bool CanRead
|
||||||
|
{
|
||||||
|
get { return true; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CanWrite
|
||||||
|
{
|
||||||
|
get { return true; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Types.Data.Types.Result[]? ReadJson(Newtonsoft.Json.JsonReader reader, Type objectType, Types.Data.Types.Result[]? existingValue, bool hasExistingValue, Newtonsoft.Json.JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
if (reader.TokenType == Newtonsoft.Json.JsonToken.Null)
|
||||||
|
{
|
||||||
|
return existingValue;
|
||||||
|
}
|
||||||
|
else if (reader.TokenType == Newtonsoft.Json.JsonToken.StartArray)
|
||||||
|
{
|
||||||
|
reader.Read();
|
||||||
|
|
||||||
|
var tmpList = new List<Types.Data.Types.Result>();
|
||||||
|
|
||||||
|
while (reader.TokenType != Newtonsoft.Json.JsonToken.EndArray)
|
||||||
|
{
|
||||||
|
if (reader.TokenType == Newtonsoft.Json.JsonToken.StartArray)
|
||||||
|
{
|
||||||
|
reader.Read();
|
||||||
|
|
||||||
|
int offset = 0;
|
||||||
|
var tmpItem = new Types.Data.Types.Result();
|
||||||
|
|
||||||
|
while (reader.TokenType != Newtonsoft.Json.JsonToken.EndArray)
|
||||||
|
{
|
||||||
|
if (offset == 0)
|
||||||
|
{
|
||||||
|
tmpItem.Sentiment = serializer.Deserialize<string>(reader)!;
|
||||||
|
}
|
||||||
|
else if (offset == 1)
|
||||||
|
{
|
||||||
|
tmpItem.Score = serializer.Deserialize<double>(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
offset++;
|
||||||
|
reader.Read();
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpList.Add(tmpItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.Read();
|
||||||
|
}
|
||||||
|
|
||||||
|
return tmpList.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Newtonsoft.Json.JsonReaderException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void WriteJson(Newtonsoft.Json.JsonWriter writer, Types.Data.Types.Result[]? value, Newtonsoft.Json.JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
if (value != null)
|
||||||
|
{
|
||||||
|
writer.WriteStartArray();
|
||||||
|
|
||||||
|
foreach (var item in value)
|
||||||
|
{
|
||||||
|
writer.WriteStartArray();
|
||||||
|
writer.WriteValue(item.Sentiment);
|
||||||
|
writer.WriteValue(item.Score);
|
||||||
|
writer.WriteEndArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.WriteEndArray();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writer.WriteNull();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class SystemTextJsonResultArrayConverter : System.Text.Json.Serialization.JsonConverter<Types.Data.Types.Result[]?>
|
||||||
|
{
|
||||||
|
public override Types.Data.Types.Result[]? Read(ref System.Text.Json.Utf8JsonReader reader, Type typeToConvert, System.Text.Json.JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
if (reader.TokenType == System.Text.Json.JsonTokenType.Null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else if (reader.TokenType == System.Text.Json.JsonTokenType.StartArray)
|
||||||
|
{
|
||||||
|
reader.Read();
|
||||||
|
|
||||||
|
var tmpList = new List<Types.Data.Types.Result>();
|
||||||
|
var tmpOptions = new System.Text.Json.JsonSerializerOptions(options);
|
||||||
|
|
||||||
|
while (reader.TokenType != System.Text.Json.JsonTokenType.EndArray)
|
||||||
|
{
|
||||||
|
if (reader.TokenType == System.Text.Json.JsonTokenType.StartArray)
|
||||||
|
{
|
||||||
|
reader.Read();
|
||||||
|
|
||||||
|
int offset = 0;
|
||||||
|
var tmpItem = new Types.Data.Types.Result();
|
||||||
|
|
||||||
|
while (reader.TokenType != System.Text.Json.JsonTokenType.EndArray)
|
||||||
|
{
|
||||||
|
if (offset == 0)
|
||||||
|
{
|
||||||
|
tmpItem.Sentiment = System.Text.Json.JsonSerializer.Deserialize<string>(ref reader, tmpOptions)!;
|
||||||
|
}
|
||||||
|
else if (offset == 1)
|
||||||
|
{
|
||||||
|
tmpItem.Score = System.Text.Json.JsonSerializer.Deserialize<double>(ref reader, tmpOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
offset++;
|
||||||
|
reader.Read();
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpList.Add(tmpItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.Read();
|
||||||
|
}
|
||||||
|
|
||||||
|
return tmpList.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new System.Text.Json.JsonException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(System.Text.Json.Utf8JsonWriter writer, Types.Data.Types.Result[]? value, System.Text.Json.JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
if (value != null)
|
||||||
|
{
|
||||||
|
writer.WriteStartArray();
|
||||||
|
|
||||||
|
foreach (var item in value)
|
||||||
|
{
|
||||||
|
writer.WriteStartArray();
|
||||||
|
writer.WriteStringValue(item.Sentiment);
|
||||||
|
writer.WriteNumberValue(item.Score);
|
||||||
|
writer.WriteEndArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.WriteEndArray();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writer.WriteNullValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,38 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// <para>表示 [POST] /openapi/nlp/tokenize/{TOKEN} 接口的请求。</para>
|
||||||
|
/// </summary>
|
||||||
|
public class OpenApiNLPTokenizeRequest : WechatOpenAIRequest, WechatOpenAIRequest.Serialization.IEncryptedUrlEncodedFormData
|
||||||
|
{
|
||||||
|
public static class Types
|
||||||
|
{
|
||||||
|
public class Data
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置输入文本。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonProperty("q")]
|
||||||
|
[System.Text.Json.Serialization.JsonPropertyName("q")]
|
||||||
|
public string QueryString { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置用户 ID。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonProperty("uid")]
|
||||||
|
[System.Text.Json.Serialization.JsonPropertyName("uid")]
|
||||||
|
public string UserId { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置请求数据。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonProperty("data")]
|
||||||
|
[System.Text.Json.Serialization.JsonPropertyName("data")]
|
||||||
|
public Types.Data Data { get; set; } = new Types.Data();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,59 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// <para>表示 [POST] /openapi/nlp/tokenize/{TOKEN} 接口的响应。</para>
|
||||||
|
/// </summary>
|
||||||
|
public class OpenApiNLPTokenizeResponse : WechatOpenAIResponse<OpenApiNLPTokenizeResponse.Types.Data>
|
||||||
|
{
|
||||||
|
public static class Types
|
||||||
|
{
|
||||||
|
public class Data
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置常规粒度分词结果列表。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonProperty("words")]
|
||||||
|
[System.Text.Json.Serialization.JsonPropertyName("words")]
|
||||||
|
public string[] WordList { get; set; } = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置常规粒度词性标签列表。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonProperty("POSs")]
|
||||||
|
[System.Text.Json.Serialization.JsonPropertyName("POSs")]
|
||||||
|
public int[] POSList { get; set; } = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置混合粒度分词结果列表。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonProperty("words_mix")]
|
||||||
|
[System.Text.Json.Serialization.JsonPropertyName("words_mix")]
|
||||||
|
public string[] WordMixList { get; set; } = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置混合粒度词性标签列表。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonProperty("POSs_mix")]
|
||||||
|
[System.Text.Json.Serialization.JsonPropertyName("POSs_mix")]
|
||||||
|
public int[] POSMixList { get; set; } = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置短语提取结果列表。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonProperty("entities")]
|
||||||
|
[System.Text.Json.Serialization.JsonPropertyName("entities")]
|
||||||
|
public string[] EntityList { get; set; } = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置短语类型标签列表。
|
||||||
|
/// </summary>
|
||||||
|
[Newtonsoft.Json.JsonProperty("entity_types")]
|
||||||
|
[System.Text.Json.Serialization.JsonPropertyName("entity_types")]
|
||||||
|
public int[] EntityTypeList { get; set; } = default!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -9,7 +9,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
|
|||||||
public class UserRegisterRequest : WechatOpenAIRequest
|
public class UserRegisterRequest : WechatOpenAIRequest
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取或设置平台自定义用户名。
|
/// 获取或设置用户 ID。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Newtonsoft.Json.JsonProperty("uid")]
|
[Newtonsoft.Json.JsonProperty("uid")]
|
||||||
[System.Text.Json.Serialization.JsonPropertyName("uid")]
|
[System.Text.Json.Serialization.JsonPropertyName("uid")]
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="JWT" Version="8.4.2" />
|
||||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
|
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
@@ -24,14 +24,14 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Settings
|
|||||||
public string? AppId { get; }
|
public string? AppId { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 初始化客户端时 <see cref="WechatOpenAIClientOptions.PushToken"/> 的副本。
|
/// 初始化客户端时 <see cref="WechatOpenAIClientOptions.Token"/> 的副本。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? PushToken { get; }
|
public string? Token { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 初始化客户端时 <see cref="WechatOpenAIClientOptions.PushEncodingAESKey"/> 的副本。
|
/// 初始化客户端时 <see cref="WechatOpenAIClientOptions.EncodingAESKey"/> 的副本。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? PushEncodingAESKey { get; }
|
public string? EncodingAESKey { get; }
|
||||||
|
|
||||||
internal Credentials(WechatOpenAIClientOptions options)
|
internal Credentials(WechatOpenAIClientOptions options)
|
||||||
{
|
{
|
||||||
@@ -40,8 +40,8 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Settings
|
|||||||
ClientId = options.ClientId;
|
ClientId = options.ClientId;
|
||||||
ClientKey = options.ClientKey;
|
ClientKey = options.ClientKey;
|
||||||
AppId = options.AppId;
|
AppId = options.AppId;
|
||||||
PushToken = options.PushToken;
|
Token = options.Token;
|
||||||
PushEncodingAESKey = options.PushEncodingAESKey;
|
EncodingAESKey = options.EncodingAESKey;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,25 @@
|
|||||||
|
using System;
|
||||||
|
using JWT;
|
||||||
|
using JWT.Algorithms;
|
||||||
|
using JWT.Serializers;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Utilities
|
||||||
|
{
|
||||||
|
internal static class JWTUtility
|
||||||
|
{
|
||||||
|
private static readonly Lazy<IJwtEncoder> _encoder = new Lazy<IJwtEncoder>(() =>
|
||||||
|
{
|
||||||
|
IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
|
||||||
|
IJsonSerializer serializer = new JsonNetSerializer(new JsonSerializer() { NullValueHandling = NullValueHandling.Ignore });
|
||||||
|
IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
|
||||||
|
IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);
|
||||||
|
return encoder;
|
||||||
|
}, isThreadSafe: true);
|
||||||
|
|
||||||
|
public static string EncodeWithHS256(object payload, string secret)
|
||||||
|
{
|
||||||
|
return _encoder.Value.Encode(payload, secret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -115,7 +115,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
|
|||||||
if (data is WechatOpenAIRequest.Serialization.IEncryptedXmlable)
|
if (data is WechatOpenAIRequest.Serialization.IEncryptedXmlable)
|
||||||
{
|
{
|
||||||
string plainXml = Utilities.XmlUtility.Serialize(data);
|
string plainXml = Utilities.XmlUtility.Serialize(data);
|
||||||
string encryptedXml = Utilities.WxBizMsgCryptor.AESEncrypt(plainText: plainXml, encodingAESKey: Credentials.PushEncodingAESKey!, appId: Credentials.AppId!);
|
string encryptedXml = Utilities.WxBizMsgCryptor.AESEncrypt(plainText: plainXml, encodingAESKey: Credentials.EncodingAESKey!, appId: Credentials.AppId!);
|
||||||
data = new { encrypt = encryptedXml };
|
data = new { encrypt = encryptedXml };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,6 +128,38 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 异步发起请求。
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <param name="flurlRequest"></param>
|
||||||
|
/// <param name="data"></param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<T> SendRequestWithUrlEncodedAsync<T>(IFlurlRequest flurlRequest, object? data = null, CancellationToken cancellationToken = default)
|
||||||
|
where T : WechatOpenAIResponse, new()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (data is WechatOpenAIRequest.Serialization.IEncryptedUrlEncodedFormData)
|
||||||
|
{
|
||||||
|
string jwt = Utilities.JWTUtility.EncodeWithHS256(payload: data, secret: Credentials.EncodingAESKey!);
|
||||||
|
data = new { query = jwt };
|
||||||
|
}
|
||||||
|
|
||||||
|
using IFlurlResponse flurlResponse = await flurlRequest
|
||||||
|
.WithClient(FlurlClient)
|
||||||
|
.AllowAnyHttpStatus()
|
||||||
|
.SendUrlEncodedAsync(flurlRequest.Verb, data, cancellationToken)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
return await GetResposneAsync<T>(flurlResponse).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
catch (FlurlHttpException ex)
|
||||||
|
{
|
||||||
|
throw new WechatOpenAIException(ex.Message, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<T> GetResposneAsync<T>(IFlurlResponse flurlResponse)
|
private async Task<T> GetResposneAsync<T>(IFlurlResponse flurlResponse)
|
||||||
where T : WechatOpenAIResponse, new()
|
where T : WechatOpenAIResponse, new()
|
||||||
{
|
{
|
||||||
|
@@ -33,13 +33,13 @@
|
|||||||
public string? AppId { get; set; }
|
public string? AppId { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取或设置微信智能对话服务器推送的 EncodingAESKey。仅限平台接入时使用。
|
/// 获取或设置微信智能对话 Token。仅限平台接入时使用。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? PushEncodingAESKey { get; set; }
|
public string? Token { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取或设置微信智能对话服务器推送的 Token。仅限平台接入时使用。
|
/// 获取或设置微信智能对话 EncodingAESKey。仅限平台接入时使用。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? PushToken { get; set; }
|
public string? EncodingAESKey { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -12,6 +12,10 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
|
|||||||
public interface IEncryptedXmlable
|
public interface IEncryptedXmlable
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface IEncryptedUrlEncodedFormData
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
/* @codestyle-disable no-jsonable-property-in-get */
|
/* @codestyle-disable no-jsonable-property-in-request-get */
|
||||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
|
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"uid": "xjlsj33lasfaf",
|
||||||
|
"data": {
|
||||||
|
"q": "帮我订两张后天上午的火车票"
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"type": "number",
|
||||||
|
"span": [
|
||||||
|
3,
|
||||||
|
4
|
||||||
|
],
|
||||||
|
"text": "两",
|
||||||
|
"norm": "2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "datetime_interval",
|
||||||
|
"span": [
|
||||||
|
5,
|
||||||
|
9
|
||||||
|
],
|
||||||
|
"text": "后天上午",
|
||||||
|
"norm": "2019-10-30 08:00:00~2019-10-30 11:59:59"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"uid": "xjlsj33lasfaf",
|
||||||
|
"data": {
|
||||||
|
"q": "楼主真垃圾,祝你早日死全家",
|
||||||
|
"model": "cnnn"
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"result": [
|
||||||
|
[
|
||||||
|
"dirty_curse",
|
||||||
|
0.9999999900000001
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"other",
|
||||||
|
9.9999999E-9
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"dirty_politics",
|
||||||
|
0.0
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"dirty_porno",
|
||||||
|
0.0
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"uid": "xjlsj33lasfaf",
|
||||||
|
"data": {
|
||||||
|
"q": "恭喜小张脱单成功",
|
||||||
|
"mode": "3class"
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"result": [
|
||||||
|
[
|
||||||
|
"正面",
|
||||||
|
0.9593541622161865
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"无情感",
|
||||||
|
0.0400625541806221
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"负面",
|
||||||
|
0.000583284127060324
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"uid": "xjlsj33lasfaf",
|
||||||
|
"data": {
|
||||||
|
"q": "在微信智言与微信智聆两大技术的支持下,微信AI团队推出了“微信对话开放平台”和“腾讯小微”智能硬件两大核心产品。微信支付团队最新发布的“微信青蛙Pro”在现场设置了体验区,让大家感受AI认脸的本事。"
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,284 @@
|
|||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"words": [
|
||||||
|
"在",
|
||||||
|
"微信",
|
||||||
|
"智",
|
||||||
|
"言",
|
||||||
|
"与",
|
||||||
|
"微信",
|
||||||
|
"智",
|
||||||
|
"聆",
|
||||||
|
"两",
|
||||||
|
"大",
|
||||||
|
"技术",
|
||||||
|
"的",
|
||||||
|
"支持",
|
||||||
|
"下",
|
||||||
|
",",
|
||||||
|
"微信",
|
||||||
|
"ai",
|
||||||
|
"团队",
|
||||||
|
"推出",
|
||||||
|
"了",
|
||||||
|
"“",
|
||||||
|
"微信",
|
||||||
|
"对话",
|
||||||
|
"开放",
|
||||||
|
"平台",
|
||||||
|
"”",
|
||||||
|
"和",
|
||||||
|
"“",
|
||||||
|
"腾讯",
|
||||||
|
"小",
|
||||||
|
"微",
|
||||||
|
"”",
|
||||||
|
"智能",
|
||||||
|
"硬件",
|
||||||
|
"两",
|
||||||
|
"大",
|
||||||
|
"核心",
|
||||||
|
"产品",
|
||||||
|
"。",
|
||||||
|
"微信",
|
||||||
|
"支付",
|
||||||
|
"团队",
|
||||||
|
"最新",
|
||||||
|
"发布",
|
||||||
|
"的",
|
||||||
|
"“",
|
||||||
|
"微信",
|
||||||
|
"青蛙",
|
||||||
|
"pro",
|
||||||
|
"”",
|
||||||
|
"在",
|
||||||
|
"现场",
|
||||||
|
"设置",
|
||||||
|
"了",
|
||||||
|
"体验",
|
||||||
|
"区",
|
||||||
|
",",
|
||||||
|
"让",
|
||||||
|
"大家",
|
||||||
|
"感受",
|
||||||
|
"ai",
|
||||||
|
"认",
|
||||||
|
"脸",
|
||||||
|
"的",
|
||||||
|
"本事",
|
||||||
|
"。"
|
||||||
|
],
|
||||||
|
"POSs": [
|
||||||
|
25,
|
||||||
|
16,
|
||||||
|
16,
|
||||||
|
46,
|
||||||
|
25,
|
||||||
|
16,
|
||||||
|
16,
|
||||||
|
46,
|
||||||
|
15,
|
||||||
|
1,
|
||||||
|
16,
|
||||||
|
30,
|
||||||
|
33,
|
||||||
|
8,
|
||||||
|
34,
|
||||||
|
31,
|
||||||
|
23,
|
||||||
|
16,
|
||||||
|
31,
|
||||||
|
36,
|
||||||
|
34,
|
||||||
|
16,
|
||||||
|
33,
|
||||||
|
33,
|
||||||
|
16,
|
||||||
|
34,
|
||||||
|
5,
|
||||||
|
34,
|
||||||
|
6,
|
||||||
|
1,
|
||||||
|
38,
|
||||||
|
34,
|
||||||
|
16,
|
||||||
|
16,
|
||||||
|
15,
|
||||||
|
1,
|
||||||
|
16,
|
||||||
|
16,
|
||||||
|
34,
|
||||||
|
6,
|
||||||
|
31,
|
||||||
|
16,
|
||||||
|
1,
|
||||||
|
31,
|
||||||
|
30,
|
||||||
|
34,
|
||||||
|
31,
|
||||||
|
16,
|
||||||
|
23,
|
||||||
|
34,
|
||||||
|
25,
|
||||||
|
28,
|
||||||
|
31,
|
||||||
|
30,
|
||||||
|
33,
|
||||||
|
16,
|
||||||
|
34,
|
||||||
|
31,
|
||||||
|
27,
|
||||||
|
31,
|
||||||
|
23,
|
||||||
|
31,
|
||||||
|
16,
|
||||||
|
30,
|
||||||
|
16,
|
||||||
|
34
|
||||||
|
],
|
||||||
|
"words_mix": [
|
||||||
|
"在",
|
||||||
|
"微信",
|
||||||
|
"智",
|
||||||
|
"言",
|
||||||
|
"与",
|
||||||
|
"微信",
|
||||||
|
"智",
|
||||||
|
"聆",
|
||||||
|
"两",
|
||||||
|
"大",
|
||||||
|
"技术",
|
||||||
|
"的",
|
||||||
|
"支持",
|
||||||
|
"下",
|
||||||
|
",",
|
||||||
|
"微信",
|
||||||
|
"ai",
|
||||||
|
"团队",
|
||||||
|
"推出",
|
||||||
|
"了",
|
||||||
|
"“",
|
||||||
|
"微信",
|
||||||
|
"对话",
|
||||||
|
"开放",
|
||||||
|
"平台",
|
||||||
|
"”",
|
||||||
|
"和",
|
||||||
|
"“",
|
||||||
|
"腾讯",
|
||||||
|
"小微",
|
||||||
|
"”",
|
||||||
|
"智能",
|
||||||
|
"硬件",
|
||||||
|
"两",
|
||||||
|
"大",
|
||||||
|
"核心",
|
||||||
|
"产品",
|
||||||
|
"。",
|
||||||
|
"微信",
|
||||||
|
"支付",
|
||||||
|
"团队",
|
||||||
|
"最新",
|
||||||
|
"发布",
|
||||||
|
"的",
|
||||||
|
"“",
|
||||||
|
"微信",
|
||||||
|
"青蛙",
|
||||||
|
"pro",
|
||||||
|
"”",
|
||||||
|
"在",
|
||||||
|
"现场",
|
||||||
|
"设置",
|
||||||
|
"了",
|
||||||
|
"体验",
|
||||||
|
"区",
|
||||||
|
",",
|
||||||
|
"让",
|
||||||
|
"大家",
|
||||||
|
"感受",
|
||||||
|
"ai",
|
||||||
|
"认",
|
||||||
|
"脸",
|
||||||
|
"的",
|
||||||
|
"本事",
|
||||||
|
"。"
|
||||||
|
],
|
||||||
|
"POSs_mix": [
|
||||||
|
25,
|
||||||
|
16,
|
||||||
|
16,
|
||||||
|
46,
|
||||||
|
25,
|
||||||
|
16,
|
||||||
|
16,
|
||||||
|
46,
|
||||||
|
15,
|
||||||
|
1,
|
||||||
|
16,
|
||||||
|
30,
|
||||||
|
33,
|
||||||
|
8,
|
||||||
|
34,
|
||||||
|
31,
|
||||||
|
23,
|
||||||
|
16,
|
||||||
|
31,
|
||||||
|
36,
|
||||||
|
34,
|
||||||
|
16,
|
||||||
|
33,
|
||||||
|
33,
|
||||||
|
16,
|
||||||
|
34,
|
||||||
|
5,
|
||||||
|
34,
|
||||||
|
6,
|
||||||
|
16,
|
||||||
|
34,
|
||||||
|
16,
|
||||||
|
16,
|
||||||
|
15,
|
||||||
|
1,
|
||||||
|
16,
|
||||||
|
16,
|
||||||
|
34,
|
||||||
|
6,
|
||||||
|
31,
|
||||||
|
16,
|
||||||
|
1,
|
||||||
|
31,
|
||||||
|
30,
|
||||||
|
34,
|
||||||
|
31,
|
||||||
|
16,
|
||||||
|
23,
|
||||||
|
34,
|
||||||
|
25,
|
||||||
|
28,
|
||||||
|
31,
|
||||||
|
30,
|
||||||
|
33,
|
||||||
|
16,
|
||||||
|
34,
|
||||||
|
31,
|
||||||
|
27,
|
||||||
|
31,
|
||||||
|
23,
|
||||||
|
31,
|
||||||
|
16,
|
||||||
|
30,
|
||||||
|
16,
|
||||||
|
34
|
||||||
|
],
|
||||||
|
"entities": [
|
||||||
|
"腾讯",
|
||||||
|
"小微",
|
||||||
|
"最新发布"
|
||||||
|
],
|
||||||
|
"entity_types": [
|
||||||
|
100000013,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
@@ -9,7 +9,10 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests
|
|||||||
Instance = new WechatOpenAIClient(new WechatOpenAIClientOptions()
|
Instance = new WechatOpenAIClient(new WechatOpenAIClientOptions()
|
||||||
{
|
{
|
||||||
ClientId = TestConfigs.WechatClientId,
|
ClientId = TestConfigs.WechatClientId,
|
||||||
ClientKey = TestConfigs.WechatClientKey
|
ClientKey = TestConfigs.WechatClientKey,
|
||||||
|
AppId = TestConfigs.WechatAppId,
|
||||||
|
Token = TestConfigs.WechatToken,
|
||||||
|
EncodingAESKey = TestConfigs.WechatEncodingAESKey
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -17,6 +17,9 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests
|
|||||||
var config = json.RootElement.GetProperty("WechatConfig");
|
var config = json.RootElement.GetProperty("WechatConfig");
|
||||||
WechatClientId = config.GetProperty("ClientId").GetString();
|
WechatClientId = config.GetProperty("ClientId").GetString();
|
||||||
WechatClientKey = config.GetProperty("ClientKey").GetString();
|
WechatClientKey = config.GetProperty("ClientKey").GetString();
|
||||||
|
WechatAppId = config.GetProperty("AppId").GetString();
|
||||||
|
WechatToken = config.GetProperty("Token").GetString();
|
||||||
|
WechatEncodingAESKey = config.GetProperty("EncodingAESKey").GetString();
|
||||||
WechatAccessToken = config.GetProperty("AccessToken").GetString();
|
WechatAccessToken = config.GetProperty("AccessToken").GetString();
|
||||||
|
|
||||||
ProjectSourceDirectory = json.RootElement.GetProperty("ProjectSourceDirectory").GetString();
|
ProjectSourceDirectory = json.RootElement.GetProperty("ProjectSourceDirectory").GetString();
|
||||||
@@ -25,6 +28,9 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests
|
|||||||
|
|
||||||
public static readonly string WechatClientId;
|
public static readonly string WechatClientId;
|
||||||
public static readonly string WechatClientKey;
|
public static readonly string WechatClientKey;
|
||||||
|
public static readonly string WechatAppId;
|
||||||
|
public static readonly string WechatToken;
|
||||||
|
public static readonly string WechatEncodingAESKey;
|
||||||
public static readonly string WechatAccessToken;
|
public static readonly string WechatAccessToken;
|
||||||
|
|
||||||
public static readonly string ProjectSourceDirectory;
|
public static readonly string ProjectSourceDirectory;
|
||||||
|
@@ -0,0 +1,32 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests
|
||||||
|
{
|
||||||
|
public class WechatOpenAIJWTTests
|
||||||
|
{
|
||||||
|
[Fact(DisplayName = "JWT 编码(HS256)")]
|
||||||
|
public void JWTEncodeWithHS256Test()
|
||||||
|
{
|
||||||
|
object payload = new
|
||||||
|
{
|
||||||
|
uid = "xjlsj33lasfaf",
|
||||||
|
data = new
|
||||||
|
{
|
||||||
|
q = "在微信智言与微信智聆两大技术的支持下,微信AI团队推出了“微信对话开放平台”和“腾讯小微”智能硬件两大核心产品。微信支付团队最新发布的“微信青蛙Pro”在现场设置了体验区,让大家感受AI认脸的本事。"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
string secret = "jWmYm7qr5nMoAUwZRjGtBxmz3KA1tkAj3ykkR6q2B2C";
|
||||||
|
|
||||||
|
string actualJwt = Utilities.JWTUtility.EncodeWithHS256(payload: payload, secret: secret);
|
||||||
|
string expectdJwt = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1aWQiOiJ4amxzajMzbGFzZmFmIiwiZGF0YSI6eyJxIjoi5Zyo5b6u5L-h5pm66KiA5LiO5b6u5L-h5pm66IGG5Lik5aSn5oqA5pyv55qE5pSv5oyB5LiL77yM5b6u5L-hQUnlm6LpmJ_mjqjlh7rkuobigJzlvq7kv6Hlr7nor53lvIDmlL7lubPlj7DigJ3lkozigJzohb7orq_lsI_lvq7igJ3mmbrog73noazku7bkuKTlpKfmoLjlv4Pkuqflk4HjgILlvq7kv6HmlK_ku5jlm6LpmJ_mnIDmlrDlj5HluIPnmoTigJzlvq7kv6HpnZLom5lQcm_igJ3lnKjnjrDlnLrorr7nva7kuobkvZPpqozljLrvvIzorqnlpKflrrbmhJ_lj5dBSeiupOiEuOeahOacrOS6i-OAgiJ9fQ.8FeSvxKlIrbI6MCAaWGekB4sHGA8DeUxgVXiHa8ulJk";
|
||||||
|
|
||||||
|
Assert.Equal(expectdJwt, actualJwt, ignoreCase: true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -497,7 +497,7 @@ namespace SKIT.FlurlHttpClient.Wechat
|
|||||||
// 如果是 GET 请求,检查是否包含 JSON 序列化字段
|
// 如果是 GET 请求,检查是否包含 JSON 序列化字段
|
||||||
if ("GET".Equals(expectedRequestMethod, StringComparison.OrdinalIgnoreCase))
|
if ("GET".Equals(expectedRequestMethod, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
if (!(reqCodeSourceCode.Contains("/* @codestyle-disable") && reqCodeSourceCode.Contains("no-jsonable-property-in-get")))
|
if (!(reqCodeSourceCode.Contains("/* @codestyle-disable") && reqCodeSourceCode.Contains("no-jsonable-property-in-request-get")))
|
||||||
{
|
{
|
||||||
if (new Regex("\\[Newtonsoft.Json.JsonProperty\\(\"[a-zA-Z0-9_]*\"\\)\\]").IsMatch(reqCodeSourceCode))
|
if (new Regex("\\[Newtonsoft.Json.JsonProperty\\(\"[a-zA-Z0-9_]*\"\\)\\]").IsMatch(reqCodeSourceCode))
|
||||||
{
|
{
|
||||||
@@ -560,10 +560,13 @@ namespace SKIT.FlurlHttpClient.Wechat
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 检验是否包含 `new class()` 的赋值
|
// 检验是否包含 `new class()` 的赋值
|
||||||
if (new Regex("=\\s*new\\s[a-zA-Z0-9.]*\\(\\)").IsMatch(resCodeSourceCode))
|
if (!(resCodeSourceCode.Contains("/* @codestyle-disable") && resCodeSourceCode.Contains("no-instantiated-property-in-response")))
|
||||||
{
|
{
|
||||||
lstError.Add(new Exception($"源代码 \"{resCodeFileName}\" 下代码有误,请求模型不应包含 `= new class()` 赋值。"));
|
if (new Regex("=\\s*new\\s[a-zA-Z0-9.]*\\(\\)").IsMatch(resCodeSourceCode))
|
||||||
return false;
|
{
|
||||||
|
lstError.Add(new Exception($"源代码 \"{resCodeFileName}\" 下代码有误,响应模型不应包含 `= new class()` 赋值。"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检验是否包含列表类型字段
|
// 检验是否包含列表类型字段
|
||||||
|
Reference in New Issue
Block a user