diff --git a/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Events/ThirdKf/UserEnterEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Events/ThirdKf/UserEnterEvent.cs
new file mode 100644
index 00000000..522eb3ba
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Events/ThirdKf/UserEnterEvent.cs
@@ -0,0 +1,60 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Events
+{
+ ///
+ /// 表示 userEnter 事件的数据。
+ /// REF: https://developers.weixin.qq.com/doc/aispeech/platform/thirdkefu/recivemsg.html
+ ///
+ public class UserEnterEvent : WechatOpenAIEvent, WechatOpenAIEvent.Serialization.IXmlSerializable
+ {
+ public static class Types
+ {
+ public class Content
+ {
+ ///
+ /// 获取或设置消息。
+ ///
+ [System.Xml.Serialization.XmlElement("msg")]
+ public string Message { get; set; } = default!;
+ }
+ }
+
+ ///
+ /// 获取或设置用户 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("userid")]
+ public string UserId { get; set; } = default!;
+
+ ///
+ /// 获取或设置对话来源。
+ ///
+ [System.Xml.Serialization.XmlElement("from")]
+ public string From { get; set; } = default!;
+
+ ///
+ /// 获取或设置消息内容。
+ ///
+ [System.Xml.Serialization.XmlElement("content")]
+ public Types.Content? Content { get; set; }
+
+ ///
+ /// 获取或设置客服接入状态。
+ ///
+ [System.Xml.Serialization.XmlElement("status")]
+ public int Status { get; set; }
+
+ ///
+ /// 获取或设置渠道。
+ ///
+ [System.Xml.Serialization.XmlElement("channel", IsNullable = true)]
+ public string? Channel { get; set; }
+
+ ///
+ /// 获取或设置用户评价。
+ ///
+ [System.Xml.Serialization.XmlElement("assessment", IsNullable = true)]
+ public int? Assessment { get; set; }
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Events/ThirdKf/UserQuitEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Events/ThirdKf/UserQuitEvent.cs
new file mode 100644
index 00000000..ae2bb8d1
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Events/ThirdKf/UserQuitEvent.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Events
+{
+ ///
+ /// 表示 userQuit 事件的数据。
+ /// REF: https://developers.weixin.qq.com/doc/aispeech/platform/thirdkefu/recivemsg.html
+ ///
+ public class UserQuitEvent : UserEnterEvent
+ {
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Extensions/WechatOpenAIClientEventExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Extensions/WechatOpenAIClientEventExtensions.cs
index 82694c5b..b0cb77ed 100644
--- a/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Extensions/WechatOpenAIClientEventExtensions.cs
+++ b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Extensions/WechatOpenAIClientEventExtensions.cs
@@ -98,18 +98,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
try
{
- using var stream = new MemoryStream();
- using var writer = new System.Xml.XmlTextWriter(stream, Encoding.UTF8);
- writer.Formatting = System.Xml.Formatting.None;
-
- XmlSerializer xmlSerializer = new XmlSerializer(typeof(TEvent), new XmlRootAttribute("xml"));
- XmlSerializerNamespaces xmlNamespace = new XmlSerializerNamespaces();
- xmlNamespace.Add(string.Empty, string.Empty);
- xmlSerializer.Serialize(writer, callbackModel, xmlNamespace);
- writer.Flush();
- xml = Encoding.UTF8.GetString(stream.ToArray());
- xml = Regex.Replace(xml, "\\s+<\\w+ (xsi|d2p1):nil=\"true\"[^>]*/>", string.Empty, RegexOptions.IgnoreCase);
- xml = Regex.Replace(xml, "<\\?xml[^>]*\\?>", string.Empty, RegexOptions.IgnoreCase);
+ xml = Utilities.XmlUtility.Serialize(callbackModel);
}
catch (Exception ex)
{
diff --git a/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Extensions/WechatOpenAIClientExecuteOpenApiThirdKfExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Extensions/WechatOpenAIClientExecuteOpenApiThirdKfExtensions.cs
new file mode 100644
index 00000000..ffd9dbb8
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Extensions/WechatOpenAIClientExecuteOpenApiThirdKfExtensions.cs
@@ -0,0 +1,72 @@
+using System;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Flurl;
+using Flurl.Http;
+
+namespace SKIT.FlurlHttpClient.Wechat.OpenAI
+{
+ public static class WechatOpenAIClientExecuteOpenApiThirdKfExtensions
+ {
+ ///
+ /// 异步调用 [POST] /openapi/sendmsg/{TOKEN} 接口。
+ /// REF: https://developers.weixin.qq.com/doc/aispeech/platform/thirdkefu/sendmsg.html
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static async Task ExecuteOpenApiSendMessageAsync(this WechatOpenAIClient client, Models.OpenApiSendMessageRequest 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", "sendmsg", client.Credentials.PushToken!);
+
+ return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken);
+ }
+
+ ///
+ /// 异步调用 [POST] /openapi/kefustate/get/{TOKEN} 接口。
+ /// REF: https://developers.weixin.qq.com/doc/aispeech/platform/thirdkefu/getstate.html
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static async Task ExecuteOpenApiKefuStateGetAsync(this WechatOpenAIClient client, Models.OpenApiKefuStateGetRequest 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", "kefustate", "get", client.Credentials.PushToken!);
+
+ return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken);
+ }
+
+ ///
+ /// 异步调用 [POST] /openapi/kefustate/change/{TOKEN} 接口。
+ /// REF: https://developers.weixin.qq.com/doc/aispeech/platform/thirdkefu/getstate.html
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static async Task ExecuteOpenApiKefuStateChangeAsync(this WechatOpenAIClient client, Models.OpenApiKefuStateChangeRequest 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", "kefustate", "change", client.Credentials.PushToken!);
+
+ return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken);
+ }
+
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Models/OpenApiThirdKf/OpenApiKefuStateChangeRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Models/OpenApiThirdKf/OpenApiKefuStateChangeRequest.cs
new file mode 100644
index 00000000..2c61be57
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Models/OpenApiThirdKf/OpenApiKefuStateChangeRequest.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.Xml.Serialization;
+
+namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
+{
+ ///
+ /// 表示 [POST] /openapi/kefustate/change/{TOKEN} 接口的请求。
+ ///
+ [XmlRoot("xml")]
+ public class OpenApiKefuStateChangeRequest : WechatOpenAIRequestEncryptedXmlable
+ {
+ ///
+ /// 获取或设置用户的 OpenId。
+ ///
+ [XmlElement("openid")]
+ public string OpenId { get; set; } = string.Empty;
+
+ ///
+ /// 获取或设置客服接入状态。
+ ///
+ [XmlElement("kefustate")]
+ public string State { get; set; } = string.Empty;
+
+ ///
+ /// 获取或设置有效期(单位:秒)。
+ /// 默认值:1800
+ ///
+ [XmlElement("expires")]
+ public int ExpiresIn { get; set; } = 1800;
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Models/OpenApiThirdKf/OpenApiKefuStateChangeResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Models/OpenApiThirdKf/OpenApiKefuStateChangeResponse.cs
new file mode 100644
index 00000000..8315485f
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Models/OpenApiThirdKf/OpenApiKefuStateChangeResponse.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
+{
+ ///
+ /// 表示 [POST] /openapi/kefustate/change/{TOKEN} 接口的响应。
+ ///
+ public class OpenApiKefuStateChangeResponse : WechatOpenAIResponse
+ {
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Models/OpenApiThirdKf/OpenApiKefuStateGetRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Models/OpenApiThirdKf/OpenApiKefuStateGetRequest.cs
new file mode 100644
index 00000000..2c8f36e1
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Models/OpenApiThirdKf/OpenApiKefuStateGetRequest.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Xml.Serialization;
+
+namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
+{
+ ///
+ /// 表示 [POST] /openapi/kefustate/get/{TOKEN} 接口的请求。
+ ///
+ [XmlRoot("xml")]
+ public class OpenApiKefuStateGetRequest : WechatOpenAIRequestEncryptedXmlable
+ {
+ ///
+ /// 获取或设置用户的 OpenId。
+ ///
+ [XmlElement("openid")]
+ public string OpenId { get; set; } = string.Empty;
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Models/OpenApiThirdKf/OpenApiKefuStateGetResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Models/OpenApiThirdKf/OpenApiKefuStateGetResponse.cs
new file mode 100644
index 00000000..071316dc
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Models/OpenApiThirdKf/OpenApiKefuStateGetResponse.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
+{
+ ///
+ /// 表示 [POST] /openapi/kefustate/get/{TOKEN} 接口的响应。
+ ///
+ public class OpenApiKefuStateGetResponse : WechatOpenAIResponse
+ {
+ ///
+ /// 获取或设置客户接入状态。
+ ///
+ [Newtonsoft.Json.JsonProperty("kefustate")]
+ [System.Text.Json.Serialization.JsonPropertyName("kefustate")]
+ public string State { get; set; } = default!;
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Models/OpenApiThirdKf/OpenApiSendMessageRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Models/OpenApiThirdKf/OpenApiSendMessageRequest.cs
new file mode 100644
index 00000000..f80e0a3b
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Models/OpenApiThirdKf/OpenApiSendMessageRequest.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.Xml.Serialization;
+
+namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
+{
+ ///
+ /// 表示 [POST] /openapi/sendmsg/{TOKEN} 接口的请求。
+ ///
+ [XmlRoot("xml")]
+ public class OpenApiSendMessageRequest : WechatOpenAIRequestEncryptedXmlable
+ {
+ ///
+ /// 获取或设置用户的 OpenId。
+ ///
+ [XmlElement("openid")]
+ public string OpenId { get; set; } = string.Empty;
+
+ ///
+ /// 获取或设置消息内容。
+ ///
+ [XmlElement("msg")]
+ public string Message { get; set; } = string.Empty;
+
+ ///
+ /// 获取或设置渠道。
+ ///
+ [XmlElement("channel")]
+ public int Channel { get; set; }
+
+ ///
+ /// 获取或设置事件。
+ ///
+ [XmlElement("event")]
+ public string? Event { get; set; }
+
+ ///
+ /// 获取或设置客服人员的昵称。
+ ///
+ [XmlElement("kefuname")]
+ public string? KfName { get; set; }
+
+ ///
+ /// 获取或设置客服人员的头像 URL。
+ ///
+ [XmlElement("kefuavatar")]
+ public string? KfAvatarUrl { get; set; }
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Models/OpenApiThirdKf/OpenApiSendMessageResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Models/OpenApiThirdKf/OpenApiSendMessageResponse.cs
new file mode 100644
index 00000000..7f3eef19
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Models/OpenApiThirdKf/OpenApiSendMessageResponse.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
+{
+ ///
+ /// 表示 [POST] /openapi/sendmsg/{TOKEN} 接口的响应。
+ ///
+ public class OpenApiSendMessageResponse : WechatOpenAIResponse
+ {
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Utilities/Internal/XmlUtility.cs b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Utilities/Internal/XmlUtility.cs
new file mode 100644
index 00000000..13e4c775
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Utilities/Internal/XmlUtility.cs
@@ -0,0 +1,37 @@
+using System;
+using System.IO;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Xml.Serialization;
+
+namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Utilities
+{
+ internal static class XmlUtility
+ {
+ public static string Serialize(Type type, object obj)
+ {
+ string xml;
+
+ using var stream = new MemoryStream();
+ using var writer = new System.Xml.XmlTextWriter(stream, Encoding.UTF8);
+ writer.Formatting = System.Xml.Formatting.None;
+
+ XmlSerializer xmlSerializer = new XmlSerializer(type, new XmlRootAttribute("xml"));
+ XmlSerializerNamespaces xmlNamespace = new XmlSerializerNamespaces();
+ xmlNamespace.Add(string.Empty, string.Empty);
+ xmlSerializer.Serialize(writer, obj, xmlNamespace);
+ writer.Flush();
+ xml = Encoding.UTF8.GetString(stream.ToArray());
+ xml = Regex.Replace(xml, "\\s+<\\w+ (xsi|d2p1):nil=\"true\"[^>]*/>", string.Empty, RegexOptions.IgnoreCase);
+ xml = Regex.Replace(xml, "<\\?xml[^>]*\\?>", string.Empty, RegexOptions.IgnoreCase);
+
+ return xml;
+ }
+
+ public static string Serialize(T obj)
+ where T : class
+ {
+ return Serialize(typeof(T), obj);
+ }
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.OpenAI/WechatOpenAIClient.cs b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/WechatOpenAIClient.cs
index a049c8f1..0f3bc68c 100644
--- a/src/SKIT.FlurlHttpClient.Wechat.OpenAI/WechatOpenAIClient.cs
+++ b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/WechatOpenAIClient.cs
@@ -112,6 +112,15 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
{
try
{
+ if (data is WechatOpenAIRequestEncryptedXmlable xmlData)
+ {
+ if (xmlData.AppId == null)
+ xmlData.AppId = Credentials.AppId;
+
+ string xml = Utilities.XmlUtility.Serialize(xmlData);
+ data = new { encrypt = Utilities.WxBizMsgCryptor.AESEncrypt(plainText: xml, encodingAESKey: Credentials.PushEncodingAESKey!, appId: xmlData.AppId!) };
+ }
+
using IFlurlResponse flurlResponse = await base.SendRequestWithJsonAsync(flurlRequest, data, cancellationToken).ConfigureAwait(false);
return await GetResposneAsync(flurlResponse).ConfigureAwait(false);
}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.OpenAI/WechatOpenAIRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/WechatOpenAIRequest.cs
index be9c5937..83f8fdca 100644
--- a/src/SKIT.FlurlHttpClient.Wechat.OpenAI/WechatOpenAIRequest.cs
+++ b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/WechatOpenAIRequest.cs
@@ -12,6 +12,8 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
///
[Newtonsoft.Json.JsonIgnore]
[System.Text.Json.Serialization.JsonIgnore]
+ [System.Xml.Serialization.XmlIgnore]
+ [System.Xml.Serialization.SoapIgnore]
public virtual int? Timeout { get; set; }
///
@@ -19,6 +21,8 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
///
[Newtonsoft.Json.JsonIgnore]
[System.Text.Json.Serialization.JsonIgnore]
+ [System.Xml.Serialization.XmlIgnore]
+ [System.Xml.Serialization.SoapIgnore]
public virtual string? RequestId { get; set; }
///
@@ -26,6 +30,8 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
///
[Newtonsoft.Json.JsonIgnore]
[System.Text.Json.Serialization.JsonIgnore]
+ [System.Xml.Serialization.XmlIgnore]
+ [System.Xml.Serialization.SoapIgnore]
public virtual string? BotId { get; set; }
///
@@ -33,6 +39,17 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
///
[Newtonsoft.Json.JsonIgnore]
[System.Text.Json.Serialization.JsonIgnore]
+ [System.Xml.Serialization.XmlIgnore]
+ [System.Xml.Serialization.SoapIgnore]
public virtual string? AccessToken { get; set; }
}
+
+ public abstract class WechatOpenAIRequestEncryptedXmlable : WechatOpenAIRequest
+ {
+ ///
+ /// 获取或设置微信 AppId。如果不指定将使用构造 时的 参数。
+ ///
+ [System.Xml.Serialization.XmlElement("appid")]
+ public string? AppId { get; set; }
+ }
}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.OpenAI/WechatOpenAIResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/WechatOpenAIResponse.cs
index 0ed93ffd..4ea44e08 100644
--- a/src/SKIT.FlurlHttpClient.Wechat.OpenAI/WechatOpenAIResponse.cs
+++ b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/WechatOpenAIResponse.cs
@@ -32,16 +32,30 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
///
/// 获取微信智能对话 API 返回的错误码。
///
- [Newtonsoft.Json.JsonProperty("code")]
- [System.Text.Json.Serialization.JsonPropertyName("code")]
- public virtual int ErrorCode { get; set; }
+ [Newtonsoft.Json.JsonProperty("errcode")]
+ [System.Text.Json.Serialization.JsonPropertyName("errcode")]
+ public virtual int? ErrorCode { get; set; }
///
- /// 获取微信智能对话 API 返回的错误描述。
+ /// 获取微信智能对话 API 返回的错误信息。
+ ///
+ [Newtonsoft.Json.JsonProperty("errmsg")]
+ [System.Text.Json.Serialization.JsonPropertyName("errmsg")]
+ public virtual string? ErrorMessage { get; set; }
+
+ ///
+ /// 获取微信智能对话 API 返回的状态码。
+ ///
+ [Newtonsoft.Json.JsonProperty("code")]
+ [System.Text.Json.Serialization.JsonPropertyName("code")]
+ public virtual int? Code { get; set; }
+
+ ///
+ /// 获取微信智能对话 API 返回的调用信息。
///
[Newtonsoft.Json.JsonProperty("msg")]
[System.Text.Json.Serialization.JsonPropertyName("msg")]
- public virtual string? ErrorMessage { get; set; }
+ public virtual string? Message { get; set; }
///
/// 获取微信智能对话 API 返回的请求唯一标识。
@@ -51,12 +65,12 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
public virtual string? RequestId { get; set; }
///
- /// 获取一个值,该值指示调用微信 API 是否成功(即 HTTP 状态码为 200、且 errcode 值为 0)。
+ /// 获取一个值,该值指示调用微信 API 是否成功(即 HTTP 状态码为 200、且 code 和 errcode 值都为 0)。
///
///
public virtual bool IsSuccessful()
{
- return RawStatus == 200 && ErrorCode == 0;
+ return RawStatus == 200 && ErrorCode.GetValueOrDefault() == 0 && Code.GetValueOrDefault() == 0;
}
}
diff --git a/src/SKIT.FlurlHttpClient.Wechat/IWechatRequest.cs b/src/SKIT.FlurlHttpClient.Wechat/IWechatRequest.cs
index f983df0a..de02e4c2 100644
--- a/src/SKIT.FlurlHttpClient.Wechat/IWechatRequest.cs
+++ b/src/SKIT.FlurlHttpClient.Wechat/IWechatRequest.cs
@@ -1,6 +1,4 @@
-using System;
-
-namespace SKIT.FlurlHttpClient.Wechat
+namespace SKIT.FlurlHttpClient.Wechat
{
///
/// SKIT.FlurlHttpClient.Wechat 请求接口。
diff --git a/src/SKIT.FlurlHttpClient.Wechat/IWechatResponse.cs b/src/SKIT.FlurlHttpClient.Wechat/IWechatResponse.cs
index 97f3b97b..40a883e3 100644
--- a/src/SKIT.FlurlHttpClient.Wechat/IWechatResponse.cs
+++ b/src/SKIT.FlurlHttpClient.Wechat/IWechatResponse.cs
@@ -1,16 +1,9 @@
-using System;
-using System.Collections.Generic;
-
-namespace SKIT.FlurlHttpClient.Wechat
+namespace SKIT.FlurlHttpClient.Wechat
{
///
/// SKIT.FlurlHttpClient.Wechat 响应接口。
///
public interface IWechatResponse : ICommonResponse
{
- ///
- /// 获取微信 API 返回的错误描述。
- ///
- string? ErrorMessage { get; set; }
}
}
diff --git a/test/SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests/EventSamples/ThirdKf/UserEnterEvent.xml b/test/SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests/EventSamples/ThirdKf/UserEnterEvent.xml
new file mode 100644
index 00000000..4c39b906
--- /dev/null
+++ b/test/SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests/EventSamples/ThirdKf/UserEnterEvent.xml
@@ -0,0 +1,13 @@
+
+ 用户的唯一ID,(通常为用户在微信的openid)
+ 应用的appid
+
+ 机器人或用户的的内容
+
+ userEnter
+ 0
+ 0
+ 渠0
+ 0
+ 1234567890
+
\ No newline at end of file
diff --git a/test/SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests/EventSamples/ThirdKf/UserQuitEvent.xml b/test/SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests/EventSamples/ThirdKf/UserQuitEvent.xml
new file mode 100644
index 00000000..4bfbb88b
--- /dev/null
+++ b/test/SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests/EventSamples/ThirdKf/UserQuitEvent.xml
@@ -0,0 +1,10 @@
+
+ 用户的唯一ID,(通常为用户在微信的openid)
+ 应用的appid
+ userQuit
+ 0
+ 0
+ 渠0
+ 0
+ 1234567890
+
\ No newline at end of file
diff --git a/test/SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests/SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests.csproj b/test/SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests/SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests.csproj
index 1338fd3c..72d255b9 100644
--- a/test/SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests/SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests.csproj
+++ b/test/SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests/SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests.csproj
@@ -11,6 +11,7 @@
PreserveNewest
+