refactor(openai): 重新实现请求加密 XML 序列化的方式

This commit is contained in:
Fu Diwei
2022-11-21 15:56:59 +08:00
parent 154eea7ac2
commit 9741b34642
40 changed files with 312 additions and 136 deletions

View File

@@ -112,7 +112,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
using var fileContent = new ByteArrayContent(request.FileBytes ?? Array.Empty<byte>());
using var paramContent = new StringContent(
Utilities.WxMsgCryptor.AESEncrypt(
plainText: Utilities.XmlUtility.Serialize(request),
plainText: Utilities.XmlUtility.ConvertFromJson(client.JsonSerializer.Serialize(request)),
encodingAESKey: client.Credentials.EncodingAESKey!,
appId: client.Credentials.AppId!
),

View File

@@ -1,12 +1,10 @@
using System.Collections.Generic;
using System.Xml.Serialization;
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
{
/// <summary>
/// <para>表示 [POST] /batchimportskill/{TOKEN} 接口的请求。</para>
/// </summary>
[XmlRoot("xml")]
public class BatchImportSkillRequest : WechatOpenAIRequest, WechatOpenAIRequest.Serialization.IEncryptedXmlable
{
public static class Types
@@ -16,25 +14,29 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
/// <summary>
/// 获取或设置技能名称。
/// </summary>
[XmlElement("skillname")]
[Newtonsoft.Json.JsonProperty("skillname")]
[System.Text.Json.Serialization.JsonPropertyName("skillname")]
public string SkillName { get; set; } = string.Empty;
/// <summary>
/// 获取或设置标准问题。
/// </summary>
[XmlElement("title")]
[Newtonsoft.Json.JsonProperty("title")]
[System.Text.Json.Serialization.JsonPropertyName("title")]
public string Title { get; set; } = string.Empty;
/// <summary>
/// 获取或设置相似问题列表。
/// </summary>
[XmlElement("question", Type = typeof(string))]
[Newtonsoft.Json.JsonProperty("question")]
[System.Text.Json.Serialization.JsonPropertyName("question")]
public IList<string> QuestionList { get; set; } = new List<string>();
/// <summary>
/// 获取或设置机器人回答列表。
/// </summary>
[XmlElement("answer", Type = typeof(string))]
[Newtonsoft.Json.JsonProperty("answer")]
[System.Text.Json.Serialization.JsonPropertyName("answer")]
public IList<string> AnswerList { get; set; } = new List<string>();
}
}
@@ -42,13 +44,15 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
/// <summary>
/// 获取或设置管理员 ID。
/// </summary>
[XmlElement("managerid")]
[Newtonsoft.Json.JsonProperty("managerid")]
[System.Text.Json.Serialization.JsonPropertyName("managerid")]
public string ManagetId { get; set; } = string.Empty;
/// <summary>
/// 获取或设置技能列表。
/// </summary>
[XmlElement("skill", Type = typeof(Types.Skill))]
[Newtonsoft.Json.JsonProperty("skill")]
[System.Text.Json.Serialization.JsonPropertyName("skill")]
public IList<Types.Skill> SkillList { get; set; } = new List<Types.Skill>();
}
}

View File

