diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Agent/SwitchWorkbenchModeEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Agent/SwitchWorkbenchModeEvent.cs
new file mode 100644
index 00000000..c10ac4bc
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Agent/SwitchWorkbenchModeEvent.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 EVENT.switch_workbench_mode 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/92535
+ ///
+ public class SwitchWorkbenchModeEvent : WechatWorkEvent, WechatWorkEvent.Types.IXmlSerializable
+ {
+ ///
+ /// 获取或设置应用 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("AgentID")]
+ public int AgentId { get; set; }
+
+ ///
+ /// 获取或设置自定义模式。
+ ///
+ [System.Xml.Serialization.XmlElement("Mode")]
+ public int Mode { get; set; }
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Approval/OpenApprovalChangeEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Approval/OpenApprovalChangeEvent.cs
new file mode 100644
index 00000000..30763206
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Approval/OpenApprovalChangeEvent.cs
@@ -0,0 +1,241 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 EVENT.open_approval_change 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/90269
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/93798
+ ///
+ public class OpenApprovalChangeEvent : WechatWorkEvent, WechatWorkEvent.Types.IXmlSerializable
+ {
+ public new static class Types
+ {
+ public class Approval
+ {
+ public static class Types
+ {
+ public class ApprovalRecord
+ {
+ public static class Types
+ {
+ public class RecordDetail
+ {
+ public static class Types
+ {
+ public class ApprovalerList
+ {
+ ///
+ /// 获取或设置审批人列表。
+ ///
+ [System.Xml.Serialization.XmlArray("Item")]
+ public ApprovalerItem[] Items { get; set; } = default!;
+ }
+
+ public class ApprovalerItem
+ {
+ ///
+ /// 获取或设置审批人成员账号。
+ ///
+ [System.Xml.Serialization.XmlElement("ItemUserId")]
+ public string UserId { get; set; } = default!;
+
+ ///
+ /// 获取或设置审批人名称。
+ ///
+ [System.Xml.Serialization.XmlElement("ItemName")]
+ public string Name { get; set; } = default!;
+
+ ///
+ /// 获取或设置审批人部门名称。
+ ///
+ [System.Xml.Serialization.XmlElement("ItemParty")]
+ public string DepartmentName { get; set; } = default!;
+
+ ///
+ /// 获取或设置审批人头像 URL。
+ ///
+ [System.Xml.Serialization.XmlElement("ItemImage")]
+ public string AvatarUrl { get; set; } = default!;
+
+ ///
+ /// 获取或设置分支审批状态。
+ ///
+ [System.Xml.Serialization.XmlElement("ItemStatus")]
+ public int ApproveStatus { get; set; }
+
+ ///
+ /// 获取或设置分支审批时间戳。
+ ///
+ [System.Xml.Serialization.XmlElement("ItemOpTime", IsNullable = true)]
+ public long? ApproveTimestamp { get; set; }
+
+ ///
+ /// 获取或设置审批意见。
+ ///
+ [System.Xml.Serialization.XmlElement("ItemSpeech", IsNullable = true)]
+ public string? Speech { get; set; }
+ }
+ }
+
+ ///
+ /// 获取或设置节点审批状态。
+ ///
+ [System.Xml.Serialization.XmlElement("NodeStatus")]
+ public int ApproveStatus { get; set; }
+
+ ///
+ /// 获取或设置节点审批方式。
+ ///
+ [System.Xml.Serialization.XmlElement("NodeAttr")]
+ public int ApproveType { get; set; }
+
+ ///
+ /// 获取或设置节点类型。
+ ///
+ [System.Xml.Serialization.XmlElement("NodeType")]
+ public int NodeType { get; set; }
+
+ ///
+ /// 获取或设置节点审批人列表。
+ ///
+ [System.Xml.Serialization.XmlArray("Items")]
+ public Types.ApprovalerList ApprovalerList { get; set; } = default!;
+ }
+ }
+
+ ///
+ /// 获取或设置审批流程详情列表。
+ ///
+ [System.Xml.Serialization.XmlArray("ApprovalNode")]
+ public Types.RecordDetail[] RecordDetailList { get; set; } = default!;
+ }
+
+ public class Notification
+ {
+ public static class Types
+ {
+ public class Notifier
+ {
+ ///
+ /// 获取或设置抄送人成员账号。
+ ///
+ [System.Xml.Serialization.XmlElement("ItemUserid")]
+ public string UserId { get; set; } = default!;
+
+ ///
+ /// 获取或设置抄送人名称。
+ ///
+ [System.Xml.Serialization.XmlElement("ItemName")]
+ public string Name { get; set; } = default!;
+
+ ///
+ /// 获取或设置抄送人部门名称。
+ ///
+ [System.Xml.Serialization.XmlElement("ItemParty")]
+ public string DepartmentName { get; set; } = default!;
+
+ ///
+ /// 获取或设置抄送人头像 URL。
+ ///
+ [System.Xml.Serialization.XmlElement("ItemImage")]
+ public string AvatarUrl { get; set; } = default!;
+ }
+ }
+
+ ///
+ /// 获取或设置审批抄送列表。
+ ///
+ [System.Xml.Serialization.XmlArray("NotifyNode")]
+ public Types.Notifier[] NotifierList { get; set; } = default!;
+ }
+ }
+
+ ///
+ /// 获取或设置第三方审批单号。
+ ///
+ [System.Xml.Serialization.XmlElement("ThirdNo")]
+ public string ThirdPartyApprovalNumber { get; set; } = default!;
+
+ ///
+ /// 获取或设置服务商审批模板 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("OpenTemplateId")]
+ public string OpenTemplateId { get; set; } = default!;
+
+ ///
+ /// 获取或设置审批单名称。
+ ///
+ [System.Xml.Serialization.XmlElement("OpenSpName")]
+ public string Name { get; set; } = default!;
+
+ ///
+ /// 获取或设置审批单状态。
+ ///
+ [System.Xml.Serialization.XmlElement("OpenSpStatus")]
+ public int Status { get; set; }
+
+ ///
+ /// 获取或设置申请时间戳。
+ ///
+ [System.Xml.Serialization.XmlElement("ApplyTime")]
+ public long ApplyTimestamp { get; set; }
+
+ ///
+ /// 获取或设置申请人成员账号。
+ ///
+ [System.Xml.Serialization.XmlElement("ApplyUserId")]
+ public string ApplicantUserId { get; set; } = default!;
+
+ ///
+ /// 获取或设置申请人成员名称。
+ ///
+ [System.Xml.Serialization.XmlElement("ApplyUserName")]
+ public string ApplicantName { get; set; } = default!;
+
+ ///
+ /// 获取或设置提单部门名称。
+ ///
+ [System.Xml.Serialization.XmlElement("ApplyUserParty")]
+ public string ApplicantDepartmentName { get; set; } = default!;
+
+ ///
+ /// 获取或设置申请人头像 URL。
+ ///
+ [System.Xml.Serialization.XmlElement("ApplyUserImage")]
+ public string ApplicantAvatarUrl { get; set; } = default!;
+
+ ///
+ /// 获取或设置审批信息。
+ ///
+ [System.Xml.Serialization.XmlElement("ApprovalNodes")]
+ public Types.ApprovalRecord ApprovalRecord { get; set; } = default!;
+
+ ///
+ /// 获取或设置抄送信息。
+ ///
+ [System.Xml.Serialization.XmlElement("NotifyNodes")]
+ public Types.Notification Notification { get; set; } = default!;
+
+ ///
+ /// 获取或设置当前审批节点。
+ ///
+ [System.Xml.Serialization.XmlElement("ApproverStep")]
+ public int ApproverStep { get; set; }
+ }
+ }
+
+ ///
+ /// 获取或设置应用 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("AgentID")]
+ public int AgentId { get; set; }
+
+ ///
+ /// 获取或设置第三方审批单信息。
+ ///
+ [System.Xml.Serialization.XmlElement("ApprovalInfo")]
+ public Types.Approval Approval { get; set; } = default!;
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Approval/SystemApprovalChangeEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Approval/SystemApprovalChangeEvent.cs
new file mode 100644
index 00000000..bede1420
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Approval/SystemApprovalChangeEvent.cs
@@ -0,0 +1,233 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 EVENT.sys_approval_change 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/91815
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/92633
+ ///
+ public class SystemApprovalChangeEvent : WechatWorkEvent, WechatWorkEvent.Types.IXmlSerializable
+ {
+ public new static class Types
+ {
+ public class Approval
+ {
+ public static class Types
+ {
+ public class Applicant
+ {
+ ///
+ /// 获取或设置申请人成员账号。
+ ///
+ [System.Xml.Serialization.XmlElement("UserId")]
+ public string UserId { get; set; } = default!;
+
+ ///
+ /// 获取或设置提单部门 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("Party")]
+ public int DepartmentId { get; set; }
+ }
+
+ public class Notifier
+ {
+ ///
+ /// 获取或设置抄送人成员账号。
+ ///
+ [System.Xml.Serialization.XmlElement("UserId")]
+ public string UserId { get; set; } = default!;
+ }
+
+ public class Record
+ {
+ public static class Types
+ {
+ public class RecordDetail
+ {
+ public static class Types
+ {
+ public class Approver
+ {
+ ///
+ /// 获取或设置审批人成员账号。
+ ///
+ [Newtonsoft.Json.JsonProperty("userid")]
+ [System.Text.Json.Serialization.JsonPropertyName("userid")]
+ public string UserId { get; set; } = default!;
+ }
+ }
+
+ ///
+ /// 获取或设置审批人信息。
+ ///
+ [System.Xml.Serialization.XmlElement("Approver")]
+ public Types.Approver Approver { get; set; } = default!;
+
+ ///
+ /// 获取或设置分支审批状态。
+ ///
+ [System.Xml.Serialization.XmlElement("SpStatus")]
+ public int ApproveStatus { get; set; }
+
+ ///
+ /// 获取或设置分支审批时间戳。
+ ///
+ [System.Xml.Serialization.XmlElement("SpTime", IsNullable = true)]
+ public long? ApproveTimestamp { get; set; }
+
+ ///
+ /// 获取或设置审批意见。
+ ///
+ [System.Xml.Serialization.XmlElement("Speech", IsNullable = true)]
+ public string? Speech { get; set; }
+
+ ///
+ /// 获取或设置审批意见附件 MediaId 列表。
+ ///
+ [System.Xml.Serialization.XmlArray("Attach", IsNullable = true)]
+ public string[]? SpeechMediaIdList { get; set; }
+ }
+ }
+
+ ///
+ /// 获取或设置节点审批状态。
+ ///
+ [System.Xml.Serialization.XmlElement("SpStatus")]
+ public int ApproveStatus { get; set; }
+
+ ///
+ /// 获取或设置审批方式。
+ ///
+ [System.Xml.Serialization.XmlElement("ApproverAttr")]
+ public int ApproveType { get; set; }
+
+ ///
+ /// 获取或设置审批流程详情列表。
+ ///
+ [System.Xml.Serialization.XmlArray("Details")]
+ public Types.RecordDetail[] DetailList { get; set; } = default!;
+ }
+
+ public class Comment
+ {
+ public static class Types
+ {
+ public class CommentUser
+ {
+ ///
+ /// 获取或设置评论人成员账号。
+ ///
+ [System.Xml.Serialization.XmlElement("UserId")]
+ public string UserId { get; set; } = default!;
+ }
+ }
+
+ ///
+ /// 获取或设置评论 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("CommentId")]
+ public string CommentId { get; set; } = default!;
+
+ ///
+ /// 获取或设置评论人信息。
+ ///
+ [System.Xml.Serialization.XmlElement("CommentUserInfo")]
+ public Types.CommentUser CommentUser { get; set; } = default!;
+
+ ///
+ /// 获取或设置评论内容。
+ ///
+ [System.Xml.Serialization.XmlElement("CommentContent")]
+ public string Content { get; set; } = default!;
+
+ ///
+ /// 获取或设置评论内容附件 MediaId 列表。
+ ///
+ [System.Xml.Serialization.XmlArray("Attach")]
+ public string[] MediaIdList { get; set; } = default!;
+
+ ///
+ /// 获取或设置评论时间戳。
+ ///
+ [System.Xml.Serialization.XmlElement("CommentTime")]
+ public long CreateTimestamp { get; set; }
+ }
+ }
+
+ ///
+ /// 获取或设置审批申请状态变化类型。
+ ///
+ [System.Xml.Serialization.XmlElement("StatuChangeEvent")]
+ public int StatusChangeEvent { get; set; }
+
+ ///
+ /// 获取或设置审批单号。
+ ///
+ [System.Xml.Serialization.XmlElement("SpNo")]
+ public string ApprovalNumber { get; set; } = default!;
+
+ ///
+ /// 获取或设置审批单名称。
+ ///
+ [System.Xml.Serialization.XmlElement("SpName")]
+ public string Name { get; set; } = default!;
+
+ ///
+ /// 获取或设置审批单状态。
+ ///
+ [System.Xml.Serialization.XmlElement("SpStatus")]
+ public int Status { get; set; }
+
+ ///
+ /// 获取或设置审批模板 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("TemplateId")]
+ public string TemplateId { get; set; } = default!;
+
+ ///
+ /// 获取或设置申请人信息。
+ ///
+ [System.Xml.Serialization.XmlElement("Applyer")]
+ public Types.Applicant Applicant { get; set; } = default!;
+
+ ///
+ /// 获取或设置申请时间戳。
+ ///
+ [System.Xml.Serialization.XmlElement("ApplyTime")]
+ public long ApplyTimestamp { get; set; }
+
+ ///
+ /// 获取或设置抄送人列表。
+ ///
+ [System.Xml.Serialization.XmlArray("Notifyer")]
+ public Types.Notifier[]? NotifyerList { get; set; }
+
+ ///
+ /// 获取或设置审批流程列表。
+ ///
+ [System.Xml.Serialization.XmlArray("SpRecord")]
+ public Types.Record[] RecordList { get; set; } = default!;
+
+ ///
+ /// 获取或设置评论列表。
+ ///
+ [System.Xml.Serialization.XmlArray("Comments")]
+ public Types.Comment[] CommentList { get; set; } = default!;
+ }
+ }
+
+ ///
+ /// 获取或设置应用 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("AgentID")]
+ public int AgentId { get; set; }
+
+ ///
+ /// 获取或设置审批单信息。
+ ///
+ [System.Xml.Serialization.XmlElement("ApprovalInfo")]
+ public Types.Approval Approval { get; set; } = default!;
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Batch/BatchJobResultEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Batch/BatchJobResultEvent.cs
new file mode 100644
index 00000000..e2b48169
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Batch/BatchJobResultEvent.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 EVENT.batch_job_result 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/90973
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/90240
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/91135
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/90376
+ ///
+ public class BatchJobResultEvent : WechatWorkEvent, WechatWorkEvent.Types.IXmlSerializable
+ {
+ public new static class Types
+ {
+ public class BatchJob
+ {
+ ///
+ /// 获取或设置任务 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("JobId")]
+ public string JobId { get; set; } = default!;
+
+ ///
+ /// 获取或设置任务类型。
+ ///
+ [System.Xml.Serialization.XmlElement("JobType")]
+ public string Type { get; set; } = default!;
+
+ ///
+ /// 获取或设置错误码。
+ ///
+ [System.Xml.Serialization.XmlElement("ErrCode")]
+ public int ErrorCode { get; set; }
+
+ ///
+ /// 获取或设置错误信息。
+ ///
+ [System.Xml.Serialization.XmlElement("ErrMsg", IsNullable = true)]
+ public string? ErrorMessage { get; set; }
+ }
+ }
+
+ ///
+ /// 获取或设置异步任务信息。
+ ///
+ [System.Xml.Serialization.XmlElement("BatchJob")]
+ public Types.BatchJob BatchJob { get; set; } = default!;
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Calendar/AddCalendarEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Calendar/AddCalendarEvent.cs
new file mode 100644
index 00000000..baa5308a
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Calendar/AddCalendarEvent.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 EVENT.add_calendar 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/93651
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/93704
+ ///
+ public class AddCalendarEvent : WechatWorkEvent, WechatWorkEvent.Types.IJsonSerializable, WechatWorkEvent.Types.IXmlSerializable
+ {
+ ///
+ /// 获取或设置日历 ID。
+ ///
+ [Newtonsoft.Json.JsonProperty("CalId")]
+ [System.Text.Json.Serialization.JsonPropertyName("CalId")]
+ [System.Xml.Serialization.XmlElement("CalId")]
+ public string CalendarId { get; set; } = default!;
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Calendar/DeleteCalendarEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Calendar/DeleteCalendarEvent.cs
new file mode 100644
index 00000000..0a82afeb
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Calendar/DeleteCalendarEvent.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 EVENT.delete_calendar 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/93651
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/93704
+ ///
+ public class DeleteCalendarEvent : AddCalendarEvent, WechatWorkEvent.Types.IJsonSerializable, WechatWorkEvent.Types.IXmlSerializable
+ {
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Calendar/ModifyCalendarEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Calendar/ModifyCalendarEvent.cs
new file mode 100644
index 00000000..2d6bc0da
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Calendar/ModifyCalendarEvent.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 EVENT.modify_calendar 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/93651
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/93704
+ ///
+ public class ModifyCalendarEvent : AddCalendarEvent, WechatWorkEvent.Types.IJsonSerializable, WechatWorkEvent.Types.IXmlSerializable
+ {
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Contact/ChangeContactEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Contact/ChangeContactEvent.cs
new file mode 100644
index 00000000..3e63ee28
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Contact/ChangeContactEvent.cs
@@ -0,0 +1,244 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 EVENT.change_contact 或 INFO.change_contact 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/90970
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/90971
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/90972
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90135/90240
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/92654
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/92655
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/92656
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/90639
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/90640
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/90641
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/90376
+ ///
+ public class ChangeContactEvent : WechatWorkEvent, WechatWorkEvent.Types.IXmlSerializable
+ {
+ public new static class Types
+ {
+ public class ExtendedAttribute
+ {
+ public static class Types
+ {
+ public class Attribute
+ {
+ ///
+ /// 获取或设置属性类型。
+ ///
+ [System.Xml.Serialization.XmlElement("Type")]
+ public int Type { get; set; }
+
+ ///
+ /// 获取或设置属性名称。
+ ///
+ [System.Xml.Serialization.XmlElement("Name")]
+ public string Name { get; set; } = default!;
+
+ ///
+ /// 获取或设置文本属性值。
+ ///
+ [System.Xml.Serialization.XmlElement("Text", IsNullable = true)]
+ public TextAttribute? Text { get; set; }
+
+ ///
+ /// 获取或设置网页属性值。
+ ///
+ [System.Xml.Serialization.XmlElement("Web", IsNullable = true)]
+ public WebAttribute? Web { get; set; }
+ }
+
+ public class TextAttribute
+ {
+ ///
+ /// 获取或设置文本内容。
+ ///
+ [System.Xml.Serialization.XmlElement("Value")]
+ public string Value { get; set; } = default!;
+ }
+
+ public class WebAttribute
+ {
+ ///
+ /// 获取或设置网页标题。
+ ///
+ [System.Xml.Serialization.XmlElement("Title")]
+ public string Title { get; set; } = default!;
+
+ ///
+ /// 获取或设置网页 URL。
+ ///
+ [System.Xml.Serialization.XmlElement("Url")]
+ public string Url { get; set; } = default!;
+ }
+ }
+
+ ///
+ /// 获取或设置自定义字段列表。
+ ///
+ [System.Xml.Serialization.XmlArray("Item")]
+ public Types.Attribute[] AttributeList { get; set; } = default!;
+ }
+ }
+
+ ///
+ /// 获取或设置第三方应用的 SuiteId。
+ ///
+ [System.Xml.Serialization.XmlElement("SuiteId", IsNullable = true)]
+ public string? SuiteId { get; set; }
+
+ ///
+ /// 获取或设置授权方的 CorpId。
+ ///
+ [System.Xml.Serialization.XmlElement("AuthCorpId", IsNullable = true)]
+ public string? AuthorizerCorpId { get; set; }
+
+ ///
+ /// 获取或设置操作类型。
+ ///
+ [System.Xml.Serialization.XmlElement("ChangeType")]
+ public string ActionType { get; set; } = default!;
+
+ ///
+ /// 获取或设置成员、部门或标签名称。
+ ///
+ [System.Xml.Serialization.XmlElement("Name")]
+ public string Name { get; set; } = default!;
+
+ ///
+ /// 获取或设置用户成员账号。
+ ///
+ [System.Xml.Serialization.XmlElement("UserID", IsNullable = true)]
+ public string? UserId { get; set; }
+
+ ///
+ /// 获取或设置用户成员别名。
+ ///
+ [System.Xml.Serialization.XmlElement("Alias", IsNullable = true)]
+ public string? UserAlias { get; set; }
+
+ ///
+ /// 获取或设置用户所在部门 ID(以逗号分割)。
+ ///
+ [System.Xml.Serialization.XmlElement("Department", IsNullable = true)]
+ public string? UserDepartmentIds { get; set; }
+
+ ///
+ /// 获取或设置用户的部门领导状态(以逗号分割)。
+ ///
+ [System.Xml.Serialization.XmlElement("IsLeaderInDept", IsNullable = true)]
+ public string? UserDepartmentLeaderStatus { get; set; }
+
+ ///
+ /// 获取或设置用户的主部门 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("MainDepartment", IsNullable = true)]
+ public int? UserMainDepartmentId { get; set; }
+
+ ///
+ /// 获取或设置用户邮箱。
+ ///
+ [System.Xml.Serialization.XmlElement("Email", IsNullable = true)]
+ public string? UserEmail { get; set; }
+
+ ///
+ /// 获取或设置用户手机号码。
+ ///
+ [System.Xml.Serialization.XmlElement("Mobile", IsNullable = true)]
+ public string? UserMobileNumber { get; set; }
+
+ ///
+ /// 获取或设置用户座机号码。
+ ///
+ [System.Xml.Serialization.XmlElement("Telephone", IsNullable = true)]
+ public string? UserTeleNumber { get; set; }
+
+ ///
+ /// 获取或设置用户性别。
+ ///
+ [System.Xml.Serialization.XmlElement("Gender", IsNullable = true)]
+ public int? UserGender { get; set; }
+
+ ///
+ /// 获取或设置用户地址。
+ ///
+ [System.Xml.Serialization.XmlElement("Address", IsNullable = true)]
+ public string? UserAddress { get; set; }
+
+ ///
+ /// 获取或设置用户职务。
+ ///
+ [System.Xml.Serialization.XmlElement("Position", IsNullable = true)]
+ public string? UserPosition { get; set; }
+
+ ///
+ /// 获取或设置用户头像 URL。
+ ///
+ [System.Xml.Serialization.XmlElement("Avatar", IsNullable = true)]
+ public string? UserAvatarUrl { get; set; }
+
+ ///
+ /// 获取或设置用户激活状态。
+ ///
+ [System.Xml.Serialization.XmlElement("Status", IsNullable = true)]
+ public int? UserStatus { get; set; }
+
+ ///
+ /// 获取或设置用户自定义字段信息。
+ ///
+ [System.Xml.Serialization.XmlElement("ExtAttr", IsNullable = true)]
+ public Types.ExtendedAttribute? UserExtendedAttribute { get; set; }
+
+ ///
+ /// 获取或设置部门 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("Id", IsNullable = true)]
+ public int? DepartmentId { get; set; }
+
+ ///
+ /// 获取或设置上级部门 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("ParentId", IsNullable = true)]
+ public string? DepartmentParentId { get; set; }
+
+ ///
+ /// 获取或设置部门排序值。
+ ///
+ [System.Xml.Serialization.XmlElement("Order", IsNullable = true)]
+ public int? DepartmentOrder { get; set; }
+
+ ///
+ /// 获取或设置标签 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("TagId", IsNullable = true)]
+ public int? TagId { get; set; }
+
+ ///
+ /// 获取或设置标签中新增的成员账号(以逗号分隔)。
+ ///
+ [System.Xml.Serialization.XmlElement("AddUserItems", IsNullable = true)]
+ public string? TagAddedUserIds { get; set; }
+
+ ///
+ /// 获取或设置标签中删除的成员账号(以逗号分隔)。
+ ///
+ [System.Xml.Serialization.XmlElement("DelUserItems", IsNullable = true)]
+ public string? TagRemovedUserIds { get; set; }
+
+ ///
+ /// 获取或设置标签中新增的部门 ID(以逗号分隔)。
+ ///
+ [System.Xml.Serialization.XmlElement("AddPartyItems", IsNullable = true)]
+ public string? TagAddedDepartmentIds { get; set; }
+
+ ///
+ /// 获取或设置标签中删除的部门 ID(以逗号分隔)。
+ ///
+ [System.Xml.Serialization.XmlElement("DelPartyItems", IsNullable = true)]
+ public string? TagRemovedDepartmentIds { get; set; }
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/ExternalContact/ChangeExternalChatEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/ExternalContact/ChangeExternalChatEvent.cs
new file mode 100644
index 00000000..6e39e161
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/ExternalContact/ChangeExternalChatEvent.cs
@@ -0,0 +1,55 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 EVENT.change_external_chat 或 INFO.change_external_chat 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/92130
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/92277
+ ///
+ public class ChangeExternalChatEvent : WechatWorkEvent, WechatWorkEvent.Types.IXmlSerializable
+ {
+ ///
+ /// 获取或设置第三方应用的 SuiteId。
+ ///
+ [System.Xml.Serialization.XmlElement("SuiteId", IsNullable = true)]
+ public string? SuiteId { get; set; }
+
+ ///
+ /// 获取或设置授权方的 CorpId。
+ ///
+ [System.Xml.Serialization.XmlElement("AuthCorpId", IsNullable = true)]
+ public string? AuthorizerCorpId { get; set; }
+
+ ///
+ /// 获取或设置操作类型。
+ ///
+ [System.Xml.Serialization.XmlElement("ChangeType")]
+ public string ActionType { get; set; } = default!;
+
+ ///
+ /// 获取或设置客户群 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("ChatId", IsNullable = true)]
+ public string? GroupChatId { get; set; }
+
+ ///
+ /// 获取或设置客户群变更详情。
+ ///
+ [System.Xml.Serialization.XmlElement("UpdateDetail", IsNullable = true)]
+ public string? UpdateDetail { get; set; }
+
+ ///
+ /// 获取或设置客户群入群场景值。
+ ///
+ [System.Xml.Serialization.XmlElement("JoinScene", IsNullable = true)]
+ public int? JoinScene { get; set; }
+
+ ///
+ /// 获取或设置客户群退群场景值。
+ ///
+ [System.Xml.Serialization.XmlElement("QuitScene", IsNullable = true)]
+ public int? QuitScene { get; set; }
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/ExternalContact/ChangeExternalContactEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/ExternalContact/ChangeExternalContactEvent.cs
new file mode 100644
index 00000000..b186ffef
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/ExternalContact/ChangeExternalContactEvent.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 EVENT.change_external_contact 或 INFO.change_external_contact 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/92130
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/92005
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/92277
+ ///
+ public class ChangeExternalContactEvent : WechatWorkEvent, WechatWorkEvent.Types.IXmlSerializable
+ {
+ ///
+ /// 获取或设置第三方应用的 SuiteId。
+ ///
+ [System.Xml.Serialization.XmlElement("SuiteId", IsNullable = true)]
+ public string? SuiteId { get; set; }
+
+ ///
+ /// 获取或设置授权方的 CorpId。
+ ///
+ [System.Xml.Serialization.XmlElement("AuthCorpId", IsNullable = true)]
+ public string? AuthorizerCorpId { get; set; }
+
+ ///
+ /// 获取或设置操作类型。
+ ///
+ [System.Xml.Serialization.XmlElement("ChangeType")]
+ public string ActionType { get; set; } = default!;
+
+ ///
+ /// 获取或设置用户成员账号。
+ ///
+ [System.Xml.Serialization.XmlElement("UserID", IsNullable = true)]
+ public string? UserId { get; set; }
+
+ ///
+ /// 获取或设置外部联系人账号。
+ ///
+ [System.Xml.Serialization.XmlElement("ExternalUserID", IsNullable = true)]
+ public string? ExternalUserId { get; set; }
+
+ ///
+ /// 获取或设置自定义渠道参数。
+ ///
+ [System.Xml.Serialization.XmlElement("State", IsNullable = true)]
+ public string? State { get; set; }
+
+ ///
+ /// 获取或设置欢迎语 Code。
+ ///
+ [System.Xml.Serialization.XmlElement("WelcomeCode", IsNullable = true)]
+ public string? WelcomeCode { get; set; }
+
+ ///
+ /// 获取或设置接替失败原因。
+ ///
+ [System.Xml.Serialization.XmlElement("FailReason", IsNullable = true)]
+ public string? TransferFailReason { get; set; }
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/ExternalContact/ChangeExternalTagEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/ExternalContact/ChangeExternalTagEvent.cs
new file mode 100644
index 00000000..a6c84135
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/ExternalContact/ChangeExternalTagEvent.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 EVENT.change_external_tag 或 INFO.change_external_tag 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/92130
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/92277
+ ///
+ public class ChangeExternalTagEvent : WechatWorkEvent, WechatWorkEvent.Types.IXmlSerializable
+ {
+ ///
+ /// 获取或设置第三方应用的 SuiteId。
+ ///
+ [System.Xml.Serialization.XmlElement("SuiteId", IsNullable = true)]
+ public string? SuiteId { get; set; }
+
+ ///
+ /// 获取或设置授权方的 CorpId。
+ ///
+ [System.Xml.Serialization.XmlElement("AuthCorpId", IsNullable = true)]
+ public string? AuthorizerCorpId { get; set; }
+
+ ///
+ /// 获取或设置操作类型。
+ ///
+ [System.Xml.Serialization.XmlElement("ChangeType")]
+ public string ActionType { get; set; } = default!;
+
+ ///
+ /// 获取或设置 ID 类型。
+ ///
+ [System.Xml.Serialization.XmlElement("TagType", IsNullable = true)]
+ public string IdType { get; set; } = default!;
+
+ ///
+ /// 获取或设置企业标签或标签分组 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("Id", IsNullable = true)]
+ public string? TagOrGroupId { get; set; }
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Living/LivingStatusChangeEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Living/LivingStatusChangeEvent.cs
new file mode 100644
index 00000000..9178cf92
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Living/LivingStatusChangeEvent.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 EVENT.living_status_change 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/94145
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/94308
+ ///
+ public class LivingStatusChangeEvent : WechatWorkEvent, WechatWorkEvent.Types.IXmlSerializable
+ {
+ ///
+ /// 获取或设置应用 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("AgentID")]
+ public int AgentId { get; set; }
+
+ ///
+ /// 获取或设置直播 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("LivingId")]
+ public string LivingId { get; set; } = default!;
+
+ ///
+ /// 获取或设置直播状态。
+ ///
+ [System.Xml.Serialization.XmlElement("Status")]
+ public int Status { get; set; }
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Message/ImageMessageEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Message/ImageMessageEvent.cs
new file mode 100644
index 00000000..d0369933
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Message/ImageMessageEvent.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 IMAGE 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/90239
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/90375
+ ///
+ public class ImageMessageEvent : WechatWorkEvent, WechatWorkEvent.Types.IXmlSerializable
+ {
+ ///
+ /// 获取或设置应用 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("AgentID")]
+ public int AgentId { get; set; }
+
+ ///
+ /// 获取或设置消息 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("MsgId")]
+ public long MessageId { get; set; }
+
+ ///
+ /// 获取或设置图片 URL。
+ ///
+ [System.Xml.Serialization.XmlElement("PicUrl")]
+ public string PictureUrl { get; set; } = default!;
+
+ ///
+ /// 获取或设置图片消息 MediaId。
+ ///
+ [System.Xml.Serialization.XmlElement("MediaId")]
+ public string MediaId { get; set; } = default!;
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Message/LinkMessageEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Message/LinkMessageEvent.cs
new file mode 100644
index 00000000..32a3eb8d
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Message/LinkMessageEvent.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 LINK 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/90239
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/90375
+ ///
+ public class LinkMessageEvent : WechatWorkEvent, WechatWorkEvent.Types.IXmlSerializable
+ {
+ ///
+ /// 获取或设置应用 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("AgentID")]
+ public int AgentId { get; set; }
+
+ ///
+ /// 获取或设置消息 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("MsgId")]
+ public long MessageId { get; set; }
+
+ ///
+ /// 获取或设置标题。
+ ///
+ [System.Xml.Serialization.XmlElement("Title")]
+ public string Title { get; set; } = default!;
+
+ ///
+ /// 获取或设置描述。
+ ///
+ [System.Xml.Serialization.XmlElement("Description")]
+ public string Description { get; set; } = default!;
+
+ ///
+ /// 获取或设置跳转链接 URL。
+ ///
+ [System.Xml.Serialization.XmlElement("Url")]
+ public string Url { get; set; } = default!;
+
+ ///
+ /// 获取或设置封面图片 URL。
+ ///
+ [System.Xml.Serialization.XmlElement("PicUrl")]
+ public string PictureUrl { get; set; } = default!;
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Message/LocationMessageEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Message/LocationMessageEvent.cs
new file mode 100644
index 00000000..804f720a
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Message/LocationMessageEvent.cs
@@ -0,0 +1,55 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 LOCATION 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/90239
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/90375
+ ///
+ public class LocationMessageEvent : WechatWorkEvent, WechatWorkEvent.Types.IXmlSerializable
+ {
+ ///
+ /// 获取或设置应用 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("AgentID")]
+ public int AgentId { get; set; }
+
+ ///
+ /// 获取或设置应用类型。
+ ///
+ [System.Xml.Serialization.XmlElement("AppType", IsNullable = true)]
+ public string? AppType { get; set; }
+
+ ///
+ /// 获取或设置消息 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("MsgId")]
+ public long MessageId { get; set; }
+
+ ///
+ /// 获取或设置纬度坐标。
+ ///
+ [System.Xml.Serialization.XmlElement("Location_X")]
+ public double Latitude { get; set; }
+
+ ///
+ /// 获取或设置经度坐标。
+ ///
+ [System.Xml.Serialization.XmlElement("Location_Y")]
+ public double Longitude { get; set; }
+
+ ///
+ /// 获取或设置地图缩放大小。
+ ///
+ [System.Xml.Serialization.XmlElement("Scale")]
+ public double Scale { get; set; }
+
+ ///
+ /// 获取或设置地理位置信息。
+ ///
+ [System.Xml.Serialization.XmlElement("Label")]
+ public string Label { get; set; } = default!;
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Message/TextMessageEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Message/TextMessageEvent.cs
new file mode 100644
index 00000000..231f5e48
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Message/TextMessageEvent.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 TEXT 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/90239
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/90375
+ ///
+ public class TextMessageEvent : WechatWorkEvent, WechatWorkEvent.Types.IXmlSerializable
+ {
+ ///
+ /// 获取或设置应用 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("AgentID")]
+ public int AgentId { get; set; }
+
+ ///
+ /// 获取或设置消息 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("MsgId")]
+ public long MessageId { get; set; }
+
+ ///
+ /// 获取或设置消息内容。
+ ///
+ [System.Xml.Serialization.XmlElement("Content")]
+ public string Content { get; set; } = default!;
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Message/VideoMessageEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Message/VideoMessageEvent.cs
new file mode 100644
index 00000000..8a2ccaf6
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Message/VideoMessageEvent.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 VIDEO 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/90239
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/90375
+ ///
+ public class VideoMessageEvent : WechatWorkEvent, WechatWorkEvent.Types.IXmlSerializable
+ {
+ ///
+ /// 获取或设置应用 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("AgentID")]
+ public int AgentId { get; set; }
+
+ ///
+ /// 获取或设置消息 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("MsgId")]
+ public long MessageId { get; set; }
+
+ ///
+ /// 获取或设置视频消息 MediaId。
+ ///
+ [System.Xml.Serialization.XmlElement("MediaId")]
+ public string MediaId { get; set; } = default!;
+
+ ///
+ /// 获取或设置视频消息缩略图 MediaId。
+ ///
+ [System.Xml.Serialization.XmlElement("ThumbMediaId")]
+ public string ThumbnailMediaId { get; set; } = default!;
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Message/VoiceMessageEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Message/VoiceMessageEvent.cs
new file mode 100644
index 00000000..9eab9cc6
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Message/VoiceMessageEvent.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 VOICE 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/90239
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/90375
+ ///
+ public class VoiceMessageEvent : WechatWorkEvent, WechatWorkEvent.Types.IXmlSerializable
+ {
+ ///
+ /// 获取或设置应用 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("AgentID")]
+ public int AgentId { get; set; }
+
+ ///
+ /// 获取或设置消息 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("MsgId")]
+ public long MessageId { get; set; }
+
+ ///
+ /// 获取或设置语音格式。
+ ///
+ [System.Xml.Serialization.XmlElement("Format")]
+ public string Format { get; set; } = default!;
+
+ ///
+ /// 获取或设置语音消息 MediaId。
+ ///
+ [System.Xml.Serialization.XmlElement("MediaId")]
+ public string MediaId { get; set; } = default!;
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Push/ClickPushEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Push/ClickPushEvent.cs
new file mode 100644
index 00000000..d92a8361
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Push/ClickPushEvent.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 EVENT.click 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/90240
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/90376
+ ///
+ public class ClickPushEvent : WechatWorkEvent, WechatWorkEvent.Types.IXmlSerializable
+ {
+ ///
+ /// 获取或设置应用 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("AgentID")]
+ public int AgentId { get; set; }
+
+ ///
+ /// 获取或设置事件 Key,即自定义菜单接口中的 Key 值。
+ ///
+ [System.Xml.Serialization.XmlElement("EventKey")]
+ public string EventKey { get; set; } = default!;
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Push/EnterAgentPushEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Push/EnterAgentPushEvent.cs
new file mode 100644
index 00000000..35855f7a
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Push/EnterAgentPushEvent.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 EVENT.enter_agent 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/90240
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/90376
+ ///
+ public class EnterAgentPushEvent : WechatWorkEvent, WechatWorkEvent.Types.IXmlSerializable
+ {
+ ///
+ /// 获取或设置应用 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("AgentID")]
+ public int AgentId { get; set; }
+
+ ///
+ /// 获取或设置事件 Key。
+ ///
+ [System.Xml.Serialization.XmlElement("EventKey")]
+ public string? EventKey { get; set; }
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Push/LocationPushEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Push/LocationPushEvent.cs
new file mode 100644
index 00000000..4d166c46
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Push/LocationPushEvent.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 EVENT.LOCATION 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/90240
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/90376
+ ///
+ public class LocationPushEvent : WechatWorkEvent, WechatWorkEvent.Types.IXmlSerializable
+ {
+ ///
+ /// 获取或设置应用 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("AgentID")]
+ public int AgentId { get; set; }
+
+ ///
+ /// 获取或设置应用类型。
+ ///
+ [System.Xml.Serialization.XmlElement("AppType", IsNullable = true)]
+ public string? AppType { get; set; }
+
+ ///
+ /// 获取或设置地理位置纬度。
+ ///
+ [System.Xml.Serialization.XmlElement("Latitude")]
+ public double Latitude { get; set; }
+
+ ///
+ /// 获取或设置地理位置经度。
+ ///
+ [System.Xml.Serialization.XmlElement("Longitude")]
+ public double Longitude { get; set; }
+
+ ///
+ /// 获取或设置地理位置精度。
+ ///
+ [System.Xml.Serialization.XmlElement("Precision")]
+ public double Precision { get; set; }
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Push/ScanCodePushEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Push/ScanCodePushEvent.cs
new file mode 100644
index 00000000..45abd4b0
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Push/ScanCodePushEvent.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 EVENT.scancode_push 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/90240
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/90376
+ ///
+ public class ScanCodePushEvent : WechatWorkEvent, WechatWorkEvent.Types.IXmlSerializable
+ {
+ public new static class Types
+ {
+ public class ScanCode
+ {
+ ///
+ /// 获取或设置扫描类型。
+ ///
+ [System.Xml.Serialization.XmlElement("ScanType")]
+ public string ScanType { get; set; } = default!;
+
+ ///
+ /// 获取或设置扫描结果。
+ ///
+ [System.Xml.Serialization.XmlElement("ScanResult")]
+ public string ScanResult { get; set; } = default!;
+ }
+ }
+
+ ///
+ /// 获取或设置应用 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("AgentID")]
+ public int AgentId { get; set; }
+
+ ///
+ /// 获取或设置事件 Key,即自定义菜单接口中的 Key 值。
+ ///
+ [System.Xml.Serialization.XmlElement("EventKey")]
+ public string EventKey { get; set; } = default!;
+
+ ///
+ /// 获取或设置扫描信息。
+ ///
+ [System.Xml.Serialization.XmlElement("ScanCodeInfo")]
+ public Types.ScanCode ScanCode { get; set; } = default!;
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Push/SubscribePushEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Push/SubscribePushEvent.cs
new file mode 100644
index 00000000..bbc1e0d2
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Push/SubscribePushEvent.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 EVENT.subscribe 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/90240
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/90376
+ ///
+ public class SubscribePushEvent : WechatWorkEvent, WechatWorkEvent.Types.IXmlSerializable
+ {
+ ///
+ /// 获取或设置应用 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("AgentID")]
+ public int AgentId { get; set; }
+
+ ///
+ /// 获取或设置事件 Key。
+ ///
+ [System.Xml.Serialization.XmlElement("EventKey", IsNullable = true)]
+ public string? EventKey { get; set; }
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Push/TaskCardClickPushEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Push/TaskCardClickPushEvent.cs
new file mode 100644
index 00000000..15baad08
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Push/TaskCardClickPushEvent.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 EVENT.taskcard_click 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/90240
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/90376
+ ///
+ public class TaskCardClickPushEvent : WechatWorkEvent, WechatWorkEvent.Types.IXmlSerializable
+ {
+ ///
+ /// 获取或设置应用 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("AgentID")]
+ public int AgentId { get; set; }
+
+ ///
+ /// 获取或设置事件 Key,即发送任务卡片时自定义按钮的 Key 值。
+ ///
+ [System.Xml.Serialization.XmlElement("EventKey")]
+ public string EventKey { get; set; } = default!;
+
+ ///
+ /// 获取或设置任务 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("TaskId")]
+ public string TaskId { get; set; } = default!;
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Push/UnsubscribePushEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Push/UnsubscribePushEvent.cs
new file mode 100644
index 00000000..ea8af09f
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Push/UnsubscribePushEvent.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 EVENT.unsubscribe 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/90240
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/90376
+ ///
+ public class UnsubscribePushEvent : SubscribePushEvent
+ {
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Push/ViewPushEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Push/ViewPushEvent.cs
new file mode 100644
index 00000000..d2d0a300
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Push/ViewPushEvent.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 EVENT.view 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/90240
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/90376
+ ///
+ public class ViewPushEvent : WechatWorkEvent, WechatWorkEvent.Types.IXmlSerializable
+ {
+ ///
+ /// 获取或设置应用 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("AgentID")]
+ public int AgentId { get; set; }
+
+ ///
+ /// 获取或设置事件 Key,即跳转的 URL。
+ ///
+ [System.Xml.Serialization.XmlElement("EventKey")]
+ public string EventKey { get; set; } = default!;
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Schedule/AddScheduleEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Schedule/AddScheduleEvent.cs
new file mode 100644
index 00000000..ed0efbf4
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Schedule/AddScheduleEvent.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 EVENT.add_schedule 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/93651
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/93704
+ ///
+ public class AddScheduleEvent : WechatWorkEvent, WechatWorkEvent.Types.IJsonSerializable, WechatWorkEvent.Types.IXmlSerializable
+ {
+ ///
+ /// 获取或设置日程 ID。
+ ///
+ [Newtonsoft.Json.JsonProperty("ScheduleId")]
+ [System.Text.Json.Serialization.JsonPropertyName("ScheduleId")]
+ [System.Xml.Serialization.XmlElement("ScheduleId")]
+ public string ScheduleId { get; set; } = default!;
+
+ ///
+ /// 获取或设置日历 ID。
+ ///
+ [Newtonsoft.Json.JsonProperty("CalId")]
+ [System.Text.Json.Serialization.JsonPropertyName("CalId")]
+ [System.Xml.Serialization.XmlElement("CalId")]
+ public string CalendarId { get; set; } = default!;
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Schedule/DeleteScheduleEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Schedule/DeleteScheduleEvent.cs
new file mode 100644
index 00000000..2ff8b9e7
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Schedule/DeleteScheduleEvent.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 EVENT.delete_schedule 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/93651
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/93704
+ ///
+ public class DeleteScheduleEvent : AddScheduleEvent, WechatWorkEvent.Types.IJsonSerializable, WechatWorkEvent.Types.IXmlSerializable
+ {
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Schedule/ModifyScheduleEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Schedule/ModifyScheduleEvent.cs
new file mode 100644
index 00000000..1ce65f55
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Schedule/ModifyScheduleEvent.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 EVENT.modify_schedule 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/93651
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/93704
+ ///
+ public class ModifyScheduleEvent : AddScheduleEvent, WechatWorkEvent.Types.IJsonSerializable, WechatWorkEvent.Types.IXmlSerializable
+ {
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/School/ChangeSchoolContactEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/School/ChangeSchoolContactEvent.cs
new file mode 100644
index 00000000..699f9f33
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/School/ChangeSchoolContactEvent.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 EVENT.change_school_contact 或 INFO.change_school_contact 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/92032
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/92052
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/92051
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/92050
+ ///
+ public class ChangeSchoolContactEvent : WechatWorkEvent, WechatWorkEvent.Types.IXmlSerializable
+ {
+ ///
+ /// 获取或设置第三方应用的 SuiteId。
+ ///
+ [System.Xml.Serialization.XmlElement("SuiteId", IsNullable = true)]
+ public string? SuiteId { get; set; }
+
+ ///
+ /// 获取或设置授权方的 CorpId。
+ ///
+ [System.Xml.Serialization.XmlElement("AuthCorpId", IsNullable = true)]
+ public string? AuthorizerCorpId { get; set; }
+
+ ///
+ /// 获取或设置操作类型。
+ ///
+ [System.Xml.Serialization.XmlElement("ChangeType")]
+ public string ActionType { get; set; } = default!;
+
+ ///
+ /// 获取或设置学生/家长账号或部门 ID(即班级)。
+ ///
+ [System.Xml.Serialization.XmlElement("Id", IsNullable = true)]
+ public string? StudentOrParentOrDepartmentId { get; set; }
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Service/CancelAuthEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Service/CancelAuthEvent.cs
new file mode 100644
index 00000000..c26d1254
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Service/CancelAuthEvent.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 INFO.cancel_auth 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/90642
+ ///
+ public class CancelAuthEvent : ChangeAuthEvent
+ {
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Service/ChangeAuthEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Service/ChangeAuthEvent.cs
new file mode 100644
index 00000000..4aef2af6
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Service/ChangeAuthEvent.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 INFO.change_auth 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/90642
+ ///
+ public class ChangeAuthEvent : WechatWorkEvent, WechatWorkEvent.Types.IXmlSerializable
+ {
+ ///
+ /// 获取或设置第三方应用的 SuiteId。
+ ///
+ [System.Xml.Serialization.XmlElement("SuiteId")]
+ public string SuiteId { get; set; } = default!;
+
+ ///
+ /// 获取或设置授权方的 CorpId。
+ ///
+ [System.Xml.Serialization.XmlElement("AuthCorpId")]
+ public string AuthorizerCorpId { get; set; } = default!;
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Service/CreateAuthEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Service/CreateAuthEvent.cs
new file mode 100644
index 00000000..cb755688
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Service/CreateAuthEvent.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 INFO.create_auth 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/90642
+ ///
+ public class CreateAuthEvent : WechatWorkEvent, WechatWorkEvent.Types.IXmlSerializable
+ {
+ ///
+ /// 获取或设置第三方应用的 SuiteId。
+ ///
+ [System.Xml.Serialization.XmlElement("SuiteId")]
+ public string SuiteId { get; set; } = default!;
+
+ ///
+ /// 获取或设置授权码。
+ ///
+ [System.Xml.Serialization.XmlElement("AuthCode")]
+ public string AuthCode { get; set; } = default!;
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Service/RegisterCorpEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Service/RegisterCorpEvent.cs
new file mode 100644
index 00000000..77202040
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Service/RegisterCorpEvent.cs
@@ -0,0 +1,81 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 INFO.register_corp 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/90585
+ ///
+ public class RegisterCorpEvent : WechatWorkEvent, WechatWorkEvent.Types.IXmlSerializable
+ {
+ public new static class Types
+ {
+ public class ContactSync
+ {
+ ///
+ /// 获取或设置通讯录迁移凭证。
+ ///
+ [System.Xml.Serialization.XmlElement("AccessToken")]
+ public string AccessToken { get; set; } = default!;
+
+ ///
+ /// 获取或设置通讯录迁移凭证有效期(单位:秒)。
+ ///
+ [System.Xml.Serialization.XmlElement("ExpiresIn")]
+ public int ExpiresIn { get; set; }
+ }
+
+ public class AuthorizerUser
+ {
+ ///
+ /// 获取或设置成员账号。
+ ///
+ [System.Xml.Serialization.XmlElement("UserId")]
+ public string UserId { get; set; } = default!;
+ }
+ }
+
+ ///
+ /// 获取或设置服务商 CorpId。
+ ///
+ [System.Xml.Serialization.XmlElement("ServiceCorpId")]
+ public string ServiceCorpId { get; set; } = default!;
+
+ ///
+ /// 获取或设置授权方的 CorpId。
+ ///
+ [System.Xml.Serialization.XmlElement("AuthCorpId")]
+ public string AuthorizerCorpId { get; set; } = default!;
+
+ ///
+ /// 获取或设置注册码。
+ ///
+ [System.Xml.Serialization.XmlElement("RegisterCode")]
+ public string RegisterCode { get; set; } = default!;
+
+ ///
+ /// 获取或设置通讯录迁移信息。
+ ///
+ [System.Xml.Serialization.XmlElement("ContactSync", IsNullable = true)]
+ public Types.ContactSync? ContactSync { get; set; }
+
+ ///
+ /// 获取或设置授权管理员信息。
+ ///
+ [System.Xml.Serialization.XmlElement("AuthUserInfo", IsNullable = true)]
+ public Types.AuthorizerUser? AuthorizerUser { get; set; }
+
+ ///
+ /// 获取或设置推广包 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("TemplateId")]
+ public string TemplateId { get; set; } = default!;
+
+ ///
+ /// 获取或设置自定义渠道参数。
+ ///
+ [System.Xml.Serialization.XmlElement("State", IsNullable = true)]
+ public string? State { get; set; }
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Service/ShareAgentChangeEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Service/ShareAgentChangeEvent.cs
new file mode 100644
index 00000000..8a810dc2
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Service/ShareAgentChangeEvent.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 EVENT.share_agent_change 或 INFO.share_agent_change 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90000/90135/90240
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/93373
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/90376
+ ///
+ public class ShareAgentChangeEvent : WechatWorkEvent, WechatWorkEvent.Types.IXmlSerializable
+ {
+ ///
+ /// 获取或设置第三方应用的 SuiteId。
+ ///
+ [System.Xml.Serialization.XmlElement("SuiteId", IsNullable = true)]
+ public string? SuiteId { get; set; }
+
+ ///
+ /// 获取或设置上级企业 CorpId。
+ ///
+ [System.Xml.Serialization.XmlElement("CorpId", IsNullable = true)]
+ public string? ParentCorpId { get; set; }
+
+ ///
+ /// 获取或设置上级企业应用 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("AgentId")]
+ public int ParentAgentId { get; set; }
+
+ ///
+ /// 获取或设置下级企业应用 ID。
+ ///
+ [System.Xml.Serialization.XmlElement("AppId", IsNullable = true)]
+ public int? AgentId { get; set; }
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Service/SuiteTicketEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Service/SuiteTicketEvent.cs
new file mode 100644
index 00000000..26778ee0
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/Service/SuiteTicketEvent.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work.Events
+{
+ ///
+ /// 表示 INFO.suite_ticket 事件的数据。
+ /// REF: https://open.work.weixin.qq.com/api/doc/90001/90143/90628
+ ///
+ public class SuiteTicketEvent : WechatWorkEvent, WechatWorkEvent.Types.IXmlSerializable
+ {
+ ///
+ /// 获取或设置第三方应用的 SuiteId。
+ ///
+ [System.Xml.Serialization.XmlElement("SuiteId")]
+ public string SuiteId { get; set; } = default!;
+
+ ///
+ /// 获取或设置第三方应用的 SuiteTicket。
+ ///
+ [System.Xml.Serialization.XmlElement("SuiteTicket")]
+ public string SuiteTicket { get; set; } = default!;
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Extensions/WechatWorkClientEventExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Extensions/WechatWorkClientEventExtensions.cs
new file mode 100644
index 00000000..d13b17a8
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Extensions/WechatWorkClientEventExtensions.cs
@@ -0,0 +1,44 @@
+using System;
+using System.IO;
+using System.Xml.Serialization;
+
+namespace SKIT.FlurlHttpClient.Wechat.Work
+{
+ ///
+ /// 为 提供回调通知事件的扩展方法。
+ ///
+ public static class WechatWorkClientEventExtensions
+ {
+ ///
+ /// 从 JSON 反序列化得到 对象。
+ ///
+ ///
+ ///
+ ///
+ public static TEvent DeserializeEventFromJson(this WechatWorkClient client, string callbackJson)
+ where TEvent : WechatWorkEvent, WechatWorkEvent.Types.IJsonSerializable, new()
+ {
+ if (client == null) throw new ArgumentNullException(nameof(client));
+ if (string.IsNullOrEmpty(callbackJson)) throw new ArgumentNullException(callbackJson);
+
+ return client.JsonSerializer.Deserialize(callbackJson);
+ }
+
+ ///
+ /// 从 XML 反序列化得到 对象。
+ ///
+ ///
+ ///
+ ///
+ public static TEvent DeserializeEventFromXml(this WechatWorkClient client, string callbackXml)
+ where TEvent : WechatWorkEvent, WechatWorkEvent.Types.IXmlSerializable, new()
+ {
+ if (client == null) throw new ArgumentNullException(nameof(client));
+ if (string.IsNullOrEmpty(callbackXml)) throw new ArgumentNullException(callbackXml);
+
+ using StringReader reader = new StringReader(callbackXml);
+ XmlSerializer xmlSerializer = new XmlSerializer(typeof(TEvent), new XmlRootAttribute("xml"));
+ return (TEvent)xmlSerializer.Deserialize(reader);
+ }
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/WechatWorkEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/WechatWorkEvent.cs
index 33669338..a1d705e2 100644
--- a/src/SKIT.FlurlHttpClient.Wechat.Work/WechatWorkEvent.cs
+++ b/src/SKIT.FlurlHttpClient.Wechat.Work/WechatWorkEvent.cs
@@ -10,34 +10,73 @@ namespace SKIT.FlurlHttpClient.Wechat.Work
[Serializable]
public class WechatWorkEvent
{
+ public static class Types
+ {
+ [Newtonsoft.Json.JsonObject]
+ public interface IJsonSerializable
+ {
+ }
+
+ [System.Xml.Serialization.XmlRoot("xml")]
+ public interface IXmlSerializable
+ {
+ }
+ }
+
///
- /// 获取或设置企业 CorpId。
+ /// 获取或设置企业 CorpId 或第三方应用的 SuiteId。
///
+ [Newtonsoft.Json.JsonProperty("ToUserName")]
+ [System.Text.Json.Serialization.JsonPropertyName("ToUserName")]
[XmlElement("ToUserName", IsNullable = true)]
public string? ToUserName { get; set; }
///
/// 获取或设置发送方账号。
///
+ [Newtonsoft.Json.JsonProperty("FromUserName")]
+ [System.Text.Json.Serialization.JsonPropertyName("FromUserName")]
[XmlElement("FromUserName", IsNullable = true)]
public string? FromUserName { get; set; }
///
/// 获取或设置消息类型。
///
+ [Newtonsoft.Json.JsonProperty("MsgType")]
+ [System.Text.Json.Serialization.JsonPropertyName("MsgType")]
[XmlElement("MsgType", IsNullable = true)]
public string? MessageType { get; set; }
///
/// 获取或设置事件类型。
///
+ [Newtonsoft.Json.JsonProperty("Event")]
+ [System.Text.Json.Serialization.JsonPropertyName("Event")]
[XmlElement("Event", IsNullable = true)]
public string? Event { get; set; }
///
- /// 获取或设置消息创建时间。
+ /// 获取或设置消息创建时间戳。
///
- [XmlElement("CreateTime")]
- public long CreateTimestamp { get; set; }
+ [Newtonsoft.Json.JsonProperty("CreateTime")]
+ [System.Text.Json.Serialization.JsonPropertyName("CreateTime")]
+ [XmlElement("CreateTime", IsNullable = true)]
+ public long? CreateTimestamp { get; set; }
+
+ ///
+ /// 获取或设置消息类型。
+ ///
+ [Newtonsoft.Json.JsonIgnore]
+ [System.Text.Json.Serialization.JsonIgnore]
+ [XmlElement("InfoType", IsNullable = true)]
+ public string? InfoType { get; set; }
+
+ ///
+ /// 获取或设置消息时间戳。
+ ///
+ [Newtonsoft.Json.JsonIgnore]
+ [System.Text.Json.Serialization.JsonIgnore]
+ [XmlElement("TimeStamp", IsNullable = true)]
+ public long? InfoTimestamp { get; set; }
}
}