diff --git a/internal/app/event_personal_oa_test.go b/internal/app/event_personal_oa_test.go index 4ff33c38..0f337956 100644 --- a/internal/app/event_personal_oa_test.go +++ b/internal/app/event_personal_oa_test.go @@ -29,6 +29,10 @@ func TestPersonalOAEventListAndSchemaCommands(t *testing.T) { } for _, eventKey := range []string{ personal.EventOAApprovalTaskCreated, + personal.EventOAApprovalTaskFinished, + personal.EventOAApprovalTaskRedirected, + personal.EventOAApprovalInstanceStarted, + personal.EventOAApprovalInstanceTerminated, personal.EventOAApprovalInstanceFinished, } { if !strings.Contains(listOut.String(), eventKey) { @@ -83,6 +87,10 @@ func TestPersonalOAEventConsumeDryRunAndValidation(t *testing.T) { oaEvents := []string{ personal.EventOAApprovalTaskCreated, + personal.EventOAApprovalTaskFinished, + personal.EventOAApprovalTaskRedirected, + personal.EventOAApprovalInstanceStarted, + personal.EventOAApprovalInstanceTerminated, personal.EventOAApprovalInstanceFinished, } for _, eventKey := range oaEvents { @@ -132,7 +140,7 @@ func TestPersonalOAEventConsumeDryRunAndValidation(t *testing.T) { var stderr bytes.Buffer cmd.SetOut(io.Discard) cmd.SetErr(&stderr) - cmd.SetArgs([]string{oaEvents[0], oaEvents[1], "--dry-run"}) + cmd.SetArgs(append(append([]string(nil), oaEvents...), "--dry-run")) if err := cmd.Execute(); err != nil { t.Fatalf("multi OA dry-run error = %v", err) } @@ -192,7 +200,9 @@ func TestPersonalOAEventConsumeDryRunAndValidation(t *testing.T) { cmd.SilenceErrors = true cmd.SetOut(io.Discard) cmd.SetErr(io.Discard) - cmd.SetArgs([]string{oaEvents[0], oaEvents[1], flag, value, "--dry-run"}) + args := append([]string(nil), oaEvents...) + args = append(args, flag, value, "--dry-run") + cmd.SetArgs(args) err := cmd.Execute() if err == nil || !strings.Contains(err.Error(), "not supported for OA event") { t.Fatalf("multi OA consume %s error = %v", flag, err) @@ -272,6 +282,10 @@ func TestPersonalOAMultiConsumeCreatesIndependentAllSubscriptionsOnSharedBus(t * eventKeys := []string{ personal.EventOAApprovalTaskCreated, + personal.EventOAApprovalTaskFinished, + personal.EventOAApprovalTaskRedirected, + personal.EventOAApprovalInstanceStarted, + personal.EventOAApprovalInstanceTerminated, personal.EventOAApprovalInstanceFinished, } if err := runPersonalEventConsume(newPersonalCoverageCommand(), personalConsumeOptions{ diff --git a/internal/cli/schema_agent_metadata/index.json b/internal/cli/schema_agent_metadata/index.json index c26af7b9..f4dccb70 100644 --- a/internal/cli/schema_agent_metadata/index.json +++ b/internal/cli/schema_agent_metadata/index.json @@ -1,6 +1,6 @@ { "version": 1, - "source_hash": "sha256:8fcdd1f039a25ff4b9f868fe1955d1bad87d3177400b11384da6b314151cef29", + "source_hash": "sha256:853478184de2998932c3ce94cab108a1640a96b17a9db2faedcefb169e80e690", "surface_hash": "sha256:4cf8460240b19f896c3a330c69982cbb5f57aa8576cdf30373172082eea893ed", "coverage": { "surface_products": 26, diff --git a/internal/cli/schema_agent_metadata_audit.json b/internal/cli/schema_agent_metadata_audit.json index ebcbc0dc..b91f2c50 100644 --- a/internal/cli/schema_agent_metadata_audit.json +++ b/internal/cli/schema_agent_metadata_audit.json @@ -1,6 +1,6 @@ { "version": 1, - "source_hash": "sha256:8fcdd1f039a25ff4b9f868fe1955d1bad87d3177400b11384da6b314151cef29", + "source_hash": "sha256:853478184de2998932c3ce94cab108a1640a96b17a9db2faedcefb169e80e690", "surface_hash": "sha256:4cf8460240b19f896c3a330c69982cbb5f57aa8576cdf30373172082eea893ed", "source_files": 160, "hint_files": 54, @@ -2800,7 +2800,7 @@ { "tool_path": "event consume user_im_message_receive_o2o_all", "source": "skills/mono/references/products/event.md", - "line": 125, + "line": 137, "candidates": [ "event consume", "event list", @@ -2810,7 +2810,7 @@ { "tool_path": "event consume user_im_message_receive_group_all", "source": "skills/mono/references/products/event.md", - "line": 126, + "line": 138, "candidates": [ "event consume", "event list", @@ -2820,7 +2820,7 @@ { "tool_path": "event consume user_im_message_receive_o2o user_im_message_read_o2o user_im_message_recall_o2o", "source": "skills/mono/references/products/event.md", - "line": 144, + "line": 160, "candidates": [ "event consume", "event list", @@ -2830,7 +2830,7 @@ { "tool_path": "event consume user_im_message_receive_group user_im_group_updated user_im_group_disbanded", "source": "skills/mono/references/products/event.md", - "line": 152, + "line": 168, "candidates": [ "event consume", "event list", diff --git a/internal/cli/schema_catalog.json b/internal/cli/schema_catalog.json index 93badc4c..c726cbe8 100644 --- a/internal/cli/schema_catalog.json +++ b/internal/cli/schema_catalog.json @@ -1,12 +1,12 @@ { "version": 1, - "source_hash": "sha256:d75c65a5a9c33a781c365d20c83171f1c4278a913f15abd8d6c583fa13d58a6f", + "source_hash": "sha256:ac05d2673d85f725b952faa7bd91fba6cd9032e0e7ab4708a9dc796ffd5032b8", "surface_hash": "sha256:4cf8460240b19f896c3a330c69982cbb5f57aa8576cdf30373172082eea893ed", "catalog": { "agent_metadata": { "products_with_metadata": 26, "source": "embedded-skill-metadata", - "source_hash": "sha256:8fcdd1f039a25ff4b9f868fe1955d1bad87d3177400b11384da6b314151cef29", + "source_hash": "sha256:853478184de2998932c3ce94cab108a1640a96b17a9db2faedcefb169e80e690", "surface_hash": "sha256:4cf8460240b19f896c3a330c69982cbb5f57aa8576cdf30373172082eea893ed", "surface_products": 26, "surface_tools": 813, diff --git a/internal/cli/schema_hints/index.json b/internal/cli/schema_hints/index.json index 1a1db002..2fe08629 100644 --- a/internal/cli/schema_hints/index.json +++ b/internal/cli/schema_hints/index.json @@ -723,15 +723,35 @@ "target": "event consume", "reason": "已审查的 OA 审批任务创建事件 Skill 引用,固定映射到当前公开 event consume leaf" }, + "event consume user_oa_approval_task_finished": { + "status": "alias", + "target": "event consume", + "reason": "已审查的 OA 审批任务完成事件 Skill 引用,固定映射到当前公开 event consume leaf" + }, + "event consume user_oa_approval_task_redirected": { + "status": "alias", + "target": "event consume", + "reason": "已审查的 OA 审批任务转交事件 Skill 引用,固定映射到当前公开 event consume leaf" + }, + "event consume user_oa_approval_instance_started": { + "status": "alias", + "target": "event consume", + "reason": "已审查的 OA 审批实例发起事件 Skill 引用,固定映射到当前公开 event consume leaf" + }, + "event consume user_oa_approval_instance_terminated": { + "status": "alias", + "target": "event consume", + "reason": "已审查的 OA 审批实例终止事件 Skill 引用,固定映射到当前公开 event consume leaf" + }, "event consume user_oa_approval_instance_finished": { "status": "alias", "target": "event consume", "reason": "已审查的 OA 审批实例完成事件 Skill 引用,固定映射到当前公开 event consume leaf" }, - "event consume user_oa_approval_task_created user_oa_approval_instance_finished": { + "event consume user_oa_approval_task_created user_oa_approval_task_finished user_oa_approval_task_redirected user_oa_approval_instance_started user_oa_approval_instance_terminated user_oa_approval_instance_finished": { "status": "alias", "target": "event consume", - "reason": "已审查的双 OA 事件 Skill 引用,固定映射到当前公开多事件 event consume leaf" + "reason": "已审查的六 OA 事件 Skill 引用,固定映射到当前公开多事件 event consume leaf" }, "event schema user_im_message_receive_at": { "status": "alias", @@ -818,6 +838,26 @@ "target": "event schema", "reason": "已审查的 OA 审批任务创建 event_key 引用,固定映射到当前公开 event schema leaf" }, + "event schema user_oa_approval_task_finished": { + "status": "alias", + "target": "event schema", + "reason": "已审查的 OA 审批任务完成 event_key 引用,固定映射到当前公开 event schema leaf" + }, + "event schema user_oa_approval_task_redirected": { + "status": "alias", + "target": "event schema", + "reason": "已审查的 OA 审批任务转交 event_key 引用,固定映射到当前公开 event schema leaf" + }, + "event schema user_oa_approval_instance_started": { + "status": "alias", + "target": "event schema", + "reason": "已审查的 OA 审批实例发起 event_key 引用,固定映射到当前公开 event schema leaf" + }, + "event schema user_oa_approval_instance_terminated": { + "status": "alias", + "target": "event schema", + "reason": "已审查的 OA 审批实例终止 event_key 引用,固定映射到当前公开 event schema leaf" + }, "event schema user_oa_approval_instance_finished": { "status": "alias", "target": "event schema", diff --git a/internal/cli/schema_hints/reference-review.json b/internal/cli/schema_hints/reference-review.json index 2c36dc85..17c61465 100644 --- a/internal/cli/schema_hints/reference-review.json +++ b/internal/cli/schema_hints/reference-review.json @@ -666,15 +666,35 @@ "target": "event consume", "reason": "已审查的 OA 审批任务创建事件 Skill 引用,固定映射到当前公开 event consume leaf" }, + "event consume user_oa_approval_task_finished": { + "status": "alias", + "target": "event consume", + "reason": "已审查的 OA 审批任务完成事件 Skill 引用,固定映射到当前公开 event consume leaf" + }, + "event consume user_oa_approval_task_redirected": { + "status": "alias", + "target": "event consume", + "reason": "已审查的 OA 审批任务转交事件 Skill 引用,固定映射到当前公开 event consume leaf" + }, + "event consume user_oa_approval_instance_started": { + "status": "alias", + "target": "event consume", + "reason": "已审查的 OA 审批实例发起事件 Skill 引用,固定映射到当前公开 event consume leaf" + }, + "event consume user_oa_approval_instance_terminated": { + "status": "alias", + "target": "event consume", + "reason": "已审查的 OA 审批实例终止事件 Skill 引用,固定映射到当前公开 event consume leaf" + }, "event consume user_oa_approval_instance_finished": { "status": "alias", "target": "event consume", "reason": "已审查的 OA 审批实例完成事件 Skill 引用,固定映射到当前公开 event consume leaf" }, - "event consume user_oa_approval_task_created user_oa_approval_instance_finished": { + "event consume user_oa_approval_task_created user_oa_approval_task_finished user_oa_approval_task_redirected user_oa_approval_instance_started user_oa_approval_instance_terminated user_oa_approval_instance_finished": { "status": "alias", "target": "event consume", - "reason": "已审查的双 OA 事件 Skill 引用,固定映射到当前公开多事件 event consume leaf" + "reason": "已审查的六 OA 事件 Skill 引用,固定映射到当前公开多事件 event consume leaf" }, "event schema user_im_message_receive_at": { "status": "alias", @@ -761,6 +781,26 @@ "target": "event schema", "reason": "已审查的 OA 审批任务创建 event_key 引用,固定映射到当前公开 event schema leaf" }, + "event schema user_oa_approval_task_finished": { + "status": "alias", + "target": "event schema", + "reason": "已审查的 OA 审批任务完成 event_key 引用,固定映射到当前公开 event schema leaf" + }, + "event schema user_oa_approval_task_redirected": { + "status": "alias", + "target": "event schema", + "reason": "已审查的 OA 审批任务转交 event_key 引用,固定映射到当前公开 event schema leaf" + }, + "event schema user_oa_approval_instance_started": { + "status": "alias", + "target": "event schema", + "reason": "已审查的 OA 审批实例发起 event_key 引用,固定映射到当前公开 event schema leaf" + }, + "event schema user_oa_approval_instance_terminated": { + "status": "alias", + "target": "event schema", + "reason": "已审查的 OA 审批实例终止 event_key 引用,固定映射到当前公开 event schema leaf" + }, "event schema user_oa_approval_instance_finished": { "status": "alias", "target": "event schema", diff --git a/internal/event/personal/client_test.go b/internal/event/personal/client_test.go index 23aac7d9..a6c7c496 100644 --- a/internal/event/personal/client_test.go +++ b/internal/event/personal/client_test.go @@ -128,6 +128,10 @@ func TestClientCreateRuleBasedSubscriptionsUsesDocumentedRuleParam(t *testing.T) {"receive_o2o_all", EventAllSingleChat, RuleOptions{}, map[string]any{}}, {"receive_group_all", EventAllGroupChat, RuleOptions{}, map[string]any{}}, {"oa_approval_task_created", EventOAApprovalTaskCreated, RuleOptions{}, map[string]any{}}, + {"oa_approval_task_finished", EventOAApprovalTaskFinished, RuleOptions{}, map[string]any{}}, + {"oa_approval_task_redirected", EventOAApprovalTaskRedirected, RuleOptions{}, map[string]any{}}, + {"oa_approval_instance_started", EventOAApprovalInstanceStarted, RuleOptions{}, map[string]any{}}, + {"oa_approval_instance_terminated", EventOAApprovalInstanceTerminated, RuleOptions{}, map[string]any{}}, {"oa_approval_instance_finished", EventOAApprovalInstanceFinished, RuleOptions{}, map[string]any{}}, {"read_group", EventReadGroup, RuleOptions{GroupID: "cid-1"}, map[string]any{"openConversationId": "cid-1"}}, {"recall_group", EventRecallGroup, RuleOptions{GroupID: "cid-1"}, map[string]any{"openConversationId": "cid-1"}}, diff --git a/internal/event/personal/output.go b/internal/event/personal/output.go index 528f4106..d7918f80 100644 --- a/internal/event/personal/output.go +++ b/internal/event/personal/output.go @@ -704,6 +704,10 @@ func isGroupLifecycleEvent(eventKey string) bool { func isOAEvent(eventKey string) bool { return eventKey == EventOAApprovalTaskCreated || + eventKey == EventOAApprovalTaskFinished || + eventKey == EventOAApprovalTaskRedirected || + eventKey == EventOAApprovalInstanceStarted || + eventKey == EventOAApprovalInstanceTerminated || eventKey == EventOAApprovalInstanceFinished } diff --git a/internal/event/personal/output_test.go b/internal/event/personal/output_test.go index 8b78bf4b..0bba024c 100644 --- a/internal/event/personal/output_test.go +++ b/internal/event/personal/output_test.go @@ -419,7 +419,14 @@ func TestCrossPlatformCoverageProjectOutputGroupLifecycleEvents(t *testing.T) { } func TestCrossPlatformCoverageProjectOutputOAEvents(t *testing.T) { - for _, eventKey := range []string{EventOAApprovalTaskCreated, EventOAApprovalInstanceFinished} { + for _, eventKey := range []string{ + EventOAApprovalTaskCreated, + EventOAApprovalTaskFinished, + EventOAApprovalTaskRedirected, + EventOAApprovalInstanceStarted, + EventOAApprovalInstanceTerminated, + EventOAApprovalInstanceFinished, + } { t.Run(eventKey, func(t *testing.T) { projected, err := ProjectOutput(transport.Event{ EventID: "outer-event", @@ -645,7 +652,14 @@ func TestCrossPlatformCoverageProjectOutputRejectsInvalidOAPayloads(t *testing.T {name: "array", payload: `,"payload":[]`}, {name: "string", payload: `,"payload":"invalid"`}, } - for _, eventKey := range []string{EventOAApprovalTaskCreated, EventOAApprovalInstanceFinished} { + for _, eventKey := range []string{ + EventOAApprovalTaskCreated, + EventOAApprovalTaskFinished, + EventOAApprovalTaskRedirected, + EventOAApprovalInstanceStarted, + EventOAApprovalInstanceTerminated, + EventOAApprovalInstanceFinished, + } { for _, tt := range tests { t.Run(eventKey+"/"+tt.name, func(t *testing.T) { ev := transport.Event{ diff --git a/internal/event/personal/registry.go b/internal/event/personal/registry.go index 5b4178c4..bffb7918 100644 --- a/internal/event/personal/registry.go +++ b/internal/event/personal/registry.go @@ -23,24 +23,28 @@ import ( ) const ( - EventMention = "user_im_message_receive_at" - EventSingleChat = "user_im_message_receive_o2o" - EventInChat = "user_im_message_receive_group" - EventFromUser = "user_im_message_receive_user" - EventAllSingleChat = "user_im_message_receive_o2o_all" - EventAllGroupChat = "user_im_message_receive_group_all" - EventReadO2O = "user_im_message_read_o2o" - EventReadGroup = "user_im_message_read_group" - EventRecallO2O = "user_im_message_recall_o2o" - EventRecallGroup = "user_im_message_recall_group" - EventReactionO2O = "user_im_message_reaction_o2o" - EventReactionGroup = "user_im_message_reaction_group" - EventGroupUpdated = "user_im_group_updated" - EventGroupMemberAdded = "user_im_group_member_added" - EventGroupMemberExited = "user_im_group_member_exited" - EventGroupDisbanded = "user_im_group_disbanded" - EventOAApprovalTaskCreated = "user_oa_approval_task_created" - EventOAApprovalInstanceFinished = "user_oa_approval_instance_finished" + EventMention = "user_im_message_receive_at" + EventSingleChat = "user_im_message_receive_o2o" + EventInChat = "user_im_message_receive_group" + EventFromUser = "user_im_message_receive_user" + EventAllSingleChat = "user_im_message_receive_o2o_all" + EventAllGroupChat = "user_im_message_receive_group_all" + EventReadO2O = "user_im_message_read_o2o" + EventReadGroup = "user_im_message_read_group" + EventRecallO2O = "user_im_message_recall_o2o" + EventRecallGroup = "user_im_message_recall_group" + EventReactionO2O = "user_im_message_reaction_o2o" + EventReactionGroup = "user_im_message_reaction_group" + EventGroupUpdated = "user_im_group_updated" + EventGroupMemberAdded = "user_im_group_member_added" + EventGroupMemberExited = "user_im_group_member_exited" + EventGroupDisbanded = "user_im_group_disbanded" + EventOAApprovalTaskCreated = "user_oa_approval_task_created" + EventOAApprovalTaskFinished = "user_oa_approval_task_finished" + EventOAApprovalTaskRedirected = "user_oa_approval_task_redirected" + EventOAApprovalInstanceStarted = "user_oa_approval_instance_started" + EventOAApprovalInstanceTerminated = "user_oa_approval_instance_terminated" + EventOAApprovalInstanceFinished = "user_oa_approval_instance_finished" ) const ( @@ -286,9 +290,53 @@ var definitions = []Definition{ Auth: map[string]any{"identity": "user"}, Public: true, }, + { + EventKey: EventOAApprovalTaskFinished, + DisplayName: "审批任务完成", + Description: "审批任务已完成", + Category: "oa", + RuleType: "all", + Status: StatusEnabled, + RequiredParams: nil, + Auth: map[string]any{"identity": "user"}, + Public: true, + }, + { + EventKey: EventOAApprovalTaskRedirected, + DisplayName: "审批人任务转交", + Description: "审批任务已转交", + Category: "oa", + RuleType: "all", + Status: StatusEnabled, + RequiredParams: nil, + Auth: map[string]any{"identity": "user"}, + Public: true, + }, + { + EventKey: EventOAApprovalInstanceStarted, + DisplayName: "发起审批单", + Description: "审批实例已发起", + Category: "oa", + RuleType: "all", + Status: StatusEnabled, + RequiredParams: nil, + Auth: map[string]any{"identity": "user"}, + Public: true, + }, + { + EventKey: EventOAApprovalInstanceTerminated, + DisplayName: "审批单终止", + Description: "审批实例已终止", + Category: "oa", + RuleType: "all", + Status: StatusEnabled, + RequiredParams: nil, + Auth: map[string]any{"identity": "user"}, + Public: true, + }, { EventKey: EventOAApprovalInstanceFinished, - DisplayName: "审批实例完成", + DisplayName: "审批单完成", Description: "审批实例完成,发送给审批单发起人", Category: "oa", RuleType: "all", diff --git a/internal/event/personal/registry_test.go b/internal/event/personal/registry_test.go index e1b49481..fa39e135 100644 --- a/internal/event/personal/registry_test.go +++ b/internal/event/personal/registry_test.go @@ -47,6 +47,10 @@ func TestCatalogEnabledEvents(t *testing.T) { EventGroupMemberExited, EventGroupDisbanded, EventOAApprovalTaskCreated, + EventOAApprovalTaskFinished, + EventOAApprovalTaskRedirected, + EventOAApprovalInstanceStarted, + EventOAApprovalInstanceTerminated, EventOAApprovalInstanceFinished, } if !reflect.DeepEqual(keys, want) { @@ -56,7 +60,14 @@ func TestCatalogEnabledEvents(t *testing.T) { func TestOAEventCatalogDefinitions(t *testing.T) { items := Catalog("oa", true, false) - wantKeys := []string{EventOAApprovalTaskCreated, EventOAApprovalInstanceFinished} + wantKeys := []string{ + EventOAApprovalTaskCreated, + EventOAApprovalTaskFinished, + EventOAApprovalTaskRedirected, + EventOAApprovalInstanceStarted, + EventOAApprovalInstanceTerminated, + EventOAApprovalInstanceFinished, + } if len(items) != len(wantKeys) { t.Fatalf("Catalog(oa) = %#v, want %d events", items, len(wantKeys)) } @@ -144,6 +155,10 @@ func TestSchemaDocumentsDefaultToTransportEnvelope(t *testing.T) { EventGroupMemberExited, EventGroupDisbanded, EventOAApprovalTaskCreated, + EventOAApprovalTaskFinished, + EventOAApprovalTaskRedirected, + EventOAApprovalInstanceStarted, + EventOAApprovalInstanceTerminated, EventOAApprovalInstanceFinished, } { t.Run(eventKey, func(t *testing.T) { @@ -461,7 +476,14 @@ func TestGroupLifecycleSchemaDocumentsUseConservativePayload(t *testing.T) { func TestOAEventSchemaDocumentsUseConservativePayload(t *testing.T) { wantProperties := []string{"type", "event_id", "timestamp", "subscribe_id", "payload"} - for _, eventKey := range []string{EventOAApprovalTaskCreated, EventOAApprovalInstanceFinished} { + for _, eventKey := range []string{ + EventOAApprovalTaskCreated, + EventOAApprovalTaskFinished, + EventOAApprovalTaskRedirected, + EventOAApprovalInstanceStarted, + EventOAApprovalInstanceTerminated, + EventOAApprovalInstanceFinished, + } { t.Run(eventKey, func(t *testing.T) { def, ok := Lookup(eventKey) if !ok { @@ -558,6 +580,10 @@ func TestBuildRuleParamAllEvents(t *testing.T) { EventAllSingleChat, EventAllGroupChat, EventOAApprovalTaskCreated, + EventOAApprovalTaskFinished, + EventOAApprovalTaskRedirected, + EventOAApprovalInstanceStarted, + EventOAApprovalInstanceTerminated, EventOAApprovalInstanceFinished, } { t.Run(eventKey, func(t *testing.T) { @@ -766,6 +792,10 @@ func TestSupportsMessageFilter(t *testing.T) { EventReactionGroup, EventGroupUpdated, EventOAApprovalTaskCreated, + EventOAApprovalTaskFinished, + EventOAApprovalTaskRedirected, + EventOAApprovalInstanceStarted, + EventOAApprovalInstanceTerminated, EventOAApprovalInstanceFinished, "unknown_event", } { diff --git a/skills/mono/SKILL.md b/skills/mono/SKILL.md index 55ff2623..748cbe7e 100644 --- a/skills/mono/SKILL.md +++ b/skills/mono/SKILL.md @@ -1,6 +1,6 @@ --- name: dws -description: 管理钉钉产品能力(AI表格/AI搜问/日历/通讯录/群聊与机器人/待办/审批/考勤/日志/DING消息/开放平台文档/钉钉文档/钉钉云盘/原生Markdown文件/AI听记/邮箱/在线电子表格/知识库等)。当用户需要操作表格数据、管理日程会议、模糊找人/查谁负责某事项、查询通讯录、管理群聊、机器人发消息、创建待办、提交审批、查看考勤、提交日报周报(钉钉日志模版)、读写钉钉文档、上传下载云盘文件、读取或修改原生.md文件、查询听记纪要、收发邮件、读写在线电子表格(axls)、管理钉钉知识库,或订阅个人 IM 事件或 OA 审批事件、实时监听群成员加入、群成员退出、群改名和群解散、审批任务创建和审批实例完成时使用。 +description: 管理钉钉产品能力(AI表格/AI搜问/日历/通讯录/群聊与机器人/待办/审批/考勤/日志/DING消息/开放平台文档/钉钉文档/钉钉云盘/原生Markdown文件/AI听记/邮箱/在线电子表格/知识库等)。当用户需要操作表格数据、管理日程会议、模糊找人/查谁负责某事项、查询通讯录、管理群聊、机器人发消息、创建待办、提交审批、查看考勤、提交日报周报(钉钉日志模版)、读写钉钉文档、上传下载云盘文件、读取或修改原生.md文件、查询听记纪要、收发邮件、读写在线电子表格(axls)、管理钉钉知识库,或订阅个人 IM 事件或 OA 审批事件、实时监听群成员加入、群成员退出、群改名和群解散、审批实例发起/终止/完成,以及审批任务创建/完成/转交时使用。 cli_version: ">=1.0.15" --- @@ -94,7 +94,7 @@ cli_version: ">=1.0.15" | `sheet` | 在线电子表格(axls):工作表 CRUD/区域读写/CSV 批量写入/行列增删/合并/查找替换/筛选视图/全局筛选/排序/下拉列表/条件格式/浮动图片/浮动图表/模板/导出 xlsx(单命令一站式) | [sheet.md](./references/products/sheet.md) | | `todo` | 待办:创建(含优先级/截止时间/循环)/查询/修改/标记完成/删除 | [todo.md](./references/products/todo.md) | | `wiki` | 知识库:空间创建/详情/列表/搜索 + 成员管理 | [wiki.md](./references/products/wiki.md) | -| `event` | 个人 IM/OA 事件:监听消息、群生命周期、审批任务创建与审批实例完成,NDJSON 输出(实时驱动 Agent)| [event.md](./references/products/event.md) | +| `event` | 个人 IM/OA 事件:监听消息、群生命周期、审批实例发起/终止/完成与审批任务创建/完成/转交,NDJSON 输出(实时驱动 Agent)| [event.md](./references/products/event.md) | ## 意图判断决策树 @@ -120,7 +120,7 @@ cli_version: ">=1.0.15" 用户提到"在线电子表格/钉钉表格/axls/工作表/单元格读写/合并单元格/筛选视图/导出 xlsx" → `sheet` 用户提到"待办/TODO/任务提醒/循环待办" → `todo` 用户提到"创建知识库/知识库列表/搜索知识库空间/wiki/团队空间/知识库成员管理/我的文档个人空间" → `wiki` -用户提到"监听有人@我/监听单聊或群消息/监听所有单聊或群消息/监听某人发送的消息/监听消息已读/监听消息撤回/监听消息贴表情或表情回应/监听群成员加入/监听群成员退出/监听群改名或群解散/监听待我审批的任务/监听审批任务创建/监听我发起的审批完成/监听审批实例完成/订阅个人 IM 或 OA 事件/实时接收钉钉事件/个人事件流/event consume user_im_message_*/event consume user_oa_approval_*/监听并自动回复消息/驱动 Agent 处理消息" → `event` +用户提到"监听有人@我/监听单聊或群消息/监听所有单聊或群消息/监听某人发送的消息/监听消息已读/监听消息撤回/监听消息贴表情或表情回应/监听群成员加入/监听群成员退出/监听群改名或群解散/监听待我审批的任务/监听审批任务创建/完成/转交/监听审批单发起/监听审批单终止/监听我发起的审批完成/监听审批实例完成/订阅个人 IM 或 OA 事件/实时接收钉钉事件/个人事件流/event consume user_im_message_*/event consume user_oa_approval_*/监听并自动回复消息/驱动 Agent 处理消息" → `event` 事件监听中,同一目标、同一过滤条件的多个兼容事件优先生成一个 `dws event consume [event_key...] --flatten`;不同用户、不同群或不同过滤条件拆成多个 consume 进程。 diff --git a/skills/mono/references/products/event.md b/skills/mono/references/products/event.md index 5304845a..be5758d7 100644 --- a/skills/mono/references/products/event.md +++ b/skills/mono/references/products/event.md @@ -1,6 +1,6 @@ # dws event — 个人 IM 与 OA 审批事件 -通过个人 Stream 长连接监听当前用户的钉钉消息接收、全量消息、已读、撤回、表情回应、群生命周期、审批任务创建和审批实例完成事件,NDJSON 输出到 stdout,用于驱动事件触发的 Agent。实时监听、自动回复、订阅事件都必须使用 `dws event consume`,不要写脚本轮询消息历史或审批列表。 +通过个人 Stream 长连接监听当前用户的钉钉消息接收、全量消息、已读、撤回、表情回应、群生命周期、审批实例发起/终止/完成,以及审批任务创建/完成/转交事件,NDJSON 输出到 stdout,用于驱动事件触发的 Agent。实时监听、自动回复、订阅事件都必须使用 `dws event consume`,不要写脚本轮询消息历史或审批列表。 ## 运行方式 @@ -43,9 +43,13 @@ | `user_im_group_member_exited` | 指定群聊有成员退出 | `--group` | | `user_im_group_disbanded` | 指定群聊被解散 | `--group` | | `user_oa_approval_task_created` | 审批任务创建,发送给审批人 | 无 | +| `user_oa_approval_task_finished` | 审批任务已完成 | 无 | +| `user_oa_approval_task_redirected` | 审批任务已转交 | 无 | +| `user_oa_approval_instance_started` | 审批实例已发起 | 无 | +| `user_oa_approval_instance_terminated` | 审批实例已终止 | 无 | | `user_oa_approval_instance_finished` | 审批实例完成,发送给审批单发起人 | 无 | -只承认上表 18 个事件码。默认身份就是当前用户,使用当前用户 OAuth 登录态,不要额外加身份切换 flag。两个 OA 事件订阅当前用户相关的全部审批事件,规则均为 `all`、空 `filterRule`,不需要目标参数。 +只承认上表 22 个事件码。默认身份就是当前用户,使用当前用户 OAuth 登录态,不要额外加身份切换 flag。六个 OA 事件订阅当前用户相关的全部审批事件,规则均为 `all`、空 `filterRule`,不需要目标参数。 ## Intent mapping @@ -73,8 +77,12 @@ | "同时监听同一人的单聊、已读和撤回" | 一个 consume 放入 3 个 event key,共享同一个 `--user` | | "同时监听同一群的消息、改名和解散" | 一个 consume 放入 3 个 event key,共享同一个 `--group` | | "监听新的待我审批任务" / "有审批任务创建时通知我" | `event consume`,事件码 `user_oa_approval_task_created`,参数 `--flatten -f ndjson` | +| "审批任务完成时通知我" | `event consume`,事件码 `user_oa_approval_task_finished`,参数 `--flatten -f ndjson` | +| "审批任务被转交时通知我" | `event consume`,事件码 `user_oa_approval_task_redirected`,参数 `--flatten -f ndjson` | +| "有审批单发起时通知我" | `event consume`,事件码 `user_oa_approval_instance_started`,参数 `--flatten -f ndjson` | +| "有审批单终止时通知我" | `event consume`,事件码 `user_oa_approval_instance_terminated`,参数 `--flatten -f ndjson` | | "监听我发起的审批何时完成" / "审批实例完成时通知我" | `event consume`,事件码 `user_oa_approval_instance_finished`,参数 `--flatten -f ndjson` | -| "同时监听审批任务创建和审批完成" | 一个 consume 放入两个 OA event key,不加目标或消息过滤参数 | +| "同时监听全部已公开 OA 事件" | 一个 consume 放入六个 OA event key,不加目标或消息过滤参数 | | "查看个人事件 schema" | `dws event schema --flatten` | | "看个人事件订阅状态" | `dws event status --event ` | | "停止这个个人事件订阅" | `dws event stop --dry-run`,确认后改用 `--yes` | @@ -112,6 +120,10 @@ dws event schema user_im_group_member_added --flatten dws event schema user_im_group_member_exited --flatten dws event schema user_im_group_disbanded --flatten dws event schema user_oa_approval_task_created --flatten +dws event schema user_oa_approval_task_finished --flatten +dws event schema user_oa_approval_task_redirected --flatten +dws event schema user_oa_approval_instance_started --flatten +dws event schema user_oa_approval_instance_terminated --flatten dws event schema user_oa_approval_instance_finished --flatten ``` @@ -135,6 +147,10 @@ dws event consume user_im_group_member_added --group --flat dws event consume user_im_group_member_exited --group --flatten -f ndjson dws event consume user_im_group_disbanded --group --flatten -f ndjson dws event consume user_oa_approval_task_created --flatten -f ndjson +dws event consume user_oa_approval_task_finished --flatten -f ndjson +dws event consume user_oa_approval_task_redirected --flatten -f ndjson +dws event consume user_oa_approval_instance_started --flatten -f ndjson +dws event consume user_oa_approval_instance_terminated --flatten -f ndjson dws event consume user_oa_approval_instance_finished --flatten -f ndjson ``` @@ -159,12 +175,16 @@ dws event consume \ dws event consume \ user_oa_approval_task_created \ + user_oa_approval_task_finished \ + user_oa_approval_task_redirected \ + user_oa_approval_instance_started \ + user_oa_approval_instance_terminated \ user_oa_approval_instance_finished \ --flatten \ -f ndjson ``` -用户类事件共享 `--user` 或 `--open-dingtalk-id`,群类事件共享 `--group`,无目标 IM 事件可加入任一组合。用户类与群类、不同目标或不同过滤条件要拆成多个进程。两个 OA 事件可以同进程消费并共享 personal bus,但各自建立独立订阅。多事件共享 `--query` / `--filter-json` 时,所选事件必须全部是 IM 消息接收事件;OA 事件单独或组合消费都禁止使用这两个消息过滤参数。 +用户类事件共享 `--user` 或 `--open-dingtalk-id`,群类事件共享 `--group`,无目标 IM 事件可加入任一组合。用户类与群类、不同目标或不同过滤条件要拆成多个进程。六个 OA 事件可以同进程消费并共享 personal bus,但各自建立独立订阅。多事件共享 `--query` / `--filter-json` 时,所选事件必须全部是 IM 消息接收事件;OA 事件单独或组合消费都禁止使用这两个消息过滤参数。 上述所有 `*_o2o` 命令和 `user_im_message_receive_user` 都可将 `--user ` 替换为 `--open-dingtalk-id `,但两个参数不能同时使用。 diff --git a/skills/multi/dingtalk-event/SKILL.md b/skills/multi/dingtalk-event/SKILL.md index b6386738..a272b673 100644 --- a/skills/multi/dingtalk-event/SKILL.md +++ b/skills/multi/dingtalk-event/SKILL.md @@ -1,6 +1,6 @@ --- name: dingtalk-event -description: 钉钉个人 IM 事件与 OA 审批事件长连接监听、订阅与消费,覆盖消息接收、全部单聊/群消息、指定发送人、已读、撤回、表情回应、群生命周期、审批任务创建和审批实例完成,输出 NDJSON 到 stdout。Use when 用户提到 监听个人消息事件、监听所有单聊或群消息、被@消息、监听单聊或群消息、监听某人发送的消息、监听消息已读、监听消息撤回、监听消息贴表情或表情回应、监听群成员加入、监听群成员退出、监听群改名或群解散、监听待我审批的任务、监听我发起的审批完成、实时接收钉钉事件、用事件驱动 Agent。命令前缀:dws event。 +description: 钉钉个人 IM 事件与 OA 审批事件长连接监听、订阅与消费,覆盖消息接收、全部单聊/群消息、指定发送人、已读、撤回、表情回应、群生命周期、审批实例发起/终止/完成,以及审批任务创建/完成/转交,输出 NDJSON 到 stdout。Use when 用户提到 监听个人消息事件、监听所有单聊或群消息、被@消息、监听单聊或群消息、监听某人发送的消息、监听消息已读、监听消息撤回、监听消息贴表情或表情回应、监听群成员加入、监听群成员退出、监听群改名或群解散、监听待我审批的任务、监听审批任务完成或转交、监听审批单发起、监听审批单终止、监听我发起的审批完成、实时接收钉钉事件、用事件驱动 Agent。命令前缀:dws event。 --- # 钉钉个人事件 @@ -48,9 +48,13 @@ description: 钉钉个人 IM 事件与 OA 审批事件长连接监听、订阅 | `user_im_group_member_exited` | 指定群聊有成员退出 | `--group` | | `user_im_group_disbanded` | 指定群聊被解散 | `--group` | | `user_oa_approval_task_created` | 审批任务创建,发送给审批人 | 无 | +| `user_oa_approval_task_finished` | 审批任务已完成 | 无 | +| `user_oa_approval_task_redirected` | 审批任务已转交 | 无 | +| `user_oa_approval_instance_started` | 审批实例已发起 | 无 | +| `user_oa_approval_instance_terminated` | 审批实例已终止 | 无 | | `user_oa_approval_instance_finished` | 审批实例完成,发送给审批单发起人 | 无 | -只承认上表 18 个事件码。其它身份模式、应用凭证模式和未列出的个人事件不在本 skill 范围内。 +只承认上表 22 个事件码。其它身份模式、应用凭证模式和未列出的个人事件不在本 skill 范围内。 ## Command rules @@ -67,11 +71,11 @@ description: 钉钉个人 IM 事件与 OA 审批事件长连接监听、订阅 - “监听群改名/群标题变更”使用 `user_im_group_updated`;“监听有人进群”使用 `user_im_group_member_added`;“监听有人退群”使用 `user_im_group_member_exited`;“监听群解散”使用 `user_im_group_disbanded`。群解散自测只能使用明确的测试群,并在执行解散操作前再次提示其不可逆影响。 - 用户要求执行“撤回消息”时使用 `dws chat`;只有“监听/订阅消息撤回”才使用 `dws event consume user_im_message_recall_*`。 - 用户说“贴标签”且语义是给消息贴表情时,按消息表情回应事件处理,event key 使用 `reaction`。 -- “有新的待我审批任务/审批任务创建”使用 `user_oa_approval_task_created`;“我发起的审批完成/审批实例完成”使用 `user_oa_approval_instance_finished`。两者都是当前用户相关的全部 OA 事件,不加 `--user`、`--open-dingtalk-id` 或 `--group`。 +- “有新的待我审批任务/审批任务创建”使用 `user_oa_approval_task_created`;“审批任务完成”使用 `user_oa_approval_task_finished`;“审批任务转交”使用 `user_oa_approval_task_redirected`;“审批单发起”使用 `user_oa_approval_instance_started`;“审批单终止”使用 `user_oa_approval_instance_terminated`;“我发起的审批完成/审批实例完成”使用 `user_oa_approval_instance_finished`。这些事件都是当前用户相关的全部 OA 事件,不加 `--user`、`--open-dingtalk-id` 或 `--group`。 - 正常 Agent 消费统一显式使用 `--flatten -f ndjson`。抓一条样本可用 `--flatten --max-events 1 -f json`。`--format` 只控制 JSON 序列化,`--flatten` 才控制数据结构。 - 同一目标、同一过滤条件的兼容事件优先放在一个 `consume` 命令中:用户类事件共享一个 `--user` 或 `--open-dingtalk-id`,群类事件共享一个 `--group`,无目标 IM 事件可加入任一类组合。 - 用户类与群类事件不能放进同一命令;不同用户、不同群或不同过滤条件必须启动多个 consume 进程。多事件命令不使用 `--subscribe-id`、`--rule`、`--event-types`、`--filter`、`--foreground`、`--force` 或 `--debug-raw-events`。 -- 两个 OA 事件可放进同一 `consume`;每个事件建立独立订阅并共享 personal bus。OA 事件不支持 `--query` 或 `--filter-json`,包含 OA 事件的多事件命令也不能使用这两个消息过滤参数。 +- 六个 OA 事件可放进同一 `consume`;每个事件建立独立订阅并共享 personal bus。OA 事件不支持 `--query` 或 `--filter-json`,包含 OA 事件的多事件命令也不能使用这两个消息过滤参数。 - 多事件共享 `--query` / `--filter-json` 时,所选事件必须全部是 IM 消息接收事件;已读、撤回、表情回应、群生命周期或 OA 事件混入后不能使用消息过滤参数。 - 监听非默认组织时带 `--profile `;漏传会退回默认 profile 而失败。 - 自己发的消息不作为事件回来(`isSelfLoop` 过滤):边监听边 `dws chat message send` 回复不成环;测试投递用别人 / 机器人发(自发会看到 0 事件)。 @@ -201,9 +205,13 @@ dws event consume \ --flatten \ -f ndjson -# 当前用户相关的审批任务创建和审批实例完成(一个进程) +# 当前用户相关的全部 OA 审批事件(一个进程) dws event consume \ user_oa_approval_task_created \ + user_oa_approval_task_finished \ + user_oa_approval_task_redirected \ + user_oa_approval_instance_started \ + user_oa_approval_instance_terminated \ user_oa_approval_instance_finished \ --flatten \ -f ndjson @@ -244,4 +252,4 @@ dws event consume user_im_message_receive_o2o \ | Topic | Reference | Coverage | |---|---|---| | IM | [references/event-im.md](references/event-im.md) | 十六类个人 IM 事件命令、参数、生命周期、输出解析、自测和排障 | -| OA | [references/event-oa.md](references/event-oa.md) | 两类个人 OA 审批事件、无参数订阅、双事件消费和保守 payload 契约 | +| OA | [references/event-oa.md](references/event-oa.md) | 六类个人 OA 审批事件、无参数订阅、多事件消费和保守 payload 契约 | diff --git a/skills/multi/dingtalk-event/references/event-oa.md b/skills/multi/dingtalk-event/references/event-oa.md index fd590e98..81039ee0 100644 --- a/skills/multi/dingtalk-event/references/event-oa.md +++ b/skills/multi/dingtalk-event/references/event-oa.md @@ -1,6 +1,6 @@ # OA 个人审批事件 -先读上层 [SKILL.md](../SKILL.md) 的命令规则、调用流和子进程契约。本参考覆盖当前公开的两个 OA 个人事件:审批任务创建和审批实例完成。 +先读上层 [SKILL.md](../SKILL.md) 的命令规则、调用流和子进程契约。本参考覆盖当前公开的六个 OA 个人事件:审批实例发起、终止和完成,以及审批任务创建、完成和转交。 实时监听审批事件必须使用 `dws event consume` 长连接,不要轮询 OA 待办或审批实例列表来模拟事件。 @@ -19,21 +19,29 @@ dws auth login | 事件码 | 订阅规则 | 接收语义 | 必填参数 | |---|---|---|---| | `user_oa_approval_task_created` | `all` | 审批任务创建,发送给审批人 | 无 | +| `user_oa_approval_task_finished` | `all` | 审批任务已完成 | 无 | +| `user_oa_approval_task_redirected` | `all` | 审批任务已转交 | 无 | +| `user_oa_approval_instance_started` | `all` | 审批实例已发起 | 无 | +| `user_oa_approval_instance_terminated` | `all` | 审批实例已终止 | 无 | | `user_oa_approval_instance_finished` | `all` | 审批实例完成,发送给审批单发起人 | 无 | -只承认上表 2 个 OA 事件码。CLI 为每个事件发送 `ruleType=all`、`filterRule={}` 的独立订阅请求;不要添加 `--user`、`--open-dingtalk-id`、`--group`、`--query` 或 `--filter-json`。 +只承认上表 6 个 OA 事件码。CLI 为每个事件发送 `ruleType=all`、`filterRule={}` 的独立订阅请求;不要添加 `--user`、`--open-dingtalk-id`、`--group`、`--query` 或 `--filter-json`。 ## Intent mapping | 用户说 | 下一步 | |---|---| | “监听新的待我审批任务” / “有审批任务创建时通知我” | `dws event consume user_oa_approval_task_created --flatten -f ndjson` | +| “审批任务完成时通知我” | `dws event consume user_oa_approval_task_finished --flatten -f ndjson` | +| “审批任务被转交时通知我” | `dws event consume user_oa_approval_task_redirected --flatten -f ndjson` | +| “有审批单发起时通知我” | `dws event consume user_oa_approval_instance_started --flatten -f ndjson` | +| “有审批单终止时通知我” | `dws event consume user_oa_approval_instance_terminated --flatten -f ndjson` | | “监听我发起的审批何时完成” / “审批实例完成时通知我” | `dws event consume user_oa_approval_instance_finished --flatten -f ndjson` | -| “同时监听审批任务创建和审批完成” | 一个 consume 放入两个 OA event key,不加目标或过滤参数 | +| “同时监听全部已公开 OA 事件” | 一个 consume 放入六个 OA event key,不加目标或过滤参数 | | “查看 OA 事件目录” | `dws event list --category oa` | | “查看 OA 事件输出字段” | 对对应事件运行 `dws event schema --flatten` | -审批任务创建事件只表达“任务已创建并投递给当前审批人”;审批实例完成事件只表达“当前用户发起的审批已完成”。首版不推断审批结果、任务 ID 或实例 ID 的具体 payload 字段。 +三个审批任务事件分别表达任务已创建、已完成和已转交;三个审批实例事件分别表达实例已发起、已终止和已完成。首版不推断审批结果、任务 ID、实例 ID、转交对象或终止原因的具体 payload 字段。 ## Commands @@ -41,6 +49,10 @@ dws auth login ```bash dws event schema user_oa_approval_task_created --flatten +dws event schema user_oa_approval_task_finished --flatten +dws event schema user_oa_approval_task_redirected --flatten +dws event schema user_oa_approval_instance_started --flatten +dws event schema user_oa_approval_instance_terminated --flatten dws event schema user_oa_approval_instance_finished --flatten ``` @@ -48,20 +60,28 @@ dws event schema user_oa_approval_instance_finished --flatten ```bash dws event consume user_oa_approval_task_created --flatten -f ndjson +dws event consume user_oa_approval_task_finished --flatten -f ndjson +dws event consume user_oa_approval_task_redirected --flatten -f ndjson +dws event consume user_oa_approval_instance_started --flatten -f ndjson +dws event consume user_oa_approval_instance_terminated --flatten -f ndjson dws event consume user_oa_approval_instance_finished --flatten -f ndjson ``` -同时监听两种事件: +同时监听六种事件: ```bash dws event consume \ user_oa_approval_task_created \ + user_oa_approval_task_finished \ + user_oa_approval_task_redirected \ + user_oa_approval_instance_started \ + user_oa_approval_instance_terminated \ user_oa_approval_instance_finished \ --flatten \ -f ndjson ``` -双事件 consume 会为两个 event key 分别创建订阅和逻辑 consumer,并共享当前组织的 personal bus、远程连接、stdout 和生命周期。不要给 OA 命令加 `--query` 或 `--filter-json`;这两个 flag 只用于兼容的 IM 消息接收事件。 +多事件 consume 会为六个 event key 分别创建订阅和逻辑 consumer,并共享当前组织的 personal bus、远程连接、stdout 和生命周期。不要给 OA 命令加 `--query` 或 `--filter-json`;这两个 flag 只用于兼容的 IM 消息接收事件。 ## Output contract @@ -86,6 +106,6 @@ dws event consume \ ## Lifecycle - 单事件等待 `[event] ready event_key= bus_pid= subscribe_id=`。 -- 双事件先保存两条 `[event] subscription event_key= subscribe_id=`,再等待 `[event] ready event_count=2 bus_pid=`。 +- 六事件先保存六条 `[event] subscription event_key= subscribe_id=`,再等待 `[event] ready event_count=6 bus_pid=`。 - 临时验证使用 `--max-events 1` 或 `--duration 10m`;任务完成后优雅结束 consume,本次新建的订阅会自动取消。 - 外部停止已有订阅时先运行 `dws event stop --dry-run`,确认后再加 `--yes`。不要 `kill -9`,否则会跳过自动退订。