@@ -1,43 +1,55 @@
using System.Collections.Generic;
using System.Xml.Serialization;
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
{
/// <summary>
/// <para>表示 [POST] /label/batchset/{TOKEN} 接口的请求。</para>
/// </summary>
[XmlRoot("xml")]
public class LabelBatchSetRequest : WechatOpenAIRequest, WechatOpenAIRequest.Serialization.IEncryptedXmlable
{
public static class Types
{
public class OpenIdList
{
[Newtonsoft.Json.JsonProperty("openid")]
[System.Text.Json.Serialization.JsonPropertyName("openid")]
public IList<string> Items { get; set; } = new List<string>();
}
}
/// <summary>
/// 获取或设置微信 AppId。
/// </summary>
[XmlElement("appid")]
[Newtonsoft.Json.JsonProperty("appid")]
[System.Text.Json.Serialization.JsonPropertyName("appid")]
public string AppId { get; set; } = string.Empty;
/// <summary>
/// 获取或设置标签名称。
/// </summary>
[XmlElement("category")]
[Newtonsoft.Json.JsonProperty("category")]
[System.Text.Json.Serialization.JsonPropertyName("category")]
public string Category { get; set; } = string.Empty;
/// <summary>
/// 获取或设置二级标签名称。
/// </summary>
[XmlElement("label")]
[Newtonsoft.Json.JsonProperty("label")]
[System.Text.Json.Serialization.JsonPropertyName("label")]
public string Label { get; set; } = string.Empty;
/// <summary>
/// 获取或设置标签分类规则。
/// </summary>
[XmlElement("desc")]
[Newtonsoft.Json.JsonProperty("desc")]
[System.Text.Json.Serialization.JsonPropertyName("desc")]
public string Description { get; set; } = string.Empty;
/// <summary>
/// 获取或设置要设置标签的 OpenId 列表。
/// </summary>
[XmlArray("list")]
[XmlArrayItem("openid", Type = typeof(string))]
public IList<string> OpenIdList { get; set; } = new List<string>();
[Newtonsoft.Json.JsonProperty("list")]
[System.Text.Json.Serialization.JsonPropertyName("list")]
public Types.OpenIdList OpenIdList { get; set; } = new Types.OpenIdList();
}
}

View File

@@ -1,17 +1,15 @@
using System.Xml.Serialization;
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
{
/// <summary>
/// <para>表示 [POST] /publish_progress/{TOKEN} 接口的请求。</para>
/// </summary>
[XmlRoot("xml")]
public class PublishProgressRequest : WechatOpenAIRequest, WechatOpenAIRequest.Serialization.IEncryptedXmlable
{
/// <summary>
/// 获取或设置管理员 ID。
/// </summary>
[XmlElement("managerid")]
[Newtonsoft.Json.JsonProperty("managerid")]
[System.Text.Json.Serialization.JsonPropertyName("managerid")]
public string ManagerId { get; set; } = string.Empty;
}
}

View File

@@ -1,17 +1,15 @@
using System.Xml.Serialization;
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
{
/// <summary>
/// <para>表示 [POST] /publish/{TOKEN} 接口的请求。</para>
/// </summary>
[XmlRoot("xml")]
public class PublishRequest : WechatOpenAIRequest, WechatOpenAIRequest.Serialization.IEncryptedXmlable
{
/// <summary>
/// 获取或设置管理员 ID。
/// </summary>
[XmlElement("managerid")]
[Newtonsoft.Json.JsonProperty("managerid")]
[System.Text.Json.Serialization.JsonPropertyName("managerid")]
public string ManagerId { get; set; } = string.Empty;
}
}

View File

@@ -1,43 +1,55 @@
using System.Collections.Generic;
using System.Xml.Serialization;
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
{
/// <summary>
/// <para>表示 [POST] /setautoreply/{TOKEN} 接口的请求。</para>
/// </summary>
[XmlRoot("xml")]
public class SetAutoReplyRequest : WechatOpenAIRequest, WechatOpenAIRequest.Serialization.IEncryptedXmlable
{
public static class Types
{
public class QuestionList
{
[Newtonsoft.Json.JsonProperty("question")]
[System.Text.Json.Serialization.JsonPropertyName("question")]
public IList<string> Items { get; set; } = new List<string>();
}
}
/// <summary>
/// 获取或设置管理员 ID。
/// </summary>
[XmlElement("managerid")]
[Newtonsoft.Json.JsonProperty("managerid")]
[System.Text.Json.Serialization.JsonPropertyName("managerid")]
public string ManagetId { get; set; } = string.Empty;
/// <summary>
/// 获取或设置技能名称。
/// </summary>
[XmlElement("skillname")]
[Newtonsoft.Json.JsonProperty("skillname")]
[System.Text.Json.Serialization.JsonPropertyName("skillname")]
public string SkillName { get; set; } = string.Empty;
/// <summary>
/// 获取或设置标准问题。
/// </summary>
[XmlElement("title")]
[Newtonsoft.Json.JsonProperty("title")]
[System.Text.Json.Serialization.JsonPropertyName("title")]
public string Title { get; set; } = string.Empty;
/// <summary>
/// 获取或设置自动回答的内容。
/// </summary>
[XmlElement("content")]
[Newtonsoft.Json.JsonProperty("content")]
[System.Text.Json.Serialization.JsonPropertyName("content")]
public string Content { get; set; } = string.Empty;
/// <summary>
/// 获取或设置相似问题列表。
/// </summary>
[XmlArray("list")]
[XmlArrayItem("question", Type = typeof(string))]
public IList<string> QuestionList { get; set; } = new List<string>();
[Newtonsoft.Json.JsonProperty("list")]
[System.Text.Json.Serialization.JsonPropertyName("list")]
public Types.QuestionList QuestionList { get; set; } = new Types.QuestionList();
}
}

