@zhin.js/plugin-group-suite 1.1.6 → 1.1.8
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 +55 -24
- package/commands/forget/index.js +1 -0
- package/commands/forget/index.ts +1 -0
- package/commands/keyword-add/[keyword]/index.js +10 -7
- package/commands/keyword-add/[keyword]/index.ts +11 -8
- package/commands/keyword-list/index.js +8 -5
- package/commands/keyword-list/index.ts +9 -6
- package/commands/keyword-remove/[keyword]/index.js +10 -6
- package/commands/keyword-remove/[keyword]/index.ts +11 -7
- package/commands/stats-card/index.js +23 -0
- package/commands/stats-card/index.ts +24 -0
- package/commands/teach/index.js +1 -0
- package/commands/teach/index.ts +1 -0
- package/commands/teach-regex/index.js +1 -0
- package/commands/teach-regex/index.ts +1 -0
- package/handlers/welcome/index.js +25 -0
- package/handlers/welcome/index.ts +24 -0
- package/lib/checkin-lib.d.ts +4 -24
- package/lib/checkin-lib.d.ts.map +1 -1
- package/lib/checkin-lib.js +3 -4
- package/lib/checkin-lib.js.map +1 -1
- package/lib/config.d.ts +4 -0
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js +2 -0
- package/lib/config.js.map +1 -1
- package/lib/conversation-scope.d.ts +21 -0
- package/lib/conversation-scope.d.ts.map +1 -0
- package/lib/conversation-scope.js +33 -0
- package/lib/conversation-scope.js.map +1 -0
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/keyword-store.d.ts +4 -0
- package/lib/keyword-store.d.ts.map +1 -1
- package/lib/keyword-store.js +15 -0
- package/lib/keyword-store.js.map +1 -1
- package/lib/runtime-state.d.ts +5 -1
- package/lib/runtime-state.d.ts.map +1 -1
- package/lib/runtime-state.js.map +1 -1
- package/lib/shared-runtime.d.ts +3 -8
- package/lib/shared-runtime.d.ts.map +1 -1
- package/lib/shared-runtime.js +4 -10
- package/lib/shared-runtime.js.map +1 -1
- package/lib/stats-lib.d.ts +5 -26
- package/lib/stats-lib.d.ts.map +1 -1
- package/lib/stats-lib.js +29 -15
- package/lib/stats-lib.js.map +1 -1
- package/lib/teach-lib.d.ts +2 -9
- package/lib/teach-lib.d.ts.map +1 -1
- package/lib/teach-lib.js +6 -8
- package/lib/teach-lib.js.map +1 -1
- package/middlewares/keyword-reply/index.js +3 -5
- package/middlewares/keyword-reply/index.ts +3 -5
- package/middlewares/stats-count/index.js +3 -7
- package/middlewares/stats-count/index.ts +3 -7
- package/package.json +29 -11
- package/plugin.js +9 -9
- package/schedules/flush-stats/index.js +11 -0
- package/schedules/flush-stats/index.ts +11 -0
- package/schema.json +51 -10
- package/skills/checkin/tools/checkin_query/index.js +5 -8
- package/skills/checkin/tools/checkin_query/index.ts +5 -9
- package/skills/checkin/tools/checkin_rank/index.js +4 -7
- package/skills/checkin/tools/checkin_rank/index.ts +4 -7
- package/skills/group-daily-analysis/tools/stats_query/index.js +3 -4
- package/skills/group-daily-analysis/tools/stats_query/index.ts +3 -4
- package/skills/group-daily-analysis/tools/stats_user/index.js +4 -5
- package/skills/group-daily-analysis/tools/stats_user/index.ts +4 -5
- package/src/checkin-lib.ts +7 -7
- package/src/config.ts +6 -0
- package/src/conversation-scope.ts +45 -0
- package/src/index.ts +1 -0
- package/src/keyword-store.ts +22 -0
- package/src/keywords.ts +72 -0
- package/src/runtime-state.ts +5 -1
- package/src/shared-runtime.ts +5 -14
- package/src/stats-lib.ts +36 -29
- package/src/teach-lib.ts +8 -17
package/README.md
CHANGED
|
@@ -1,29 +1,30 @@
|
|
|
1
1
|
# @zhin.js/plugin-group-suite
|
|
2
2
|
|
|
3
|
-
Plugin Runtime
|
|
4
|
-
|
|
3
|
+
Plugin Runtime 群运营套件,提供签到积分、消息统计、群问答、持久词库与群成员欢迎。
|
|
4
|
+
能力按统一的 commands、middlewares、handlers、schedules 和 skills 目录发现。
|
|
5
5
|
|
|
6
|
-
##
|
|
6
|
+
## 安装与配置
|
|
7
7
|
|
|
8
8
|
```bash
|
|
9
|
-
pnpm
|
|
9
|
+
pnpm exec zhin install @zhin.js/plugin-group-suite
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
安装会将实例挂在父插件的 `package.json#zhin.plugins`。手工挂载:
|
|
13
13
|
|
|
14
14
|
```json
|
|
15
|
-
{
|
|
16
|
-
"package": "@zhin.js/plugin-group-suite",
|
|
17
|
-
"instanceKey": "group-suite"
|
|
18
|
-
}
|
|
15
|
+
{ "package": "@zhin.js/plugin-group-suite", "instanceKey": "group-suite" }
|
|
19
16
|
```
|
|
20
17
|
|
|
21
|
-
|
|
18
|
+
应用 Host 必须共享同一物理实例的 `@zhin.js/command`、`@zhin.js/middleware`、
|
|
19
|
+
`@zhin.js/handler`、`@zhin.js/schedule-feature`、`@zhin.js/tool` 与 `@zhin.js/skill`
|
|
20
|
+
Feature provider,并装配 Schedule Host。正常 CLI 负责 Host 装配;手写测试 Host 也需要显式安装这些资源。
|
|
22
21
|
|
|
23
22
|
```yaml
|
|
24
23
|
plugins:
|
|
25
24
|
group-suite:
|
|
26
|
-
keywordReply:
|
|
25
|
+
keywordReply: true
|
|
26
|
+
ephemeralKeywords: false
|
|
27
|
+
welcomeMessage: "" # 默认关闭;可设为 欢迎 {name} ({id})
|
|
27
28
|
basePointsMin: 10
|
|
28
29
|
basePointsMax: 30
|
|
29
30
|
streakBonus: 5
|
|
@@ -35,26 +36,50 @@ plugins:
|
|
|
35
36
|
teachPageSize: 10
|
|
36
37
|
```
|
|
37
38
|
|
|
38
|
-
|
|
39
|
-
`
|
|
39
|
+
约束以 [schema.json](./schema.json) 为准。启用关键词回复时默认要求 Database Host 的原子
|
|
40
|
+
状态服务;没有该服务会启动失败并提示原因。演示环境可显式设置 `ephemeralKeywords: true`,
|
|
41
|
+
此时词库只活在当前插件实例,插件重载或进程重启后会丢失。
|
|
42
|
+
即使 `keywordReply: false`,词库管理仍要求持久状态服务(除非显式启用临时词库);默认无数据库
|
|
43
|
+
时这些命令会回复配置要求,不会返回伪造的空词库或宣称写入成功。
|
|
40
44
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
45
|
+
持久词库通过公开 `databaseHostToken.state.forConversation()` 存储,每次管理命令在原子
|
|
46
|
+
更新完成后才返回成功。一个群最多 200 条,关键词 1–200 字符,回复 1–2000 字符。
|
|
47
|
+
整个词库的 JSON 编码必须小于 64 KiB(UTF-8 字节,包含键、回复与 JSON 标点);条数上限与
|
|
48
|
+
字节上限同时约束,长回复可能先达到字节上限。更新超限会拒绝并保留旧词库,临时词库使用同样限制。
|
|
49
|
+
在同一数据库和相同实例身份下,指令热更新、插件重载和进程重启保留词库。
|
|
44
50
|
|
|
45
|
-
|
|
51
|
+
签到、教学和统计优先写入 Database Host;没有数据库时使用实例私有内存模型,不能视为持久存储。
|
|
52
|
+
统计只在入站累加内存缓冲,每 10 秒由正式 Schedule Host 批量写入;主动查询也会刷新缓冲。
|
|
53
|
+
它是 best-effort 计数,并非持久 outbox:停止、插件重载或崩溃时尚未落库的批次可能丢失。
|
|
54
|
+
退休 generation 的清理不额外写数据库,也不绕过代级准入。
|
|
46
55
|
|
|
47
|
-
|
|
56
|
+
## 使用与权限
|
|
57
|
+
|
|
58
|
+
未配置命名空间时直接使用表内指令名;如果实例设 `commandNamespace: suite`,使用
|
|
59
|
+
`suite checkin` 等形式。实际前缀由 Endpoint 决定。
|
|
60
|
+
|
|
61
|
+
| 指令/能力 | 说明 |
|
|
48
62
|
|---|---|
|
|
49
63
|
| `checkin` / `mypoints` / `rank` | 签到、积分与排行 |
|
|
50
64
|
| `stats` / `stats-week` / `stats-rank` / `mystats` | 消息统计 |
|
|
51
|
-
| `
|
|
52
|
-
| `
|
|
53
|
-
| `
|
|
54
|
-
| `
|
|
65
|
+
| `stats-card` | 当日统计 HTML 图卡;没有渲染服务时走统一文本降级 |
|
|
66
|
+
| `teach` / `teach-regex` / `teach-list` / `forget` | 群问答与管理 |
|
|
67
|
+
| `keyword-add <keyword> <reply...>` / `keyword-list` / `keyword-remove <keyword>` | 当前群词库 |
|
|
68
|
+
| `welcomeMessage` | 当前群增加成员时欢迎,默认关闭,只在设置非空文本后发送 |
|
|
69
|
+
| `skills/<name>/tools/<tool>/index.ts` | Skill 激活后披露签到查询、排行、统计和群公告 Tool |
|
|
70
|
+
|
|
71
|
+
关键词与问答修改命令要求群主、管理员、master 或 trusted;普通成员不能修改。查询命令仍按其
|
|
72
|
+
各自公开 permit 执行。Tool 保持既有审批策略,命令角色判断不能替代 Tool 审批或平台权限。
|
|
73
|
+
欢迎通过 `outboundMessageToken` 走统一发送链路,投递失败/未知会报错,不盲目重试。
|
|
74
|
+
`stats-card` 是 HTML 图片/文本展示,不是平台原生 `card` 载荷。
|
|
55
75
|
|
|
56
|
-
|
|
57
|
-
|
|
76
|
+
所有新数据按插件实例与完整会话隔离:平台、Endpoint 身份、群/频道/私聊类型与 ID,以及父会话、
|
|
77
|
+
线程信息共同参与键。相同群号的两个 Bot 不共享词库、签到、教学或统计。群专用 Tool 只接受 IM
|
|
78
|
+
群上下文,并通过当前 AdapterIndex 精确解析 Endpoint,无法确定唯一来源时拒绝执行。当前群的查询保留当前线程,只查该完整会话,不聚合其他线程。
|
|
79
|
+
显式查询另一群时使用该群根会话,不将当前群的线程 ID 带到另一群。
|
|
80
|
+
|
|
81
|
+
旧记录只有裸群号或全局范围,无法安全判断属于哪个 Bot。新实现不会自动读入或建立兼容别名;
|
|
82
|
+
需要保留旧记录时,维护者必须根据实际 Bot/会话身份进行明确的人工迁移。
|
|
58
83
|
|
|
59
84
|
## 验证
|
|
60
85
|
|
|
@@ -62,3 +87,9 @@ plugins:
|
|
|
62
87
|
pnpm --filter @zhin.js/plugin-group-suite build
|
|
63
88
|
pnpm --filter @zhin.js/plugin-group-suite test
|
|
64
89
|
```
|
|
90
|
+
|
|
91
|
+
集成验收使用公开 `@zhin.js/plugin-test-kit`、真实 Native Runtime/CommandIndex/PermissionHost、
|
|
92
|
+
合成端点、真实 PluginScheduleHost 和 SQLite 状态 CAS,覆盖两个实例、端点隔离、权限拒绝、
|
|
93
|
+
无数据库错误、热更新、配置失败回滚及新进程重启后的持久词库。HTML 渲染使用 stub,另测文本
|
|
94
|
+
降级;统计/签到/教学模型在此 fixture 为内存端口。它不代表真实平台登录、欢迎投递、截图质量或
|
|
95
|
+
生产数据库端到端验收;实机操作需要单独授权。
|
package/commands/forget/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import { defineCommand } from 'zhin.js/command';
|
|
|
3
3
|
import { teachForget } from "../../lib/teach-lib.js";
|
|
4
4
|
import { resolveGroupSuiteRuntime } from "../../lib/runtime-state.js";
|
|
5
5
|
export default defineCommand({
|
|
6
|
+
permit: ['group()', 'role(owner,admin,master,trusted)'],
|
|
6
7
|
description: '忘记问答(删除问答对)',
|
|
7
8
|
execute({ input, args, owner, use }) {
|
|
8
9
|
return teachForget(input ?? {}, args.join(' '), resolveGroupSuiteRuntime({ owner, use }));
|
package/commands/forget/index.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { teachForget } from '../../src/teach-lib.js';
|
|
|
5
5
|
import { resolveGroupSuiteRuntime } from '../../src/runtime-state.js';
|
|
6
6
|
|
|
7
7
|
export default defineCommand<GroupSuiteConfig, string, Message>({
|
|
8
|
+
permit: ['group()', 'role(owner,admin,master,trusted)'],
|
|
8
9
|
description: '忘记问答(删除问答对)',
|
|
9
10
|
execute({ input, args, owner, use }) {
|
|
10
11
|
return teachForget(input ?? {}, args.join(' '), resolveGroupSuiteRuntime({ owner, use }));
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
// Generated by build-plugin-runtime-entries.mjs. Do not edit.
|
|
2
2
|
import { defineCommand } from 'zhin.js/command';
|
|
3
|
-
import {
|
|
4
|
-
import { resolveGroupSuiteRuntime } from "../../../lib/runtime-state.js";
|
|
3
|
+
import { keywordsForCommand } from "../../../lib/keywords.js";
|
|
5
4
|
export default defineCommand({
|
|
6
|
-
|
|
5
|
+
permit: ['group()', 'role(owner,admin,master,trusted)'],
|
|
6
|
+
description: '添加当前群关键词自动回复',
|
|
7
7
|
params: { keyword: { type: 'string' } },
|
|
8
|
-
execute(
|
|
9
|
-
const keyword = String(params.keyword ?? '');
|
|
10
|
-
const reply = args.join(' ').trim();
|
|
8
|
+
async execute(context) {
|
|
9
|
+
const keyword = String(context.params.keyword ?? '');
|
|
10
|
+
const reply = context.args.join(' ').trim();
|
|
11
11
|
if (!keyword || !reply)
|
|
12
12
|
return '请提供关键词和回复内容';
|
|
13
|
-
|
|
13
|
+
const repository = keywordsForCommand(context.input, context);
|
|
14
|
+
if (typeof repository === 'string')
|
|
15
|
+
return repository;
|
|
16
|
+
await repository.update(store => { store.set(keyword, reply); });
|
|
14
17
|
return `已添加关键词「${keyword}」→「${reply}」`;
|
|
15
18
|
},
|
|
16
19
|
});
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import { defineCommand } from 'zhin.js/command';
|
|
2
|
-
import {
|
|
2
|
+
import type { Message } from '@zhin.js/core/runtime';
|
|
3
3
|
import type { GroupSuiteConfig } from '../../../src/config.js';
|
|
4
|
-
import {
|
|
4
|
+
import { keywordsForCommand } from '../../../src/keywords.js';
|
|
5
5
|
|
|
6
|
-
export default defineCommand<GroupSuiteConfig>({
|
|
7
|
-
|
|
6
|
+
export default defineCommand<GroupSuiteConfig, string, Message>({
|
|
7
|
+
permit: ['group()', 'role(owner,admin,master,trusted)'],
|
|
8
|
+
description: '添加当前群关键词自动回复',
|
|
8
9
|
params: { keyword: { type: 'string' } },
|
|
9
|
-
execute(
|
|
10
|
-
const keyword = String(params.keyword ?? '');
|
|
11
|
-
const reply = args.join(' ').trim();
|
|
10
|
+
async execute(context) {
|
|
11
|
+
const keyword = String(context.params.keyword ?? '');
|
|
12
|
+
const reply = context.args.join(' ').trim();
|
|
12
13
|
if (!keyword || !reply) return '请提供关键词和回复内容';
|
|
13
|
-
|
|
14
|
+
const repository = keywordsForCommand(context.input, context);
|
|
15
|
+
if (typeof repository === 'string') return repository;
|
|
16
|
+
await repository.update(store => { store.set(keyword, reply); });
|
|
14
17
|
return `已添加关键词「${keyword}」→「${reply}」`;
|
|
15
18
|
},
|
|
16
19
|
});
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
// Generated by build-plugin-runtime-entries.mjs. Do not edit.
|
|
2
2
|
import { defineCommand } from 'zhin.js/command';
|
|
3
|
-
import {
|
|
4
|
-
import { resolveGroupSuiteRuntime } from "../../lib/runtime-state.js";
|
|
3
|
+
import { keywordsForCommand } from "../../lib/keywords.js";
|
|
5
4
|
export default defineCommand({
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
permit: ['group()'],
|
|
6
|
+
description: '查看当前群关键词回复对',
|
|
7
|
+
async execute(context) {
|
|
8
|
+
const repository = keywordsForCommand(context.input, context);
|
|
9
|
+
if (typeof repository === 'string')
|
|
10
|
+
return repository;
|
|
11
|
+
const entries = await repository.read();
|
|
9
12
|
if (entries.length === 0)
|
|
10
13
|
return '当前没有设置任何关键词';
|
|
11
14
|
const lines = entries.map(([k, v], i) => `${i + 1}. 「${k}」→「${v}」`);
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { defineCommand } from 'zhin.js/command';
|
|
2
|
-
import {
|
|
2
|
+
import type { Message } from '@zhin.js/core/runtime';
|
|
3
3
|
import type { GroupSuiteConfig } from '../../src/config.js';
|
|
4
|
-
import {
|
|
4
|
+
import { keywordsForCommand } from '../../src/keywords.js';
|
|
5
5
|
|
|
6
|
-
export default defineCommand<GroupSuiteConfig>({
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
export default defineCommand<GroupSuiteConfig, string, Message>({
|
|
7
|
+
permit: ['group()'],
|
|
8
|
+
description: '查看当前群关键词回复对',
|
|
9
|
+
async execute(context) {
|
|
10
|
+
const repository = keywordsForCommand(context.input, context);
|
|
11
|
+
if (typeof repository === 'string') return repository;
|
|
12
|
+
const entries = await repository.read();
|
|
10
13
|
if (entries.length === 0) return '当前没有设置任何关键词';
|
|
11
14
|
const lines = entries.map(([k, v], i) => `${i + 1}. 「${k}」→「${v}」`);
|
|
12
15
|
return `关键词列表(共 ${entries.length} 条):\n${lines.join('\n')}`;
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
// Generated by build-plugin-runtime-entries.mjs. Do not edit.
|
|
2
2
|
import { defineCommand } from 'zhin.js/command';
|
|
3
|
-
import {
|
|
4
|
-
import { resolveGroupSuiteRuntime } from "../../../lib/runtime-state.js";
|
|
3
|
+
import { keywordsForCommand } from "../../../lib/keywords.js";
|
|
5
4
|
export default defineCommand({
|
|
6
|
-
|
|
5
|
+
permit: ['group()', 'role(owner,admin,master,trusted)'],
|
|
6
|
+
description: '删除当前群关键词自动回复',
|
|
7
7
|
params: { keyword: { type: 'string' } },
|
|
8
|
-
execute(
|
|
9
|
-
const keyword = String(params.keyword ?? '');
|
|
8
|
+
async execute(context) {
|
|
9
|
+
const keyword = String(context.params.keyword ?? '');
|
|
10
10
|
if (!keyword)
|
|
11
11
|
return '请提供要删除的关键词';
|
|
12
|
-
|
|
12
|
+
const repository = keywordsForCommand(context.input, context);
|
|
13
|
+
if (typeof repository === 'string')
|
|
14
|
+
return repository;
|
|
15
|
+
if (!(await repository.read()).some(([entry]) => entry === keyword))
|
|
13
16
|
return `关键词「${keyword}」不存在`;
|
|
17
|
+
await repository.update(store => { store.delete(keyword); });
|
|
14
18
|
return `已删除关键词「${keyword}」`;
|
|
15
19
|
},
|
|
16
20
|
});
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import { defineCommand } from 'zhin.js/command';
|
|
2
|
-
import {
|
|
2
|
+
import type { Message } from '@zhin.js/core/runtime';
|
|
3
3
|
import type { GroupSuiteConfig } from '../../../src/config.js';
|
|
4
|
-
import {
|
|
4
|
+
import { keywordsForCommand } from '../../../src/keywords.js';
|
|
5
5
|
|
|
6
|
-
export default defineCommand<GroupSuiteConfig>({
|
|
7
|
-
|
|
6
|
+
export default defineCommand<GroupSuiteConfig, string, Message>({
|
|
7
|
+
permit: ['group()', 'role(owner,admin,master,trusted)'],
|
|
8
|
+
description: '删除当前群关键词自动回复',
|
|
8
9
|
params: { keyword: { type: 'string' } },
|
|
9
|
-
execute(
|
|
10
|
-
const keyword = String(params.keyword ?? '');
|
|
10
|
+
async execute(context) {
|
|
11
|
+
const keyword = String(context.params.keyword ?? '');
|
|
11
12
|
if (!keyword) return '请提供要删除的关键词';
|
|
12
|
-
|
|
13
|
+
const repository = keywordsForCommand(context.input, context);
|
|
14
|
+
if (typeof repository === 'string') return repository;
|
|
15
|
+
if (!(await repository.read()).some(([entry]) => entry === keyword)) return `关键词「${keyword}」不存在`;
|
|
16
|
+
await repository.update(store => { store.delete(keyword); });
|
|
13
17
|
return `已删除关键词「${keyword}」`;
|
|
14
18
|
},
|
|
15
19
|
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Generated by build-plugin-runtime-entries.mjs. Do not edit.
|
|
2
|
+
import { defineCommand } from 'zhin.js/command';
|
|
3
|
+
import { segment } from 'zhin.js';
|
|
4
|
+
import { resolveGroupSuiteConfig } from "../../lib/config.js";
|
|
5
|
+
import { resolveGroupSuiteRuntime } from "../../lib/runtime-state.js";
|
|
6
|
+
import { flushStatsBuffer, queryStats, resolveGroupId } from "../../lib/stats-lib.js";
|
|
7
|
+
import { buildStatsRankReportData } from "../../lib/stats-data.js";
|
|
8
|
+
import { buildStatsRankHtml, STATS_REPORT_CANVAS } from "../../lib/stats-card.js";
|
|
9
|
+
import { todayStr, resolveSender } from "../../lib/shared-runtime.js";
|
|
10
|
+
export default defineCommand({
|
|
11
|
+
description: '查看今日群消息统计卡片(不支持图片时显示文本)',
|
|
12
|
+
permit: ['group()'],
|
|
13
|
+
async execute(context) {
|
|
14
|
+
if (!context.input)
|
|
15
|
+
throw new Error('Group statistics require an incoming message');
|
|
16
|
+
const runtime = resolveGroupSuiteRuntime(context);
|
|
17
|
+
await flushStatsBuffer(runtime);
|
|
18
|
+
const stats = await queryStats(resolveGroupId(context.input), todayStr(), runtime);
|
|
19
|
+
const data = buildStatsRankReportData(stats, '今日本群消息统计', resolveGroupSuiteConfig(context.config).rankSize, resolveSender(context.input).id);
|
|
20
|
+
return segment.html({ html: await buildStatsRankHtml(data), width: 540,
|
|
21
|
+
backgroundColor: STATS_REPORT_CANVAS, fileName: 'group-stats.png' });
|
|
22
|
+
},
|
|
23
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { defineCommand } from 'zhin.js/command';
|
|
2
|
+
import { segment } from 'zhin.js';
|
|
3
|
+
import type { Message, SendContent } from '@zhin.js/core/runtime';
|
|
4
|
+
import { resolveGroupSuiteConfig, type GroupSuiteConfig } from '../../src/config.js';
|
|
5
|
+
import { resolveGroupSuiteRuntime } from '../../src/runtime-state.js';
|
|
6
|
+
import { flushStatsBuffer, queryStats, resolveGroupId } from '../../src/stats-lib.js';
|
|
7
|
+
import { buildStatsRankReportData } from '../../src/stats-data.js';
|
|
8
|
+
import { buildStatsRankHtml, STATS_REPORT_CANVAS } from '../../src/stats-card.js';
|
|
9
|
+
import { todayStr, resolveSender } from '../../src/shared-runtime.js';
|
|
10
|
+
|
|
11
|
+
export default defineCommand<GroupSuiteConfig, SendContent, Message>({
|
|
12
|
+
description: '查看今日群消息统计卡片(不支持图片时显示文本)',
|
|
13
|
+
permit: ['group()'],
|
|
14
|
+
async execute(context) {
|
|
15
|
+
if (!context.input) throw new Error('Group statistics require an incoming message');
|
|
16
|
+
const runtime = resolveGroupSuiteRuntime(context);
|
|
17
|
+
await flushStatsBuffer(runtime);
|
|
18
|
+
const stats = await queryStats(resolveGroupId(context.input), todayStr(), runtime);
|
|
19
|
+
const data = buildStatsRankReportData(stats, '今日本群消息统计',
|
|
20
|
+
resolveGroupSuiteConfig(context.config).rankSize, resolveSender(context.input).id);
|
|
21
|
+
return segment.html({ html: await buildStatsRankHtml(data), width: 540,
|
|
22
|
+
backgroundColor: STATS_REPORT_CANVAS, fileName: 'group-stats.png' });
|
|
23
|
+
},
|
|
24
|
+
});
|
package/commands/teach/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import { resolveGroupSuiteConfig } from "../../lib/config.js";
|
|
|
4
4
|
import { teachAdd } from "../../lib/teach-lib.js";
|
|
5
5
|
import { resolveGroupSuiteRuntime } from "../../lib/runtime-state.js";
|
|
6
6
|
export default defineCommand({
|
|
7
|
+
permit: ['group()', 'role(owner,admin,master,trusted)'],
|
|
7
8
|
description: '教我问答(teach 问题 回答 或 问题|答案)',
|
|
8
9
|
execute({ config, input, args, owner, use }) {
|
|
9
10
|
return teachAdd(input ?? {}, resolveGroupSuiteConfig(config), args.join(' '), false, resolveGroupSuiteRuntime({ owner, use }));
|
package/commands/teach/index.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { teachAdd } from '../../src/teach-lib.js';
|
|
|
5
5
|
import { resolveGroupSuiteRuntime } from '../../src/runtime-state.js';
|
|
6
6
|
|
|
7
7
|
export default defineCommand<GroupSuiteConfig, string, Message>({
|
|
8
|
+
permit: ['group()', 'role(owner,admin,master,trusted)'],
|
|
8
9
|
description: '教我问答(teach 问题 回答 或 问题|答案)',
|
|
9
10
|
execute({ config, input, args, owner, use }) {
|
|
10
11
|
return teachAdd(input ?? {}, resolveGroupSuiteConfig(config), args.join(' '), false, resolveGroupSuiteRuntime({ owner, use }));
|
|
@@ -4,6 +4,7 @@ import { resolveGroupSuiteConfig } from "../../lib/config.js";
|
|
|
4
4
|
import { teachAdd } from "../../lib/teach-lib.js";
|
|
5
5
|
import { resolveGroupSuiteRuntime } from "../../lib/runtime-state.js";
|
|
6
6
|
export default defineCommand({
|
|
7
|
+
permit: ['group()', 'role(owner,admin,master,trusted)'],
|
|
7
8
|
description: '教我正则问答',
|
|
8
9
|
execute({ config, input, args, owner, use }) {
|
|
9
10
|
return teachAdd(input ?? {}, resolveGroupSuiteConfig(config), args.join(' '), true, resolveGroupSuiteRuntime({ owner, use }));
|
|
@@ -5,6 +5,7 @@ import { teachAdd } from '../../src/teach-lib.js';
|
|
|
5
5
|
import { resolveGroupSuiteRuntime } from '../../src/runtime-state.js';
|
|
6
6
|
|
|
7
7
|
export default defineCommand<GroupSuiteConfig, string, Message>({
|
|
8
|
+
permit: ['group()', 'role(owner,admin,master,trusted)'],
|
|
8
9
|
description: '教我正则问答',
|
|
9
10
|
execute({ config, input, args, owner, use }) {
|
|
10
11
|
return teachAdd(input ?? {}, resolveGroupSuiteConfig(config), args.join(' '), true, resolveGroupSuiteRuntime({ owner, use }));
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Generated by build-plugin-runtime-entries.mjs. Do not edit.
|
|
2
|
+
import { defineHandler } from 'zhin.js/handler';
|
|
3
|
+
import { outboundMessageToken } from '@zhin.js/core/runtime';
|
|
4
|
+
import { resolveGroupSuiteConfig } from "../../lib/config.js";
|
|
5
|
+
/** Canonical notice input only; no SDK-specific callbacks or direct platform sends. */
|
|
6
|
+
export default defineHandler({
|
|
7
|
+
event: 'notice.receive',
|
|
8
|
+
async handle({ payload: notice }) {
|
|
9
|
+
const text = resolveGroupSuiteConfig(this.config).welcomeMessage;
|
|
10
|
+
if (!text || notice.name !== 'notice.group.member_increase'
|
|
11
|
+
|| notice.conversation?.kind !== 'group' || !notice.target?.id)
|
|
12
|
+
return;
|
|
13
|
+
const content = text.replaceAll('{name}', notice.target.name ?? notice.target.id)
|
|
14
|
+
.replaceAll('{id}', notice.target.id);
|
|
15
|
+
const result = await this.use(outboundMessageToken).send({
|
|
16
|
+
requester: this.owner,
|
|
17
|
+
conversation: notice.conversation,
|
|
18
|
+
content: { type: 'text', data: { text: content } },
|
|
19
|
+
});
|
|
20
|
+
if (result.status !== 'sent') {
|
|
21
|
+
// Unknown delivery must remain visible, and must never trigger an automatic duplicate send.
|
|
22
|
+
throw new Error(`Group welcome delivery ${result.status}`);
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { defineHandler } from 'zhin.js/handler';
|
|
2
|
+
import { outboundMessageToken } from '@zhin.js/core/runtime';
|
|
3
|
+
import { resolveGroupSuiteConfig, type GroupSuiteConfig } from '../../src/config.js';
|
|
4
|
+
|
|
5
|
+
/** Canonical notice input only; no SDK-specific callbacks or direct platform sends. */
|
|
6
|
+
export default defineHandler({
|
|
7
|
+
event: 'notice.receive',
|
|
8
|
+
async handle({ payload: notice }) {
|
|
9
|
+
const text = resolveGroupSuiteConfig(this.config as Partial<GroupSuiteConfig>).welcomeMessage;
|
|
10
|
+
if (!text || notice.name !== 'notice.group.member_increase'
|
|
11
|
+
|| notice.conversation?.kind !== 'group' || !notice.target?.id) return;
|
|
12
|
+
const content = text.replaceAll('{name}', notice.target.name ?? notice.target.id)
|
|
13
|
+
.replaceAll('{id}', notice.target.id);
|
|
14
|
+
const result = await this.use(outboundMessageToken).send({
|
|
15
|
+
requester: this.owner,
|
|
16
|
+
conversation: notice.conversation,
|
|
17
|
+
content: { type: 'text', data: { text: content } },
|
|
18
|
+
});
|
|
19
|
+
if (result.status !== 'sent') {
|
|
20
|
+
// Unknown delivery must remain visible, and must never trigger an automatic duplicate send.
|
|
21
|
+
throw new Error(`Group welcome delivery ${result.status}`);
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
});
|
package/lib/checkin-lib.d.ts
CHANGED
|
@@ -1,27 +1,7 @@
|
|
|
1
|
+
import type { ConversationInput } from './conversation-scope.js';
|
|
1
2
|
import type { GroupSuiteConfig } from './config.js';
|
|
2
3
|
import type { GroupSuiteRuntime } from './runtime-state.js';
|
|
3
|
-
export declare function doCheckin(input:
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
readonly name?: string;
|
|
7
|
-
};
|
|
8
|
-
target?: string;
|
|
9
|
-
metadata?: Readonly<Record<string, unknown>>;
|
|
10
|
-
}, cfg: GroupSuiteConfig, runtime: GroupSuiteRuntime): Promise<string>;
|
|
11
|
-
export declare function myPoints(input: {
|
|
12
|
-
sender?: {
|
|
13
|
-
readonly id: string;
|
|
14
|
-
readonly name?: string;
|
|
15
|
-
};
|
|
16
|
-
target?: string;
|
|
17
|
-
metadata?: Readonly<Record<string, unknown>>;
|
|
18
|
-
}, runtime: GroupSuiteRuntime): Promise<string>;
|
|
19
|
-
export declare function pointsRank(input: {
|
|
20
|
-
sender?: {
|
|
21
|
-
readonly id: string;
|
|
22
|
-
readonly name?: string;
|
|
23
|
-
};
|
|
24
|
-
target?: string;
|
|
25
|
-
metadata?: Readonly<Record<string, unknown>>;
|
|
26
|
-
}, cfg: GroupSuiteConfig, runtime: GroupSuiteRuntime): Promise<string>;
|
|
4
|
+
export declare function doCheckin(input: ConversationInput, cfg: GroupSuiteConfig, runtime: GroupSuiteRuntime): Promise<string>;
|
|
5
|
+
export declare function myPoints(input: ConversationInput, runtime: GroupSuiteRuntime): Promise<string>;
|
|
6
|
+
export declare function pointsRank(input: ConversationInput, cfg: GroupSuiteConfig, runtime: GroupSuiteRuntime): Promise<string>;
|
|
27
7
|
//# sourceMappingURL=checkin-lib.d.ts.map
|
package/lib/checkin-lib.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkin-lib.d.ts","sourceRoot":"","sources":["../src/checkin-lib.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"checkin-lib.d.ts","sourceRoot":"","sources":["../src/checkin-lib.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAUpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAuD5D,wBAAsB,SAAS,CAC7B,KAAK,EAAE,iBAAiB,EACxB,GAAG,EAAE,gBAAgB,EACrB,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,MAAM,CAAC,CA2CjB;AAED,wBAAsB,QAAQ,CAC5B,KAAK,EAAE,iBAAiB,EACxB,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,MAAM,CAAC,CAqBjB;AAED,wBAAsB,UAAU,CAC9B,KAAK,EAAE,iBAAiB,EACxB,GAAG,EAAE,gBAAgB,EACrB,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,MAAM,CAAC,CAqBjB"}
|
package/lib/checkin-lib.js
CHANGED
|
@@ -112,9 +112,7 @@ export async function pointsRank(input, cfg, runtime) {
|
|
|
112
112
|
if (!M)
|
|
113
113
|
return '签到数据库尚未就绪';
|
|
114
114
|
const { type: ctxType, id: ctxId } = resolveContextKey(input);
|
|
115
|
-
const all = (await M.select().where(ctxType
|
|
116
|
-
? { context_type: 'global' }
|
|
117
|
-
: { context_type: ctxType, context_id: ctxId }));
|
|
115
|
+
const all = (await M.select().where({ context_type: ctxType, context_id: ctxId }));
|
|
118
116
|
if (all.length === 0)
|
|
119
117
|
return '还没有人签到过哦~';
|
|
120
118
|
const sorted = all.sort((a, b) => Number(b.points || 0) - Number(a.points || 0));
|
|
@@ -124,7 +122,8 @@ export async function pointsRank(input, cfg, runtime) {
|
|
|
124
122
|
const prefix = i < 3 ? medals[i] : `${i + 1}.`;
|
|
125
123
|
return `${prefix} ${u.user_name || u.user_id} — ${u.points}分 (${u.total_checkins}天)`;
|
|
126
124
|
});
|
|
127
|
-
const title = ctxType === 'group' ? '本群积分排行'
|
|
125
|
+
const title = ctxType === 'group' ? '本群积分排行'
|
|
126
|
+
: ctxType === 'channel' ? '本频道积分排行' : '当前私聊积分排行';
|
|
128
127
|
const { id: userId } = resolveSender(input);
|
|
129
128
|
const myRank = sorted.findIndex((u) => u.user_id === userId);
|
|
130
129
|
const footer = myRank >= 0 ? `\n你的排名: 第${myRank + 1}名` : '';
|
package/lib/checkin-lib.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkin-lib.js","sourceRoot":"","sources":["../src/checkin-lib.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"checkin-lib.js","sourceRoot":"","sources":["../src/checkin-lib.ts"],"names":[],"mappings":"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"}
|
package/lib/config.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
export interface GroupSuiteConfig {
|
|
2
2
|
keywordReply: boolean;
|
|
3
|
+
/** Explicitly volatile keywords for demos without a persistent Database Host. */
|
|
4
|
+
ephemeralKeywords: boolean;
|
|
5
|
+
/** Empty disables group member welcomes. {name} and {id} are literal placeholders. */
|
|
6
|
+
welcomeMessage: string;
|
|
3
7
|
basePointsMin: number;
|
|
4
8
|
basePointsMax: number;
|
|
5
9
|
streakBonus: number;
|
package/lib/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,0BAA0B,EAAE,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,OAAO,CAAC;IACtB,iFAAiF;IACjF,iBAAiB,EAAE,OAAO,CAAC;IAC3B,sFAAsF;IACtF,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,0BAA0B,EAAE,gBAaxC,CAAC;AAEF,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,SAAS,GACzC,gBAAgB,CAKlB"}
|
package/lib/config.js
CHANGED
package/lib/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAiBA,MAAM,CAAC,MAAM,0BAA0B,GAAqB;IAC1D,YAAY,EAAE,KAAK;IACnB,iBAAiB,EAAE,KAAK;IACxB,cAAc,EAAE,EAAE;IAClB,aAAa,EAAE,EAAE;IACjB,aAAa,EAAE,EAAE;IACjB,WAAW,EAAE,CAAC;IACd,SAAS,EAAE,EAAE;IACb,QAAQ,EAAE,EAAE;IACZ,gBAAgB,EAAE,GAAG;IACrB,eAAe,EAAE,IAAI;IACrB,eAAe,EAAE,IAAI;IACrB,aAAa,EAAE,EAAE;CAClB,CAAC;AAEF,MAAM,UAAU,uBAAuB,CACrC,GAA0C;IAE1C,OAAO;QACL,GAAG,0BAA0B;QAC7B,GAAG,GAAG;KACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type DeliveryTarget } from 'zhin.js';
|
|
2
|
+
import { adapterFeatureId } from 'zhin.js/adapter';
|
|
3
|
+
import type { ToolInvocationOrigin } from '@zhin.js/tool';
|
|
4
|
+
export interface ConversationInput {
|
|
5
|
+
readonly conversation?: DeliveryTarget;
|
|
6
|
+
readonly sender?: Readonly<{
|
|
7
|
+
id: string;
|
|
8
|
+
name?: string;
|
|
9
|
+
}>;
|
|
10
|
+
readonly content?: unknown;
|
|
11
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
12
|
+
}
|
|
13
|
+
/** Versioned, unambiguous identity; historical bare group ids are deliberately not read. */
|
|
14
|
+
export declare function conversationKey(target: DeliveryTarget): string;
|
|
15
|
+
export declare function requireConversation(input: ConversationInput): DeliveryTarget;
|
|
16
|
+
/** Tool origins contain an endpoint selector, not a canonical endpoint capability id. */
|
|
17
|
+
export declare function toolGroupConversation(context: {
|
|
18
|
+
readonly origin: ToolInvocationOrigin;
|
|
19
|
+
project<T>(feature: typeof adapterFeatureId): T;
|
|
20
|
+
}, groupId?: string): DeliveryTarget;
|
|
21
|
+
//# sourceMappingURL=conversation-scope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation-scope.d.ts","sourceRoot":"","sources":["../src/conversation-scope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,SAAS,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAqB,MAAM,iBAAiB,CAAC;AACtE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE1D,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,YAAY,CAAC,EAAE,cAAc,CAAC;IACvC,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1D,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACvD;AAED,4FAA4F;AAC5F,wBAAgB,eAAe,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAK9D;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,iBAAiB,GAAG,cAAc,CAG5E;AAED,yFAAyF;AACzF,wBAAgB,qBAAqB,CAAC,OAAO,EAAE;IAC7C,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;IACtC,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,gBAAgB,GAAG,CAAC,CAAC;CACjD,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,cAAc,CAgBnC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { createDeliveryTarget } from 'zhin.js';
|
|
2
|
+
import { adapterFeatureId } from 'zhin.js/adapter';
|
|
3
|
+
/** Versioned, unambiguous identity; historical bare group ids are deliberately not read. */
|
|
4
|
+
export function conversationKey(target) {
|
|
5
|
+
const canonical = createDeliveryTarget({ conversation: target });
|
|
6
|
+
return JSON.stringify(['conversation-v1', canonical.endpoint.adapter, canonical.endpoint.id,
|
|
7
|
+
canonical.kind, canonical.id, canonical.parent?.kind ?? null, canonical.parent?.id ?? null,
|
|
8
|
+
canonical.threadId ?? null]);
|
|
9
|
+
}
|
|
10
|
+
export function requireConversation(input) {
|
|
11
|
+
if (!input.conversation)
|
|
12
|
+
throw new Error('Group Suite requires a canonical conversation');
|
|
13
|
+
return createDeliveryTarget({ conversation: input.conversation });
|
|
14
|
+
}
|
|
15
|
+
/** Tool origins contain an endpoint selector, not a canonical endpoint capability id. */
|
|
16
|
+
export function toolGroupConversation(context, groupId) {
|
|
17
|
+
if (context.origin.kind !== 'im' || context.origin.scope !== 'group') {
|
|
18
|
+
throw new Error('Group Suite query tools require a group IM origin');
|
|
19
|
+
}
|
|
20
|
+
const origin = context.origin;
|
|
21
|
+
const index = context.project(adapterFeatureId);
|
|
22
|
+
const matches = index.describe().filter(endpoint => (String(endpoint.id) === origin.endpoint || endpoint.name === origin.endpoint)
|
|
23
|
+
&& index.clientAdapter(endpoint.id) === origin.platform);
|
|
24
|
+
if (matches.length !== 1)
|
|
25
|
+
throw new Error('Group Suite tool endpoint is missing or ambiguous');
|
|
26
|
+
return createDeliveryTarget({ conversation: {
|
|
27
|
+
endpoint: { id: String(matches[0].id), adapter: origin.platform },
|
|
28
|
+
kind: 'group', id: groupId ?? origin.sceneId,
|
|
29
|
+
...(origin.threadId !== undefined && (groupId === undefined || groupId === origin.sceneId)
|
|
30
|
+
? { threadId: origin.threadId } : {}),
|
|
31
|
+
} });
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=conversation-scope.js.map
|