weaver-work-cli 0.1.5 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -9
- package/dist/cmd/skills/index.js +60 -0
- package/dist/internal/e10/auth/commands.js +48 -32
- package/dist/internal/e10/auth/session.js +44 -3
- package/dist/internal/e10/auth/xiaoe.js +363 -11
- package/dist/internal/e10/context.js +4 -2
- package/dist/internal/skills/detector.js +42 -0
- package/dist/internal/skills/install.js +50 -3
- package/dist/shortcuts/archive/render/search-format.js +12 -3
- package/dist/shortcuts/ebuilder-form/continuation.js +70 -0
- package/dist/shortcuts/ebuilder-form/errors.js +54 -0
- package/dist/shortcuts/ebuilder-form/host.js +1238 -0
- package/dist/shortcuts/ebuilder-form/index.js +108 -0
- package/dist/shortcuts/ebuilder-form/manifest.js +347 -0
- package/dist/shortcuts/ebuilder-form/operations/read.js +157 -0
- package/dist/shortcuts/ebuilder-form/operations/registry.js +56 -0
- package/dist/shortcuts/ebuilder-form/operations/shared.js +132 -0
- package/dist/shortcuts/ebuilder-form/operations/types.js +19 -0
- package/dist/shortcuts/ebuilder-form/operations/write.js +277 -0
- package/dist/shortcuts/ebuilder-form/operations.js +8 -0
- package/dist/shortcuts/ehr/operations/salary.js +2 -140
- package/dist/shortcuts/im/continuation.js +70 -0
- package/dist/shortcuts/{yimiaoban → im}/errors.js +14 -14
- package/dist/shortcuts/{yimiaoban → im}/host.js +26 -26
- package/dist/shortcuts/{yimiaoban → im}/index.js +42 -42
- package/dist/shortcuts/{yimiaoban → im}/manifest.js +7 -6
- package/dist/shortcuts/{yimiaoban → im}/operations/file-user.js +54 -41
- package/dist/shortcuts/{yimiaoban → im}/operations/group-read.js +46 -44
- package/dist/shortcuts/{yimiaoban → im}/operations/group-write.js +113 -66
- package/dist/shortcuts/{yimiaoban → im}/operations/msg-sync.js +164 -141
- package/dist/shortcuts/{yimiaoban → im}/operations/msg-write.js +47 -47
- package/dist/shortcuts/{yimiaoban → im}/operations/person.js +10 -10
- package/dist/shortcuts/{yimiaoban → im}/operations/registry.js +10 -8
- package/dist/shortcuts/{yimiaoban → im}/operations/session.js +82 -83
- package/dist/shortcuts/im/operations/shared.js +442 -0
- package/dist/shortcuts/{yimiaoban → im}/operations/types.js +1 -1
- package/dist/shortcuts/im/operations/user-remind.js +201 -0
- package/dist/shortcuts/{yimiaoban → im}/operations/write-util.js +7 -7
- package/dist/shortcuts/{yimiaoban → im}/operations.js +3 -3
- package/dist/shortcuts/index.js +10 -2
- package/dist/shortcuts/invoice/manifest.js +113 -10
- package/dist/shortcuts/invoice/operations/import.js +39 -14
- package/dist/shortcuts/invoice/operations/reim.js +38 -18
- package/dist/shortcuts/invoice/operations/shared.js +35 -6
- package/dist/shortcuts/jiuchuanhui/manifest.js +3 -3
- package/dist/shortcuts/jiuchuanhui/operations/registry.js +2 -2
- package/dist/shortcuts/{yimiaoban → okr}/continuation.js +10 -10
- package/dist/shortcuts/okr/errors.js +70 -0
- package/dist/shortcuts/okr/host.js +169 -0
- package/dist/shortcuts/okr/index.js +155 -0
- package/dist/shortcuts/okr/manifest.js +70 -0
- package/dist/shortcuts/okr/operations/link.js +305 -0
- package/dist/shortcuts/okr/operations/read.js +481 -0
- package/dist/shortcuts/okr/operations/registry.js +31 -0
- package/dist/shortcuts/okr/operations/shared.js +381 -0
- package/dist/shortcuts/okr/operations/types.js +88 -0
- package/dist/shortcuts/okr/operations/write.js +838 -0
- package/dist/shortcuts/okr/operations.js +8 -0
- package/dist/shortcuts/project/continuation.js +70 -0
- package/dist/shortcuts/project/errors.js +53 -0
- package/dist/shortcuts/project/host.js +160 -0
- package/dist/shortcuts/project/index.js +106 -0
- package/dist/shortcuts/project/manifest.js +36 -0
- package/dist/shortcuts/project/operations/read.js +551 -0
- package/dist/shortcuts/project/operations/registry.js +31 -0
- package/dist/shortcuts/project/operations/shared.js +68 -0
- package/dist/shortcuts/project/operations/types.js +39 -0
- package/dist/shortcuts/project/operations/write.js +266 -0
- package/dist/shortcuts/project/operations.js +8 -0
- package/dist/shortcuts/workflow/continuation.js +508 -0
- package/dist/shortcuts/workflow/endpoints.js +149 -0
- package/dist/shortcuts/workflow/errors.js +112 -0
- package/dist/shortcuts/workflow/host.js +224 -0
- package/dist/shortcuts/workflow/index.js +116 -0
- package/dist/shortcuts/workflow/manifest.js +30 -0
- package/dist/shortcuts/workflow/operations/form.js +4159 -0
- package/dist/shortcuts/workflow/operations/read.js +3778 -0
- package/dist/shortcuts/workflow/operations/registry.js +33 -0
- package/dist/shortcuts/workflow/operations/shared.js +167 -0
- package/dist/shortcuts/workflow/operations/types.js +44 -0
- package/dist/shortcuts/workflow/operations/write.js +1991 -0
- package/dist/shortcuts/workflow/operations.js +119 -0
- package/dist/shortcuts/workflow/state.js +182 -0
- package/docs/SKILL.md +5 -3
- package/docs/_catalog.md +10 -1
- package/docs/agent-invoice.md +2 -2
- package/docs/agent-skill-install.md +2 -2
- package/docs/e10-auth.md +3 -1
- package/docs/ebuilder-form.md +38 -0
- package/docs/im.md +104 -0
- package/docs/invoice.md +5 -5
- package/docs/okr.md +122 -0
- package/docs/operation-manual.md +10 -7
- package/docs/project.md +69 -0
- package/docs/skill-review-2026-09-19.md +68 -0
- package/package.json +3 -2
- package/scripts/package-skill.mjs +38 -11
- package/scripts/sync-connector-skills.mjs +172 -0
- package/skill-template/business-info.json +357 -16
- package/skill-template/domains/ebuilder-form.md +5 -0
- package/skill-template/domains/okr.md +18 -0
- package/skill-template/domains/shijingran.md +3 -0
- package/skill-template/domains/skill-maker.md +4 -4
- package/skill-template/domains/workflow.md +22 -0
- package/skill-template/domains/yepiaotong.md +4 -2
- package/skill-template/domains/yimiaoban.md +13 -10
- package/skill-template/product.json +5 -0
- package/skill-template/skill-template.md +1 -0
- package/skills/weaver-e10-calendar/SKILL.md +5 -1
- package/skills/weaver-e10-calendar/references/calendar-query.md +7 -0
- package/skills/weaver-e10-calendar/references/source-manifest.json +314 -32
- package/skills/weaver-e10-ebuilder-form/SKILL.md +123 -0
- package/skills/weaver-e10-ebuilder-form/references/context-routing.md +90 -0
- package/skills/weaver-e10-ebuilder-form/references/custom-api.md +86 -0
- package/skills/weaver-e10-ebuilder-form/references/disabled-capabilities.md +50 -0
- package/skills/weaver-e10-ebuilder-form/references/fields-browser.md +100 -0
- package/skills/weaver-e10-ebuilder-form/references/list-nlist.md +91 -0
- package/skills/weaver-e10-ebuilder-form/references/openapi-read.md +74 -0
- package/skills/weaver-e10-ebuilder-form/references/openapi-write.md +86 -0
- package/skills/weaver-e10-ebuilder-form/references/source-manifest.json +107 -0
- package/skills/weaver-e10-esb/SKILL.md +1 -1
- package/skills/weaver-e10-esb/references/source-manifest.json +15 -14
- package/skills/weaver-e10-hrm/SKILL.md +1 -1
- package/skills/weaver-e10-hrm/references/source-manifest.json +357 -38
- package/skills/weaver-e10-jiuchuanhui/SKILL.md +22 -4
- package/skills/weaver-e10-jiuchuanhui/references/clue.md +4 -2
- package/skills/weaver-e10-jiuchuanhui/references/contact.md +1 -1
- package/skills/weaver-e10-jiuchuanhui/references/customer.md +3 -3
- package/skills/weaver-e10-jiuchuanhui/references/disabled-capabilities.md +1 -1
- package/skills/weaver-e10-jiuchuanhui/references/discovery-config.md +10 -10
- package/skills/weaver-e10-jiuchuanhui/references/general-helpers.md +3 -3
- package/skills/weaver-e10-jiuchuanhui/references/sale.md +7 -7
- package/skills/weaver-e10-jiuchuanhui/references/source-manifest.json +3 -3
- package/skills/weaver-e10-jucailin/SKILL.md +2 -2
- package/skills/weaver-e10-mail/SKILL.md +22 -6
- package/skills/weaver-e10-meeting/SKILL.md +22 -1
- package/skills/weaver-e10-okr/SKILL.md +139 -0
- package/skills/weaver-e10-okr/references/okr-align.md +59 -0
- package/skills/weaver-e10-okr/references/okr-keyresult.md +68 -0
- package/skills/weaver-e10-okr/references/okr-link-routing.md +67 -0
- package/skills/weaver-e10-okr/references/okr-query.md +105 -0
- package/skills/weaver-e10-okr/references/okr-write.md +94 -0
- package/skills/weaver-e10-okr/references/source-manifest.json +672 -0
- package/skills/weaver-e10-plan/SKILL.md +3 -3
- package/skills/weaver-e10-plan/references/plan-report-write.md +1 -1
- package/skills/weaver-e10-plan/references/source-manifest.json +20 -20
- package/skills/weaver-e10-qiyecheng/SKILL.md +21 -1
- package/skills/weaver-e10-qiyecheng/references/source-manifest.json +17 -17
- package/skills/weaver-e10-shared/SKILL.md +79 -11
- package/skills/weaver-e10-shared/references/e10-auth-and-session.md +41 -8
- package/skills/weaver-e10-shared/references/non-interactive-environment.md +78 -0
- package/skills/weaver-e10-shared/references/weaver-e10-installation.md +39 -0
- package/skills/weaver-e10-shijingran/SKILL.md +83 -0
- package/skills/weaver-e10-shijingran/references/field-resolution.md +105 -0
- package/skills/weaver-e10-shijingran/references/operations.md +154 -0
- package/skills/weaver-e10-shijingran/references/source-manifest.json +1380 -0
- package/skills/weaver-e10-shijingran/references/write-operations.md +90 -0
- package/skills/weaver-e10-skill-maker/SKILL.md +26 -9
- package/skills/weaver-e10-skill-maker/references/business-skill-generation.md +39 -8
- package/skills/weaver-e10-skill-maker/references/detector-validation.md +25 -8
- package/skills/weaver-e10-skill-maker/references/module-cli-generation.md +66 -5
- package/skills/weaver-e10-skill-maker/references/module-gap-audit-and-repair.md +86 -0
- package/skills/weaver-e10-skill-maker/references/source-update-detection.md +59 -5
- package/skills/weaver-e10-skill-maker/references/weaver-skill-style.md +16 -8
- package/skills/weaver-e10-wenshuding/SKILL.md +28 -4
- package/skills/weaver-e10-wenshuding/references/archive-search.md +14 -0
- package/skills/weaver-e10-wenshuding/references/source-manifest.json +27 -26
- package/skills/weaver-e10-workflow/SKILL.md +250 -0
- package/skills/weaver-e10-workflow/references/source-manifest.json +1062 -0
- package/skills/weaver-e10-workflow/references/workflow-agent-entry.md +96 -0
- package/skills/weaver-e10-workflow/references/workflow-batch.md +275 -0
- package/skills/weaver-e10-workflow/references/workflow-create.md +182 -0
- package/skills/weaver-e10-workflow/references/workflow-edit.md +106 -0
- package/skills/weaver-e10-workflow/references/workflow-memory.md +165 -0
- package/skills/weaver-e10-workflow/references/workflow-operate.md +153 -0
- package/skills/weaver-e10-workflow/references/workflow-query.md +821 -0
- package/skills/weaver-e10-workflow/references/workflow-share.md +117 -0
- package/skills/weaver-e10-workflow/references/workflow-view.md +189 -0
- package/skills/weaver-e10-yepiaotong/SKILL.md +28 -28
- package/skills/weaver-e10-yepiaotong/references/invoice-disabled-capabilities.md +11 -5
- package/skills/weaver-e10-yepiaotong/references/invoice-import.md +14 -8
- package/skills/weaver-e10-yepiaotong/references/invoice-issuing-examples.md +9 -43
- package/skills/weaver-e10-yepiaotong/references/invoice-issuing.md +8 -0
- package/skills/weaver-e10-yepiaotong/references/invoice-reim.md +13 -17
- package/skills/weaver-e10-yepiaotong/references/reim-api-reference.md +6 -7
- package/skills/weaver-e10-yepiaotong/references/reim-examples.md +2 -2
- package/skills/weaver-e10-yepiaotong/references/source-manifest.json +1155 -553
- package/skills/weaver-e10-yimiaoban/SKILL.md +56 -38
- package/skills/weaver-e10-yimiaoban/references/ding-write.md +8 -8
- package/skills/weaver-e10-yimiaoban/references/error-codes.md +16 -0
- package/skills/weaver-e10-yimiaoban/references/field-resolution.md +10 -10
- package/skills/weaver-e10-yimiaoban/references/file-user-i18n.md +12 -12
- package/skills/weaver-e10-yimiaoban/references/group-read.md +16 -16
- package/skills/weaver-e10-yimiaoban/references/group-write.md +17 -15
- package/skills/weaver-e10-yimiaoban/references/msg-read.md +21 -17
- package/skills/weaver-e10-yimiaoban/references/msg-write.md +10 -10
- package/skills/weaver-e10-yimiaoban/references/person.md +6 -6
- package/skills/weaver-e10-yimiaoban/references/safety-boundaries.md +15 -11
- package/skills/weaver-e10-yimiaoban/references/session-sysmsg.md +11 -10
- package/skills/weaver-e10-yimiaoban/references/source-manifest.json +2164 -154
- package/skills/weaver-e10-yimiaoban/references/user-remind.md +75 -0
- package/skills/weaver-e10-ziguanjia/SKILL.md +4 -2
- package/skills/weaver-e10-ziguanjia/references/source-manifest.json +99 -29
- package/tools/weaver-skill-detector-1.0.13/SKILL.md +253 -0
- package/tools/weaver-skill-detector-1.0.13/_meta.json +6 -0
- package/tools/weaver-skill-detector-1.0.13/references/checklist.md +298 -0
- package/tools/weaver-skill-detector-1.0.13/scripts/validate_skill.py +4190 -0
- package/dist/shortcuts/yimiaoban/operations/shared.js +0 -236
- package/docs/yimiaoban.md +0 -86
- package/skills/weaver-e10-calendar/product.json +0 -8
- package/skills/weaver-e10-esb/product.json +0 -8
- package/skills/weaver-e10-hrm/product.json +0 -8
- package/skills/weaver-e10-jiuchuanhui/product.json +0 -8
- package/skills/weaver-e10-jucailin/product.json +0 -8
- package/skills/weaver-e10-mail/product.json +0 -8
- package/skills/weaver-e10-meeting/product.json +0 -8
- package/skills/weaver-e10-plan/product.json +0 -8
- package/skills/weaver-e10-qiyecheng/product.json +0 -8
- package/skills/weaver-e10-skill-maker/product.json +0 -8
- package/skills/weaver-e10-wenshuding/product.json +0 -8
- package/skills/weaver-e10-yepiaotong/product.json +0 -8
- package/skills/weaver-e10-yepiaotong/references/invoice-red.md +0 -261
- package/skills/weaver-e10-yimiaoban/product.json +0 -8
- package/skills/weaver-e10-ziguanjia/product.json +0 -8
- /package/dist/shortcuts/{yimiaoban → im}/operations/msg-parse.js +0 -0
|
@@ -1,40 +1,47 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { READ, schemaOf,
|
|
3
|
-
import { assertImOk, compact, formatFullTime, makeMinMaxIdByTm,
|
|
1
|
+
import { imValidationError } from '../errors.js';
|
|
2
|
+
import { READ, schemaOf, imSuccess, } from './types.js';
|
|
3
|
+
import { assertImOk, clampTimeRangeTo7Days, compact, DEFAULT_PAGE_SIZE, formatFullTime, makeMinMaxIdByTm, paginationMeta, parseMsg, parseTimeToSec, pullPaged, rangeShrinkMeta, resolveAuthUid, sortMessagesNewestFirst, str, todayRange, unwrapInner, } from './shared.js';
|
|
4
4
|
import { collapseNewlines, collectI18nIds, collectPersonIds, extractFiles, extractImgs, extractVideos, parseContent, senderName, } from './msg-parse.js';
|
|
5
5
|
const MAX_MSG_ID = String((1n << 63n) - 1n);
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
6
|
+
/**
|
|
7
|
+
* 时间/最新/显式 id 计算 start/end(与源 skill 一致):
|
|
8
|
+
* 1) 显式 start/end(群聊为 startId/endId)最高优先;
|
|
9
|
+
* 2) `latest:true` → 不限日期(无界区间,只拉一页);
|
|
10
|
+
* 3) `from`/`to` 时间范围 → 时间转消息 id 区间,跨度 > 7 天自动收敛为最后 7 个自然日;
|
|
11
|
+
* 4) 缺省 → 当天(有界区间,自动循环翻页拉完)。
|
|
12
|
+
*/
|
|
13
|
+
function resolveRange(args, idKeys = { start: 'start', end: 'end' }) {
|
|
14
|
+
const explicitStart = args[idKeys.start];
|
|
15
|
+
const explicitEnd = args[idKeys.end];
|
|
16
|
+
if (explicitStart !== undefined && explicitStart !== null && explicitStart !== '') {
|
|
17
|
+
return {
|
|
18
|
+
start: String(explicitStart),
|
|
19
|
+
end: explicitEnd !== undefined && explicitEnd !== null && explicitEnd !== '' ? String(explicitEnd) : '0',
|
|
20
|
+
scope: 'explicit-id',
|
|
21
|
+
shrink: null,
|
|
22
|
+
};
|
|
15
23
|
}
|
|
16
24
|
if (args.latest === true) {
|
|
17
|
-
return { start: MAX_MSG_ID, end: '0' };
|
|
25
|
+
return { start: MAX_MSG_ID, end: '0', scope: 'latest', shrink: null };
|
|
18
26
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
return { start: MAX_MSG_ID, end: '0' };
|
|
27
|
+
const hasFrom = args.from !== undefined && args.from !== null && args.from !== '';
|
|
28
|
+
const hasTo = args.to !== undefined && args.to !== null && args.to !== '';
|
|
29
|
+
if (hasFrom || hasTo) {
|
|
30
|
+
const clamp = clampTimeRangeTo7Days(parseTimeToSec(args.from, false), parseTimeToSec(args.to, true));
|
|
31
|
+
return {
|
|
32
|
+
start: clamp.toSec > 0 ? makeMinMaxIdByTm(clamp.toSec).max : MAX_MSG_ID,
|
|
33
|
+
end: clamp.fromSec > 0 ? makeMinMaxIdByTm(clamp.fromSec).min : '0',
|
|
34
|
+
scope: 'range',
|
|
35
|
+
shrink: clamp.shrunk ? clamp : null,
|
|
36
|
+
};
|
|
30
37
|
}
|
|
31
|
-
// 3) 默认当天
|
|
32
38
|
const range = todayRange();
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
39
|
+
return {
|
|
40
|
+
start: makeMinMaxIdByTm(range.toSec).max,
|
|
41
|
+
end: makeMinMaxIdByTm(range.fromSec).min,
|
|
42
|
+
scope: 'today',
|
|
43
|
+
shrink: null,
|
|
44
|
+
};
|
|
38
45
|
}
|
|
39
46
|
function pageSizeOf(args) {
|
|
40
47
|
const raw = args.num;
|
|
@@ -42,8 +49,8 @@ function pageSizeOf(args) {
|
|
|
42
49
|
return DEFAULT_PAGE_SIZE;
|
|
43
50
|
const n = Number(raw);
|
|
44
51
|
if (!Number.isInteger(n) || n <= 0)
|
|
45
|
-
throw
|
|
46
|
-
return Math.min(n,
|
|
52
|
+
throw imValidationError('num_invalid', 'num 必须是正整数');
|
|
53
|
+
return Math.min(n, 50);
|
|
47
54
|
}
|
|
48
55
|
/** `actionMsg.code=1303`(无聊天记录)时按成功空列表返回,并说明本次口径。 */
|
|
49
56
|
function emptyPageNote(args) {
|
|
@@ -54,17 +61,6 @@ function emptyPageNote(args) {
|
|
|
54
61
|
return '该时间范围内无消息记录';
|
|
55
62
|
return '当天无消息(如需最新消息请传 latest:true,或指定 from/to 时间范围)';
|
|
56
63
|
}
|
|
57
|
-
/** 单页返回公共字段:`hasMore` + 下一页锚点 + 去重提示。 */
|
|
58
|
-
function pageMeta(messages, args) {
|
|
59
|
-
const hasMore = messages.length >= pageSizeOf(args);
|
|
60
|
-
const nextStart = minMsgId(messages);
|
|
61
|
-
return {
|
|
62
|
-
hasMore,
|
|
63
|
-
...(hasMore && nextStart
|
|
64
|
-
? { nextStart, dedupeHint: '下一页 start 传 nextStart;服务端会重复返回该条(边界消息),请按 msgid 去重' }
|
|
65
|
-
: {}),
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
64
|
/** 富化消息列表:并行取 i18n + 人员姓名,逐条解析 content/sender/media。 */
|
|
69
65
|
async function enrichMessages(rawRows, host, options = {}) {
|
|
70
66
|
const rows = rawRows.filter(Boolean);
|
|
@@ -173,22 +169,22 @@ async function enrichMessages(rawRows, host, options = {}) {
|
|
|
173
169
|
}
|
|
174
170
|
return enriched;
|
|
175
171
|
}
|
|
176
|
-
/**
|
|
172
|
+
/** 拉单聊消息(默认当天;有界区间自动循环翻页拉完)。 */
|
|
177
173
|
const msgSyncSingle = {
|
|
178
|
-
name: '
|
|
174
|
+
name: 'im.msg.sync.single',
|
|
179
175
|
resource: 'msg',
|
|
180
176
|
method: 'msg.sync.single',
|
|
181
|
-
action: '
|
|
182
|
-
summary: '
|
|
177
|
+
action: 'im.msg.sync.single',
|
|
178
|
+
summary: '拉取与某人的单聊消息(倒序,默认当天;时间范围转消息 id 区间并自动翻页拉完)',
|
|
183
179
|
capability: 'msg',
|
|
184
180
|
risk: READ,
|
|
185
181
|
inputSchema: schemaOf({
|
|
186
182
|
fromUid: { type: 'string', pattern: '^\\d+$', description: '对方 uid(必填)' },
|
|
187
183
|
fromCid: { type: 'string', pattern: '^\\d+$', description: '对方 cid(必填)' },
|
|
188
|
-
num: { type: 'integer', minimum: 1, maximum: 50, description: '
|
|
189
|
-
latest: { type: 'boolean', description: '
|
|
190
|
-
from: { type: 'string', description: '起始时间(YYYY-MM-DD 或 YYYY-MM-DD HH:mm:ss 或 unix
|
|
191
|
-
to: { type: 'string', description: '
|
|
184
|
+
num: { type: 'integer', minimum: 1, maximum: 50, description: '每页数量(默认 50,最多 50)' },
|
|
185
|
+
latest: { type: 'boolean', description: '拉最新不限日期(无界区间,只拉一页)' },
|
|
186
|
+
from: { type: 'string', description: '起始时间(YYYY-MM-DD 或 YYYY-MM-DD HH:mm:ss 或 unix 秒);跨度 > 7 天自动收敛为该范围最后 7 天' },
|
|
187
|
+
to: { type: 'string', description: '结束时间(同上)' },
|
|
192
188
|
start: { type: 'string', description: '显式起始消息 id(最高优先)' },
|
|
193
189
|
end: { type: 'string', description: '显式结束消息 id' },
|
|
194
190
|
imgFormat: { type: 'string', enum: ['small', 'large', 'original'], description: '预览规格(默认 small)' },
|
|
@@ -197,63 +193,79 @@ const msgSyncSingle = {
|
|
|
197
193
|
const fromUid = String(args.fromUid);
|
|
198
194
|
const fromCid = String(args.fromCid);
|
|
199
195
|
if (!fromUid || !fromCid || fromUid === '0' || fromCid === '0') {
|
|
200
|
-
throw
|
|
196
|
+
throw imValidationError('id_invalid', 'fromUid/fromCid 必须非 0');
|
|
201
197
|
}
|
|
202
|
-
const { start, end } =
|
|
203
|
-
const
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
198
|
+
const { start, end, scope, shrink } = resolveRange(args);
|
|
199
|
+
const num = pageSizeOf(args);
|
|
200
|
+
// 有界区间(end != 0:时间范围/默认当天/显式 end)自动循环翻页拉完;无界区间(latest)只拉一页
|
|
201
|
+
const autoLoop = end !== '0';
|
|
202
|
+
let actCode = 0;
|
|
203
|
+
const pulled = await pullPaged({
|
|
204
|
+
num,
|
|
205
|
+
start,
|
|
206
|
+
end,
|
|
207
|
+
autoLoop,
|
|
208
|
+
requestOnePage: async (pageStart, pageEnd, maxNum) => {
|
|
209
|
+
const body = {
|
|
210
|
+
trans_id: 0,
|
|
211
|
+
dev: 4,
|
|
212
|
+
enc_type: 0,
|
|
213
|
+
datas: [{ from_cid: fromCid, from_uid: fromUid, start: pageStart, end: pageEnd, max_num: maxNum }],
|
|
214
|
+
};
|
|
215
|
+
const res = await host.request({
|
|
216
|
+
method: 'POST',
|
|
217
|
+
path: '/api/em/msg/executeIm/msg/syncSingleMsg',
|
|
218
|
+
body,
|
|
219
|
+
operation: 'im.msg.sync.single',
|
|
220
|
+
});
|
|
221
|
+
// 1303=无聊天记录:按成功空列表返回(与群聊口径一致),并说明本次口径
|
|
222
|
+
actCode = Number(res?.data?.actionMsg?.code ?? -1);
|
|
223
|
+
if (actCode === 1303)
|
|
224
|
+
return [];
|
|
225
|
+
assertImOk(res, '拉取单聊消息');
|
|
226
|
+
const inner = unwrapInner(res);
|
|
227
|
+
const outerDatas = inner?.datas || [];
|
|
228
|
+
const rows = [];
|
|
229
|
+
for (const group of outerDatas) {
|
|
230
|
+
const list = group?.datas || group?.data || [];
|
|
231
|
+
if (Array.isArray(list))
|
|
232
|
+
rows.push(...list);
|
|
233
|
+
}
|
|
234
|
+
return rows;
|
|
235
|
+
},
|
|
214
236
|
});
|
|
215
|
-
const inner = unwrapInner(res);
|
|
216
|
-
const outerDatas = inner?.datas || [];
|
|
217
|
-
const rawRows = [];
|
|
218
|
-
for (const group of outerDatas) {
|
|
219
|
-
const list = group?.datas || group?.data || [];
|
|
220
|
-
if (Array.isArray(list))
|
|
221
|
-
rawRows.push(...list);
|
|
222
|
-
}
|
|
223
|
-
// 1303=无聊天记录:按成功空列表返回(与群聊口径一致),并说明本次口径
|
|
224
|
-
const actCode = Number(res?.data?.actionMsg?.code ?? -1);
|
|
225
|
-
if (actCode !== 1303)
|
|
226
|
-
assertImOk(res, '拉取单聊消息');
|
|
227
237
|
const authUid = await resolveAuthUid(host);
|
|
228
|
-
const messages = await enrichMessages(
|
|
238
|
+
const messages = await enrichMessages(pulled.rows, host, {
|
|
229
239
|
authUid,
|
|
230
240
|
user: { cid: fromCid, uid: fromUid },
|
|
231
241
|
imgFormat: args.imgFormat,
|
|
232
242
|
});
|
|
233
|
-
|
|
243
|
+
sortMessagesNewestFirst(messages);
|
|
244
|
+
return imSuccess('im.msg.sync.single', {
|
|
234
245
|
total: messages.length,
|
|
235
246
|
messages,
|
|
236
|
-
range: { from: args.from, to: args.to, start, end },
|
|
237
|
-
...
|
|
247
|
+
range: { from: args.from, to: args.to, start, end, scope, autoPaged: autoLoop },
|
|
248
|
+
...paginationMeta(pulled, num),
|
|
249
|
+
...(shrink ? { rangeShrink: rangeShrinkMeta(shrink) } : {}),
|
|
238
250
|
...(actCode === 1303 ? { empty: true, emptyReason: emptyPageNote(args) } : {}),
|
|
239
251
|
});
|
|
240
252
|
},
|
|
241
253
|
};
|
|
242
254
|
/** 拉群聊消息。 */
|
|
243
255
|
const msgSyncGroup = {
|
|
244
|
-
name: '
|
|
256
|
+
name: 'im.msg.sync.group',
|
|
245
257
|
resource: 'msg',
|
|
246
258
|
method: 'msg.sync.group',
|
|
247
|
-
action: '
|
|
248
|
-
summary: '
|
|
259
|
+
action: 'im.msg.sync.group',
|
|
260
|
+
summary: '拉取某群聊天消息(倒序,默认当天;有界区间自动翻页拉完;type=0 必传)',
|
|
249
261
|
capability: 'msg',
|
|
250
262
|
risk: READ,
|
|
251
263
|
inputSchema: schemaOf({
|
|
252
264
|
groupId: { type: 'string', pattern: '^\\d+$', description: '群 id(必填)' },
|
|
253
|
-
num: { type: 'integer', minimum: 1, maximum: 50, description: '
|
|
254
|
-
latest: { type: 'boolean', description: '
|
|
255
|
-
from: { type: 'string', description: '
|
|
256
|
-
to: { type: 'string', description: '
|
|
265
|
+
num: { type: 'integer', minimum: 1, maximum: 50, description: '每页数量(默认 50,最多 50)' },
|
|
266
|
+
latest: { type: 'boolean', description: '拉最新不限日期(无界区间,只拉一页)' },
|
|
267
|
+
from: { type: 'string', description: '起始时间;跨度 > 7 天自动收敛为该范围最后 7 天' },
|
|
268
|
+
to: { type: 'string', description: '结束时间(同上)' },
|
|
257
269
|
startId: { type: 'string', description: '显式起始消息 id(最高优先)' },
|
|
258
270
|
endId: { type: 'string', description: '显式结束消息 id' },
|
|
259
271
|
imgFormat: { type: 'string', enum: ['small', 'large', 'original'], description: '预览规格(默认 small)' },
|
|
@@ -261,60 +273,70 @@ const msgSyncGroup = {
|
|
|
261
273
|
handler: async (args, { host }) => {
|
|
262
274
|
const groupId = String(args.groupId);
|
|
263
275
|
if (!groupId || groupId === '0')
|
|
264
|
-
throw
|
|
276
|
+
throw imValidationError('id_invalid', 'groupId 必须非 0');
|
|
265
277
|
// 群聊显式 id flag 名为 startId/endId
|
|
266
|
-
const start
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
278
|
+
const { start, end, scope, shrink } = resolveRange(args, { start: 'startId', end: 'endId' });
|
|
279
|
+
const num = pageSizeOf(args);
|
|
280
|
+
const autoLoop = end !== '0';
|
|
281
|
+
let actCode = 0;
|
|
282
|
+
const pulled = await pullPaged({
|
|
283
|
+
num,
|
|
284
|
+
start,
|
|
285
|
+
end,
|
|
286
|
+
autoLoop,
|
|
287
|
+
requestOnePage: async (pageStart, pageEnd, maxNum) => {
|
|
288
|
+
const body = {
|
|
289
|
+
trans_id: 0,
|
|
290
|
+
dev: 4,
|
|
291
|
+
type: 0,
|
|
292
|
+
enc_type: 0,
|
|
293
|
+
datas: [{ group_id: groupId, start: pageStart, end: pageEnd, max_num: maxNum }],
|
|
294
|
+
};
|
|
295
|
+
const res = await host.request({
|
|
296
|
+
method: 'POST',
|
|
297
|
+
path: '/api/em/msg/executeIm/chat/syncGroupMsg',
|
|
298
|
+
body,
|
|
299
|
+
operation: 'im.msg.sync.group',
|
|
300
|
+
});
|
|
301
|
+
actCode = Number(res?.data?.actionMsg?.code ?? -1);
|
|
302
|
+
if (actCode === 1303)
|
|
303
|
+
return [];
|
|
304
|
+
assertImOk(res, '拉取群聊消息');
|
|
305
|
+
const inner = unwrapInner(res);
|
|
306
|
+
const outerDatas = inner?.datas || [];
|
|
307
|
+
const rows = [];
|
|
308
|
+
for (const group of outerDatas) {
|
|
309
|
+
const list = group?.datas || group?.data || [];
|
|
310
|
+
if (Array.isArray(list))
|
|
311
|
+
rows.push(...list);
|
|
312
|
+
}
|
|
313
|
+
return rows;
|
|
314
|
+
},
|
|
284
315
|
});
|
|
285
|
-
const inner = unwrapInner(res);
|
|
286
|
-
const outerDatas = inner?.datas || [];
|
|
287
|
-
const rawRows = [];
|
|
288
|
-
for (const group of outerDatas) {
|
|
289
|
-
const list = group?.datas || group?.data || [];
|
|
290
|
-
if (Array.isArray(list))
|
|
291
|
-
rawRows.push(...list);
|
|
292
|
-
}
|
|
293
|
-
const actCode = Number(res?.data?.actionMsg?.code ?? -1);
|
|
294
|
-
if (actCode !== 1303)
|
|
295
|
-
assertImOk(res, '拉取群聊消息');
|
|
296
316
|
const authUid = await resolveAuthUid(host);
|
|
297
|
-
const messages = await enrichMessages(
|
|
317
|
+
const messages = await enrichMessages(pulled.rows, host, {
|
|
298
318
|
authUid,
|
|
299
319
|
groupId,
|
|
300
320
|
imgFormat: args.imgFormat,
|
|
301
321
|
});
|
|
302
|
-
|
|
322
|
+
sortMessagesNewestFirst(messages);
|
|
323
|
+
return imSuccess('im.msg.sync.group', {
|
|
303
324
|
groupId,
|
|
304
325
|
total: messages.length,
|
|
305
326
|
messages,
|
|
306
|
-
range: { from: args.from, to: args.to, start, end },
|
|
307
|
-
...
|
|
327
|
+
range: { from: args.from, to: args.to, start, end, scope, autoPaged: autoLoop },
|
|
328
|
+
...paginationMeta(pulled, num),
|
|
329
|
+
...(shrink ? { rangeShrink: rangeShrinkMeta(shrink) } : {}),
|
|
308
330
|
...(actCode === 1303 ? { empty: true, emptyReason: emptyPageNote(args) } : {}),
|
|
309
331
|
});
|
|
310
332
|
},
|
|
311
333
|
};
|
|
312
334
|
/** 群置顶消息同步。 */
|
|
313
335
|
const msgTopSync = {
|
|
314
|
-
name: '
|
|
336
|
+
name: 'im.msg.top.sync',
|
|
315
337
|
resource: 'msg',
|
|
316
338
|
method: 'msg.top.sync',
|
|
317
|
-
action: '
|
|
339
|
+
action: 'im.msg.top.sync',
|
|
318
340
|
summary: '同步群置顶消息(摘要 + 消息内容)',
|
|
319
341
|
capability: 'msg',
|
|
320
342
|
risk: READ,
|
|
@@ -322,11 +344,12 @@ const msgTopSync = {
|
|
|
322
344
|
groupId: { type: 'string', pattern: '^\\d+$', description: '群 id(必填)' },
|
|
323
345
|
msgids: { type: 'array', items: { type: 'string' }, description: '仅同步指定消息 id(缺省=全部置顶)' },
|
|
324
346
|
encType: { type: 'integer', enum: [0, 1, 2, 3], description: '加密类型(默认 0,不解密)' },
|
|
347
|
+
imgFormat: { type: 'string', enum: ['small', 'large', 'original'], description: '置顶消息内图片的预览规格(默认 small)' },
|
|
325
348
|
}, { required: ['groupId'], description: '同步群置顶消息' }),
|
|
326
349
|
handler: async (args, { host }) => {
|
|
327
350
|
const groupId = String(args.groupId);
|
|
328
351
|
if (!groupId || groupId === '0')
|
|
329
|
-
throw
|
|
352
|
+
throw imValidationError('id_invalid', 'groupId 必须非 0');
|
|
330
353
|
const body = compact({
|
|
331
354
|
group_id: groupId,
|
|
332
355
|
enc_type: Number(args.encType ?? 0),
|
|
@@ -336,7 +359,7 @@ const msgTopSync = {
|
|
|
336
359
|
method: 'POST',
|
|
337
360
|
path: '/api/em/msg/executeIm/msg/syncGroupTopMsg',
|
|
338
361
|
body,
|
|
339
|
-
operation: '
|
|
362
|
+
operation: 'im.msg.top.sync',
|
|
340
363
|
});
|
|
341
364
|
assertImOk(res, '同步置顶消息');
|
|
342
365
|
const inner = unwrapInner(res);
|
|
@@ -356,7 +379,7 @@ const msgTopSync = {
|
|
|
356
379
|
imgFormat: args.imgFormat,
|
|
357
380
|
authUid: await resolveAuthUid(host),
|
|
358
381
|
});
|
|
359
|
-
return
|
|
382
|
+
return imSuccess('im.msg.top.sync', {
|
|
360
383
|
groupId,
|
|
361
384
|
total: summary.length,
|
|
362
385
|
infos: summary,
|
|
@@ -366,10 +389,10 @@ const msgTopSync = {
|
|
|
366
389
|
};
|
|
367
390
|
/** 单聊已读状态。 */
|
|
368
391
|
const msgReadSingle = {
|
|
369
|
-
name: '
|
|
392
|
+
name: 'im.msg.read.single',
|
|
370
393
|
resource: 'msg',
|
|
371
394
|
method: 'msg.read.single',
|
|
372
|
-
action: '
|
|
395
|
+
action: 'im.msg.read.single',
|
|
373
396
|
summary: '查询单聊消息阅读状态(msgids=自己发出 / recvMsgids=自己接收)',
|
|
374
397
|
capability: 'msg',
|
|
375
398
|
risk: READ,
|
|
@@ -383,7 +406,7 @@ const msgReadSingle = {
|
|
|
383
406
|
const hasSent = Array.isArray(args.msgids) && args.msgids.length > 0;
|
|
384
407
|
const hasRecv = Array.isArray(args.recvMsgids) && args.recvMsgids.length > 0;
|
|
385
408
|
if (!hasSent && !hasRecv)
|
|
386
|
-
throw
|
|
409
|
+
throw imValidationError('msgids_required', 'msgids / recvMsgids 至少其一');
|
|
387
410
|
const body = compact({
|
|
388
411
|
data: {
|
|
389
412
|
trans_id: 0,
|
|
@@ -396,7 +419,7 @@ const msgReadSingle = {
|
|
|
396
419
|
method: 'POST',
|
|
397
420
|
path: '/api/em/msg/executeIm/msg/getSingleMsgReadStatus',
|
|
398
421
|
body,
|
|
399
|
-
operation: '
|
|
422
|
+
operation: 'im.msg.read.single',
|
|
400
423
|
});
|
|
401
424
|
assertImOk(res, '查询单聊阅读状态');
|
|
402
425
|
const inner = unwrapInner(res);
|
|
@@ -410,15 +433,15 @@ const msgReadSingle = {
|
|
|
410
433
|
dev: d.dev,
|
|
411
434
|
}))
|
|
412
435
|
: [];
|
|
413
|
-
return
|
|
436
|
+
return imSuccess('im.msg.read.single', { total: rows.length, items: rows });
|
|
414
437
|
},
|
|
415
438
|
};
|
|
416
439
|
/** 群消息已读状态(未读数)。 */
|
|
417
440
|
const msgReadGroup = {
|
|
418
|
-
name: '
|
|
441
|
+
name: 'im.msg.read.group',
|
|
419
442
|
resource: 'msg',
|
|
420
443
|
method: 'msg.read.group',
|
|
421
|
-
action: '
|
|
444
|
+
action: 'im.msg.read.group',
|
|
422
445
|
summary: '查询群消息阅读状态汇总(每条消息已读/未读情况,原样输出)',
|
|
423
446
|
capability: 'msg',
|
|
424
447
|
risk: READ,
|
|
@@ -431,7 +454,7 @@ const msgReadGroup = {
|
|
|
431
454
|
const hasSent = Array.isArray(args.msgids) && args.msgids.length > 0;
|
|
432
455
|
const hasRecv = Array.isArray(args.recvMsgids) && args.recvMsgids.length > 0;
|
|
433
456
|
if (!hasSent && !hasRecv)
|
|
434
|
-
throw
|
|
457
|
+
throw imValidationError('msgids_required', 'msgids / recvMsgids 至少其一');
|
|
435
458
|
const body = compact({
|
|
436
459
|
trans_id: 0,
|
|
437
460
|
group_id: String(args.groupId),
|
|
@@ -442,11 +465,11 @@ const msgReadGroup = {
|
|
|
442
465
|
method: 'POST',
|
|
443
466
|
path: '/api/em/msg/executeIm/msg/getGroupMsgReadStatus',
|
|
444
467
|
body,
|
|
445
|
-
operation: '
|
|
468
|
+
operation: 'im.msg.read.group',
|
|
446
469
|
});
|
|
447
470
|
assertImOk(res, '查询群阅读状态');
|
|
448
471
|
const inner = unwrapInner(res);
|
|
449
|
-
return
|
|
472
|
+
return imSuccess('im.msg.read.group', {
|
|
450
473
|
groupId: String(args.groupId),
|
|
451
474
|
raw: Array.isArray(inner) ? inner : inner,
|
|
452
475
|
});
|
|
@@ -454,10 +477,10 @@ const msgReadGroup = {
|
|
|
454
477
|
};
|
|
455
478
|
/** 群消息阅读状态详情(谁已读/未读)。 */
|
|
456
479
|
const msgReadGroupDetail = {
|
|
457
|
-
name: '
|
|
480
|
+
name: 'im.msg.read.group.detail',
|
|
458
481
|
resource: 'msg',
|
|
459
482
|
method: 'msg.read.group.detail',
|
|
460
|
-
action: '
|
|
483
|
+
action: 'im.msg.read.group.detail',
|
|
461
484
|
summary: '群消息阅读详情(unread/read count + 每人状态),支持分页',
|
|
462
485
|
capability: 'msg',
|
|
463
486
|
risk: READ,
|
|
@@ -481,7 +504,7 @@ const msgReadGroupDetail = {
|
|
|
481
504
|
method: 'POST',
|
|
482
505
|
path: '/api/em/msg/executeIm/group/syncGroupReadStatus',
|
|
483
506
|
body,
|
|
484
|
-
operation: '
|
|
507
|
+
operation: 'im.msg.read.group.detail',
|
|
485
508
|
});
|
|
486
509
|
assertImOk(res, '同步群阅读详情');
|
|
487
510
|
const inner = unwrapInner(res);
|
|
@@ -496,7 +519,7 @@ const msgReadGroupDetail = {
|
|
|
496
519
|
dev: d.dev,
|
|
497
520
|
time: formatFullTime(d.time),
|
|
498
521
|
}));
|
|
499
|
-
return
|
|
522
|
+
return imSuccess('im.msg.read.group.detail', {
|
|
500
523
|
groupId: String(args.groupId),
|
|
501
524
|
msgid: String(args.msgid),
|
|
502
525
|
unreadCount: inner?.unread_count,
|
|
@@ -516,4 +539,4 @@ export const msgReadOperations = [
|
|
|
516
539
|
msgReadGroup,
|
|
517
540
|
msgReadGroupDetail,
|
|
518
541
|
];
|
|
519
|
-
export { enrichMessages,
|
|
542
|
+
export { enrichMessages, resolveRange };
|