View File

@@ -1,29 +1,29 @@
using System.Xml.Serialization;
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
{
/// <summary>
/// <para>表示 [POST] /feedback/{TOKEN} 接口的请求。</para>
/// </summary>
[XmlRoot("xml")]
public class FeedbackRequest : WechatOpenAIRequest, WechatOpenAIRequest.Serialization.IEncryptedXmlable
{
/// <summary>
/// 获取或设置消息 ID。
/// </summary>
[XmlElement("msgid")]
[Newtonsoft.Json.JsonProperty("msgid")]
[System.Text.Json.Serialization.JsonPropertyName("msgid")]
public string MessageId { get; set; } = string.Empty;
/// <summary>
/// 获取或设置反馈结果。
/// </summary>
[XmlElement("feedbackResult")]
[Newtonsoft.Json.JsonProperty("feedbackResult")]
[System.Text.Json.Serialization.JsonPropertyName("feedbackResult")]
public int FeedbackResult { get; set; }
/// <summary>
/// 获取或设置用户反馈时间戳。
/// </summary>
[XmlElement("updateAt")]
[Newtonsoft.Json.JsonProperty("updateAt")]
[System.Text.Json.Serialization.JsonPropertyName("updateAt")]
public long UpdateTimestamp { get; set; }
}
}

View File

@@ -1,67 +1,73 @@
using System.Xml.Serialization;
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
{
/// <summary>
/// <para>表示 [POST] /gethotquerydetail/{TOKEN} 接口的请求。</para>
/// </summary>
[XmlRoot("xml")]
public class GetHotQueryDetailRequest : WechatOpenAIRequest, WechatOpenAIRequest.Serialization.IEncryptedXmlable
{
/// <summary>
/// 获取或设置分页页数。
/// <para>默认值1</para>
/// </summary>
[XmlElement("pageNo")]
[Newtonsoft.Json.JsonProperty("pageNo")]
[System.Text.Json.Serialization.JsonPropertyName("pageNo")]
public int Page { get; set; } = 1;
/// <summary>
/// 获取或设置分页每页数量。
/// <para>默认值10</para>
/// </summary>
[XmlElement("pageSize")]
[Newtonsoft.Json.JsonProperty("pageSize")]
[System.Text.Json.Serialization.JsonPropertyName("pageSize")]
public int Limit { get; set; } = 10;
/// <summary>
/// 获取或设置命中类型。
/// </summary>
[XmlElement("matchType", IsNullable = true)]
[Newtonsoft.Json.JsonProperty("matchType")]
[System.Text.Json.Serialization.JsonPropertyName("matchType")]
public int? MatchType { get; set; }
/// <summary>
/// 获取或设置问题类型。
/// </summary>
[XmlElement("cluesType", IsNullable = true)]
[Newtonsoft.Json.JsonProperty("cluesType")]
[System.Text.Json.Serialization.JsonPropertyName("cluesType")]
public int? ClueType { get; set; }
/// <summary>
/// 获取或设置报告类型。
/// </summary>
[XmlElement("reportType", IsNullable = true)]
[Newtonsoft.Json.JsonProperty("reportType")]
[System.Text.Json.Serialization.JsonPropertyName("reportType")]
public int? ReportType { get; set; }
/// <summary>
/// 获取或设置日期字符串格式yyyy-MM-dd
/// </summary>
[XmlElement("date")]
[Newtonsoft.Json.JsonProperty("date")]
[System.Text.Json.Serialization.JsonPropertyName("date")]
public string DateString { get; set; } = string.Empty;
/// <summary>
/// 获取或设置开发者的 OpenId。
/// </summary>
[XmlElement("openid")]
[Newtonsoft.Json.JsonProperty("openid")]
[System.Text.Json.Serialization.JsonPropertyName("openid")]
public string OpenId { get; set; } = string.Empty;
/// <summary>
/// 获取或设置聚类结果类别 ID。
/// </summary>
[XmlElement("clusterId")]
[Newtonsoft.Json.JsonProperty("clusterId")]
[System.Text.Json.Serialization.JsonPropertyName("clusterId")]
public string ClusterId { get; set; } = string.Empty;
/// <summary>
/// 获取或设置聚类结果。
/// </summary>
[XmlElement("hotQuesCluster", IsNullable = true)]
[Newtonsoft.Json.JsonProperty("hotQuesCluster")]
[System.Text.Json.Serialization.JsonPropertyName("hotQuesCluster")]
public string? HotQuestionCluster { get; set; }
}
}

View File

@@ -1,55 +1,59 @@
using System.Xml.Serialization;
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
{
/// <summary>
/// <para>表示 [POST] /gethotquerylist/{TOKEN} 接口的请求。</para>
/// </summary>
[XmlRoot("xml")]
public class GetHotQueryListRequest : WechatOpenAIRequest, WechatOpenAIRequest.Serialization.IEncryptedXmlable
{
/// <summary>
/// 获取或设置分页页数。
/// <para>默认值1</para>
/// </summary>
[XmlElement("pageNo")]
[Newtonsoft.Json.JsonProperty("pageNo")]
[System.Text.Json.Serialization.JsonPropertyName("pageNo")]
public int Page { get; set; } = 1;
/// <summary>
/// 获取或设置分页每页数量。
/// <para>默认值10</para>
/// </summary>
[XmlElement("pageSize")]
[Newtonsoft.Json.JsonProperty("pageSize")]
[System.Text.Json.Serialization.JsonPropertyName("pageSize")]
public int Limit { get; set; } = 10;
/// <summary>
/// 获取或设置命中类型。
/// </summary>
[XmlElement("matchType", IsNullable = true)]
[Newtonsoft.Json.JsonProperty("matchType")]
[System.Text.Json.Serialization.JsonPropertyName("matchType")]
public int? MatchType { get; set; }
/// <summary>
/// 获取或设置问题类型。
/// </summary>
[XmlElement("cluesType", IsNullable = true)]
[Newtonsoft.Json.JsonProperty("cluesType")]
[System.Text.Json.Serialization.JsonPropertyName("cluesType")]
public int? ClueType { get; set; }
/// <summary>
/// 获取或设置报告类型。
/// </summary>
[XmlElement("reportType", IsNullable = true)]
[Newtonsoft.Json.JsonProperty("reportType")]
[System.Text.Json.Serialization.JsonPropertyName("reportType")]
public int? ReportType { get; set; }
/// <summary>
/// 获取或设置日期字符串格式yyyy-MM-dd
/// </summary>
[XmlElement("date")]
[Newtonsoft.Json.JsonProperty("date")]
[System.Text.Json.Serialization.JsonPropertyName("date")]
public string DateString { get; set; } = string.Empty;
/// <summary>
/// 获取或设置开发者的 OpenId。
/// </summary>
[XmlElement("openid")]
[Newtonsoft.Json.JsonProperty("openid")]
[System.Text.Json.Serialization.JsonPropertyName("openid")]
public string OpenId { get; set; } = string.Empty;
}
}

View File

@@ -1,36 +1,38 @@
using System;
using System.Xml.Serialization;
using System;
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
{
/// <summary>
/// <para>表示 [POST] /assetsupload/{TOKEN} 接口的请求。</para>
/// </summary>
[XmlRoot("xml")]
public class AssetsUploadRequest : WechatOpenAIRequest, WechatOpenAIRequest.Serialization.IEncryptedXmlable
{
/// <summary>
/// 获取或设置用户 ID。
/// </summary>
[XmlElement("userid")]
[Newtonsoft.Json.JsonProperty("userid")]
[System.Text.Json.Serialization.JsonPropertyName("userid")]
public string UserId { get; set; } = string.Empty;
/// <summary>
/// 获取或设置文件字节数组。
/// </summary>
[XmlIgnore]
[Newtonsoft.Json.JsonIgnore]
[System.Text.Json.Serialization.JsonIgnore]
public byte[] FileBytes { get; set; } = Array.Empty<byte>();
/// <summary>
/// 获取或设置文件名。如果不指定将由系统自动生成。
/// </summary>
[XmlIgnore]
[Newtonsoft.Json.JsonIgnore]
[System.Text.Json.Serialization.JsonIgnore]
public string? FileName { get; set; }
/// <summary>
/// 获取或设置文件 Conent-Type。如果不指定将由系统自动生成。
/// </summary>
[XmlIgnore]
[Newtonsoft.Json.JsonIgnore]
[System.Text.Json.Serialization.JsonIgnore]
public string? FileContentType { get; set; }
}
}

View File

@@ -1,17 +1,15 @@
using System.Xml.Serialization;
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
{
/// <summary>
/// <para>表示 [POST] /getbindlink/{TOKEN} 接口的请求。</para>
/// </summary>
[XmlRoot("xml")]
public class GetBindLinkRequest : WechatOpenAIRequest, WechatOpenAIRequest.Serialization.IEncryptedXmlable
{
/// <summary>
/// 获取或设置直播 ID。
/// </summary>
[XmlElement("redirectlink")]
public string RedirectLink { get; set; } = string.Empty;
[Newtonsoft.Json.JsonProperty("redirectlink")]
[System.Text.Json.Serialization.JsonPropertyName("redirectlink")]
public string RedirectUrl { get; set; } = string.Empty;
}
}

View File

@@ -24,6 +24,6 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("link")]
[System.Text.Json.Serialization.JsonPropertyName("link")]
public string Url { get; set; } = default!;
public string LinkUrl { get; set; } = default!;
}
}

View File

@@ -1,12 +1,9 @@
using System.Xml.Serialization;
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
{
/// <summary>
/// <para>表示 [POST] /getbindlist/{TOKEN} 接口的请求。</para>
/// </summary>
[XmlRoot("xml")]
public class GetBindListRequest : WechatOpenAIRequest, WechatOpenAIRequest.Serialization.IEncryptedXmlable
public class GetBindListRequest : WechatOpenAIRequest
{
}
}

View File

@@ -1,17 +1,15 @@
using System.Xml.Serialization;
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
{
/// <summary>
/// <para>表示 [POST] /geth5link/{TOKEN} 接口的请求。</para>
/// </summary>
[XmlRoot("xml")]
public class GetH5LinkRequest : WechatOpenAIRequest, WechatOpenAIRequest.Serialization.IEncryptedXmlable
{
/// <summary>
/// 获取或设置页面标题。
/// </summary>
[XmlElement("title", IsNullable = true)]
[Newtonsoft.Json.JsonProperty("title")]
[System.Text.Json.Serialization.JsonPropertyName("title")]
public string? Title { get; set; }
}
}

View File

@@ -24,6 +24,6 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("link")]
[System.Text.Json.Serialization.JsonPropertyName("link")]
public string Url { get; set; } = default!;
public string LinkUrl { get; set; } = default!;
}
}

View File

@@ -1,17 +1,15 @@
using System.Xml.Serialization;
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
{
/// <summary>
/// <para>表示 [POST] /unbindmp/{TOKEN} 接口的请求。</para>
/// </summary>
[XmlRoot("xml")]
public class UnbindMpRequest : WechatOpenAIRequest, WechatOpenAIRequest.Serialization.IEncryptedXmlable
{
/// <summary>
/// 获取或设置微信 AppId。
/// </summary>
[XmlElement("authorizer_appid")]
[Newtonsoft.Json.JsonProperty("authorizer_appid")]
[System.Text.Json.Serialization.JsonPropertyName("authorizer_appid")]
public string AuthorizerAppId { get; set; } = string.Empty;
}
}

View File

@@ -1,35 +1,36 @@
using System.Xml.Serialization;
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
{
/// <summary>
/// <para>表示 [POST] /kefustate/change/{TOKEN} 接口的请求。</para>
/// </summary>
[XmlRoot("xml")]
public class KefuStateChangeRequest : WechatOpenAIRequest, WechatOpenAIRequest.Serialization.IEncryptedXmlable
{
/// <summary>
/// 获取或设置微信 AppId。如果不指定将使用构造 <see cref="WechatOpenAIClient"/> 时的 <see cref="WechatOpenAIClientOptions.AppId"/> 参数。
/// </summary>
[XmlElement("appid")]
[Newtonsoft.Json.JsonProperty("appid")]
[System.Text.Json.Serialization.JsonPropertyName("appid")]
public string? AppId { get; set; }
/// <summary>
/// 获取或设置用户的 OpenId。
/// </summary>
[XmlElement("openid")]
[Newtonsoft.Json.JsonProperty("openid")]
[System.Text.Json.Serialization.JsonPropertyName("openid")]
public string OpenId { get; set; } = string.Empty;
/// <summary>
/// 获取或设置客服接入状态。
/// </summary>
[XmlElement("kefustate")]
[Newtonsoft.Json.JsonProperty("kefustate")]
[System.Text.Json.Serialization.JsonPropertyName("kefustate")]
public string KfState { get; set; } = string.Empty;
/// <summary>
/// 获取或设置有效期(单位:秒)。
/// </summary>
[XmlElement("expires", IsNullable = true)]
[Newtonsoft.Json.JsonProperty("expires")]
[System.Text.Json.Serialization.JsonPropertyName("expires")]
public int? ExpiresIn { get; set; }
}
}

View File

@@ -1,29 +1,29 @@
using System.Xml.Serialization;
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
{
/// <summary>
/// <para>表示 [POST] /kefustate/get/{TOKEN} 接口的请求。</para>
/// </summary>
[XmlRoot("xml")]
public class KefuStateGetRequest : WechatOpenAIRequest, WechatOpenAIRequest.Serialization.IEncryptedXmlable
{
/// <summary>
/// 获取或设置微信 AppId。如果不指定将使用构造 <see cref="WechatOpenAIClient"/> 时的 <see cref="WechatOpenAIClientOptions.AppId"/> 参数。
/// </summary>
[XmlElement("appid")]
[Newtonsoft.Json.JsonProperty("appid")]
[System.Text.Json.Serialization.JsonPropertyName("appid")]
public string? AppId { get; set; }
/// <summary>
/// 获取或设置用户的 OpenId。
/// </summary>
[XmlElement("openid")]
[Newtonsoft.Json.JsonProperty("openid")]
[System.Text.Json.Serialization.JsonPropertyName("openid")]
public string OpenId { get; set; } = string.Empty;
/// <summary>
/// 获取或设置获取类型。
/// </summary>
[XmlElement("type", IsNullable = true)]
[Newtonsoft.Json.JsonProperty("type")]
[System.Text.Json.Serialization.JsonPropertyName("type")]
public int? Type { get; set; }
}
}

View File

@@ -1,59 +1,64 @@
using System.Xml.Serialization;
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
{
/// <summary>
/// <para>表示 [POST] /sendmsg/{TOKEN} 接口的请求。</para>
/// </summary>
[XmlRoot("xml")]
public class SendMessageRequest : WechatOpenAIRequest, WechatOpenAIRequest.Serialization.IEncryptedXmlable
{
/// <summary>
/// 获取或设置微信 AppId。如果不指定将使用构造 <see cref="WechatOpenAIClient"/> 时的 <see cref="WechatOpenAIClientOptions.AppId"/> 参数。
/// </summary>
[XmlElement("appid")]
[Newtonsoft.Json.JsonProperty("appid")]
[System.Text.Json.Serialization.JsonPropertyName("appid")]
public string? AppId { get; set; }
/// <summary>
/// 获取或设置用户的 OpenId。
/// </summary>
[XmlElement("openid")]
[Newtonsoft.Json.JsonProperty("openid")]
[System.Text.Json.Serialization.JsonPropertyName("openid")]
public string OpenId { get; set; } = string.Empty;
/// <summary>
/// 获取或设置消息内容。
/// </summary>
[XmlElement("msg")]
[Newtonsoft.Json.JsonProperty("msg")]
[System.Text.Json.Serialization.JsonPropertyName("msg")]
public string Message { get; set; } = string.Empty;
/// <summary>
/// 获取或设置渠道。
/// </summary>
[XmlElement("channel")]
[Newtonsoft.Json.JsonProperty("channel")]
[System.Text.Json.Serialization.JsonPropertyName("channel")]
public int Channel { get; set; }
/// <summary>
/// 获取或设置事件。
/// </summary>
[XmlElement("event", IsNullable = true)]
[Newtonsoft.Json.JsonProperty("event")]
[System.Text.Json.Serialization.JsonPropertyName("event")]
public string? Event { get; set; }
/// <summary>
/// 获取或设置客服人员的昵称。
/// </summary>
[XmlElement("kefuname", IsNullable = true)]
[Newtonsoft.Json.JsonProperty("kefuname")]
[System.Text.Json.Serialization.JsonPropertyName("kefuname")]
public string? KfName { get; set; }
/// <summary>
/// 获取或设置客服人员的头像 URL。
/// </summary>
[XmlElement("kefuavatar", IsNullable = true)]
[Newtonsoft.Json.JsonProperty("kefuavatar")]
[System.Text.Json.Serialization.JsonPropertyName("kefuavatar")]
public string? KfAvatarUrl { get; set; }
/// <summary>
/// 获取或设置分类或技能名称。
/// </summary>
[XmlElement("ans_node_name", IsNullable = true)]
[Newtonsoft.Json.JsonProperty("ans_node_name")]
[System.Text.Json.Serialization.JsonPropertyName("ans_node_name")]
public string? AnswerNodeName { get; set; }
}
}

View File

@@ -5,6 +5,7 @@ using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Utilities
{
@@ -60,11 +61,6 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Utilities
return Serialize(typeof(T), obj);
}
public static string Serialize(object obj)
{
return Serialize(obj.GetType(), obj);
}
public static object Deserialize(Type type, string xml)
{
using var reader = new StringReader(xml);
@@ -77,5 +73,12 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Utilities
{
return (T)Deserialize(typeof(T), xml);
}
public static string ConvertFromJson(string json)
{
XmlDocument xmlDocument = JsonConvert.DeserializeXmlNode(json, "xml")!;
string xml = xmlDocument.InnerXml;
return xml;
}
}
}

View File

@@ -102,7 +102,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
{
if (data is WechatOpenAIRequest.Serialization.IEncryptedXmlable)
{
string plainXml = Utilities.XmlUtility.Serialize(data);
string plainXml = Utilities.XmlUtility.ConvertFromJson(JsonSerializer.Serialize(data));
string encryptedXml = Utilities.WxMsgCryptor.AESEncrypt(plainText: plainXml, encodingAESKey: Credentials.EncodingAESKey!, appId: Credentials.AppId!);
data = new { encrypt = encryptedXml };
}

View File

@@ -0,0 +1,28 @@
{
"managerid": "平台管理员ID",
"skill": [
{
"skillname": "技能名称1",
"title": "标准问题2",
"question": [
"相似问题1",
"相似问题2",
"相似问题3"
],
"answer": [
"1",
"2"
]
},
{
"skillname": "技能名称1",
"title": "标准问题3",
"question": [
"相似问题1"
],
"answer": [
"1"
]
}
]
}

View File

@@ -0,0 +1,12 @@
{
"appid": "wxxxxx",
"category": "完件",
"label": "完成",
"desc": "在 app 中完成了用户信息",
"list": {
"openid": [
"openid_1",
"openid_2"
]
}
}

View File

@@ -0,0 +1,3 @@
{
"managerid": "平台管理员ID"
}

View File

@@ -0,0 +1,10 @@
{
"errcode": 1001,
"errmsg": "TOKEN is not valid",
"code": 0,
"data": {
"progress": 100,
"status": 1
},
"msg": "success"
}

View File

@@ -0,0 +1,3 @@
{
"managerid": "平台管理员ID"
}

View File

@@ -0,0 +1,12 @@
{
"managerid": "平台管理员ID",
"skillname": "技能名称",
"title": "标准问题",
"content": "自动回答的内容",
"list": {
"question": [
"相似问题1",
"相似问题2"
]
}
}

View File

@@ -0,0 +1,5 @@
{
"msgid": "WtxsA9ENwZtFdjK",
"feedbackResult": 1,
"updateAt": 1653496004
}

View File

@@ -0,0 +1,11 @@
{
"pageNo": 1,
"pageSize": 10,
"matchType": 0,
"cluesType": 0,
"reportType": 0,
"date": "2021-07-19",
"openid": "abcdasdf123123asldjfalsjdf",
"clusterId": "10971,10971,openaiquerycluster_10971_a32bfe917bbae4b6d09b90482c33c4b6",
"hotQuesCluster": "遇到难以解决问题,请<a href=\"weixin://dl/help\">轻按此处</a>反馈给我们,我们会第一时间处理。"
}

View File

@@ -0,0 +1,9 @@
{
"pageNo": 1,
"pageSize": 10,
"matchType": 0,
"cluesType": 0,
"reportType": 0,
"date": "2021-07-19",
"openid": "abcdasdf123123asldjfalsjdf"
}

View File

@@ -0,0 +1,3 @@
{
"userid": "xxxxx"
}

View File

@@ -0,0 +1,3 @@
{
"redirectlink": "https://xxx.com/xxx"
}

View File

@@ -0,0 +1,3 @@
{
"title": "xxx客服"
}

View File

@@ -0,0 +1,3 @@
{
"authorizer_appid": "https://xxx.com/xxx"
}

View File

@@ -0,0 +1,5 @@
{
"appid": "wxxxxx",
"openid": "xxxxx",
"kefustate": "needperson"
}

View File

@@ -0,0 +1,4 @@
{
"appid": "wxxxxx",
"openid": "xxxxx"
}

View File

@@ -0,0 +1,9 @@
{
"appid": "wxxxxx",
"openid": "xxxxx",
"msg": "您好,请问需要什么帮助",
"channel": 0,
"kefuname": "客服昵称",
"kefuavatar": "客服头像图片 URL 地址",
"ans_node_name": "分类或技能名称"
}

View File

@@ -0,0 +1,17 @@
using System.Threading.Tasks;
using Xunit;
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests
{
public class TestCase_ApiExecuteDialogTests
{
[Fact(DisplayName = "测试用例:调用 API [POST] /sign/{TOKEN}")]
public async Task TestExecuteSign()
{
var request = new Models.SignRequest() { UserId = "TEST_USERID" };
var response = await TestClients.Instance.ExecuteSignAsync(request);
Assert.NotNull(response.Signature);
}
}
}

View File

@@ -0,0 +1,17 @@
using System.Threading.Tasks;
using Xunit;
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests
{
public class TestCase_ApiExecuteMpTests
{
[Fact(DisplayName = "测试用例:调用 API [POST] /getbindlink/{TOKEN}")]
public async Task TestExecuteSign()
{
var request = new Models.GetBindLinkRequest() { RedirectUrl = "https://example.com" };
var response = await TestClients.Instance.ExecuteGetBindLinkAsync(request);
Assert.NotNull(response.LinkUrl);
}
}
}

View File

@@ -1,17 +0,0 @@
using Xunit;
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests
{
public class TestCase_XmlUtilityTests
{
[Fact(DisplayName = "测试用例XML 序列化派生类")]
public void TestXmlSerializeSubClass()
{
Assert.Null(Record.Exception(() =>
{
object obj = new Models.SignRequest() { UserId = "TEST" };
Utilities.XmlUtility.Serialize(obj);
}));
}
}
}