@zhin.js/plugin-group-suite 3.0.2 → 3.0.4
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 +42 -58
- package/agent/tools/group_announce.ts +2 -2
- package/commands/checkin.ts +12 -0
- package/commands/forget.ts +12 -0
- package/commands/keyword-add/[keyword:string].ts +15 -0
- package/commands/keyword-list.ts +14 -0
- package/commands/keyword-remove/[keyword:string].ts +14 -0
- package/commands/mypoints.ts +12 -0
- package/commands/mystats.ts +12 -0
- package/commands/rank.ts +12 -0
- package/commands/stats-rank.ts +20 -0
- package/commands/stats-week.ts +20 -0
- package/commands/stats.ts +21 -0
- package/commands/teach-list/[page:number=1].ts +13 -0
- package/commands/teach-regex.ts +12 -0
- package/commands/teach.ts +12 -0
- package/lib/analysis-card.d.ts +4 -0
- package/lib/analysis-card.d.ts.map +1 -0
- package/lib/analysis-card.js.map +1 -0
- package/lib/analysis.d.ts +95 -0
- package/lib/analysis.d.ts.map +1 -0
- package/lib/analysis.js.map +1 -0
- package/lib/card-layout.d.ts +27 -0
- package/lib/card-layout.d.ts.map +1 -0
- package/lib/card-layout.js.map +1 -0
- package/lib/checkin-lib.d.ts +18 -0
- package/lib/checkin-lib.d.ts.map +1 -0
- package/lib/checkin-lib.js +118 -0
- package/lib/checkin-lib.js.map +1 -0
- package/lib/config.d.ts +15 -0
- package/lib/config.d.ts.map +1 -0
- package/lib/config.js +19 -0
- package/lib/config.js.map +1 -0
- package/lib/db-store.d.ts +12 -0
- package/lib/db-store.d.ts.map +1 -0
- package/lib/db-store.js +38 -0
- package/lib/db-store.js.map +1 -0
- package/lib/index.d.ts +10 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +8 -0
- package/lib/index.js.map +1 -0
- package/lib/keyword-store.d.ts +6 -0
- package/lib/keyword-store.d.ts.map +1 -0
- package/lib/keyword-store.js +21 -0
- package/lib/keyword-store.js.map +1 -0
- package/lib/memory-store.d.ts +29 -0
- package/lib/memory-store.d.ts.map +1 -0
- package/lib/memory-store.js +59 -0
- package/lib/memory-store.js.map +1 -0
- package/lib/runtime-state.d.ts +24 -0
- package/lib/runtime-state.d.ts.map +1 -0
- package/lib/runtime-state.js +21 -0
- package/lib/runtime-state.js.map +1 -0
- package/lib/shared-runtime.d.ts +20 -0
- package/lib/shared-runtime.d.ts.map +1 -0
- package/lib/shared-runtime.js +34 -0
- package/lib/shared-runtime.js.map +1 -0
- package/lib/stats-card.d.ts +5 -0
- package/lib/stats-card.d.ts.map +1 -0
- package/lib/stats-card.js.map +1 -0
- package/lib/stats-data.d.ts +32 -0
- package/lib/stats-data.d.ts.map +1 -0
- package/lib/stats-data.js.map +1 -0
- package/lib/stats-lib.d.ts +29 -0
- package/lib/stats-lib.d.ts.map +1 -0
- package/lib/stats-lib.js +173 -0
- package/lib/stats-lib.js.map +1 -0
- package/lib/tables.d.ts +4 -0
- package/lib/tables.d.ts.map +1 -0
- package/lib/tables.js +40 -0
- package/lib/tables.js.map +1 -0
- package/lib/teach-lib.d.ts +22 -0
- package/lib/teach-lib.d.ts.map +1 -0
- package/lib/teach-lib.js +233 -0
- package/lib/teach-lib.js.map +1 -0
- package/middlewares/keyword-reply.ts +37 -0
- package/middlewares/stats-count.ts +22 -0
- package/middlewares/teach-reply.ts +22 -0
- package/package.json +37 -15
- package/plugin.ts +39 -0
- package/schema.json +17 -0
- package/src/checkin-lib.ts +148 -0
- package/src/config.ts +23 -57
- package/src/db-store.ts +51 -0
- package/src/index.ts +47 -33
- package/src/keyword-store.ts +24 -0
- package/src/memory-store.ts +88 -0
- package/src/runtime-state.ts +44 -0
- package/src/shared-runtime.ts +44 -0
- package/src/stats-lib.ts +202 -0
- package/src/tables.ts +46 -0
- package/src/teach-lib.ts +301 -0
- package/tools/checkin-query/handler.ts +2 -2
- package/tools/checkin-rank/handler.ts +1 -1
- package/tools/stats-query/handler.ts +2 -2
- package/tools/stats-user/handler.ts +3 -2
- package/lib/agent/tools/group_announce.js +0 -13
- package/lib/agent/tools/group_announce.js.map +0 -1
- package/lib/src/admin.js +0 -114
- package/lib/src/admin.js.map +0 -1
- package/lib/src/analysis-card.js.map +0 -1
- package/lib/src/analysis.js.map +0 -1
- package/lib/src/card-layout.js.map +0 -1
- package/lib/src/checkin.js +0 -168
- package/lib/src/checkin.js.map +0 -1
- package/lib/src/config.js +0 -41
- package/lib/src/config.js.map +0 -1
- package/lib/src/daily-analysis.js +0 -333
- package/lib/src/daily-analysis.js.map +0 -1
- package/lib/src/index.js +0 -30
- package/lib/src/index.js.map +0 -1
- package/lib/src/shared.js +0 -40
- package/lib/src/shared.js.map +0 -1
- package/lib/src/stats-card.js.map +0 -1
- package/lib/src/stats-data.js.map +0 -1
- package/lib/src/stats.js +0 -258
- package/lib/src/stats.js.map +0 -1
- package/lib/src/teach.js +0 -294
- package/lib/src/teach.js.map +0 -1
- package/plugin.yml +0 -3
- package/src/admin.ts +0 -136
- package/src/checkin.ts +0 -196
- package/src/daily-analysis.ts +0 -458
- package/src/shared.ts +0 -51
- package/src/stats.ts +0 -298
- package/src/teach.ts +0 -307
- /package/lib/{src/analysis-card.js → analysis-card.js} +0 -0
- /package/lib/{src/analysis.js → analysis.js} +0 -0
- /package/lib/{src/card-layout.js → card-layout.js} +0 -0
- /package/lib/{src/stats-card.js → stats-card.js} +0 -0
- /package/lib/{src/stats-data.js → stats-data.js} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stats-lib.d.ts","sourceRoot":"","sources":["../src/stats-lib.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAapD,OAAO,KAAK,EAAE,iBAAiB,EAAyB,MAAM,oBAAoB,CAAC;AAEnF,wBAAgB,YAAY,IAAI,MAAM,CAKrC;AAED,wBAAgB,aAAa,IAAI,MAAM,CAGtC;AAQD,wBAAgB,cAAc,CAAC,KAAK,EAAE;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAC9C,GAAG,MAAM,CAUT;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAC9C,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAmBpC;AAED,wBAAsB,gBAAgB,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqCjF;AAED,wBAAsB,UAAU,CAC9B,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAsBvD;AAED,KAAK,YAAY,GAAG;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAC9C,CAAC;AAEF,wBAAsB,aAAa,CACjC,KAAK,EAAE,YAAY,EACnB,GAAG,EAAE,gBAAgB,EACrB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAOjB;AAED,wBAAsB,WAAW,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAmCnG;AAED,kBAAkB;AAClB,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC"}
|
package/lib/stats-lib.js
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { getStatsModel } from './db-store.js';
|
|
2
|
+
import { resolveSender, todayStr, ts, } from './shared-runtime.js';
|
|
3
|
+
import { buildStatsRankReportData, formatMyStatsText, formatRankText, } from './stats-data.js';
|
|
4
|
+
export function weekStartStr() {
|
|
5
|
+
const d = new Date();
|
|
6
|
+
const day = d.getDay() || 7;
|
|
7
|
+
d.setDate(d.getDate() - day + 1);
|
|
8
|
+
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
|
|
9
|
+
}
|
|
10
|
+
export function monthStartStr() {
|
|
11
|
+
const d = new Date();
|
|
12
|
+
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-01`;
|
|
13
|
+
}
|
|
14
|
+
const buffer = new Map();
|
|
15
|
+
function bufferKey(userId, groupId, date) {
|
|
16
|
+
return `${userId}:${groupId}:${date}`;
|
|
17
|
+
}
|
|
18
|
+
export function resolveGroupId(input) {
|
|
19
|
+
const meta = input.metadata ?? {};
|
|
20
|
+
const channelType = String(meta.type ?? meta.channelType ?? '');
|
|
21
|
+
if (channelType === 'group' || channelType === 'guild') {
|
|
22
|
+
return String(input.target ?? meta.channelId ?? '');
|
|
23
|
+
}
|
|
24
|
+
if (input.target && channelType !== 'private') {
|
|
25
|
+
return String(input.target);
|
|
26
|
+
}
|
|
27
|
+
return '';
|
|
28
|
+
}
|
|
29
|
+
export function recordMessage(input, runtime) {
|
|
30
|
+
const targetBuffer = runtime?.statsBuffer ?? buffer;
|
|
31
|
+
const { id: userId, name: userName } = resolveSender(input);
|
|
32
|
+
if (!userId)
|
|
33
|
+
return;
|
|
34
|
+
const groupId = resolveGroupId(input);
|
|
35
|
+
const key = bufferKey(userId, groupId, todayStr());
|
|
36
|
+
const pending = targetBuffer.get(key);
|
|
37
|
+
if (pending) {
|
|
38
|
+
pending.count++;
|
|
39
|
+
pending.user_name = userName;
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
targetBuffer.set(key, {
|
|
43
|
+
user_id: userId,
|
|
44
|
+
user_name: userName,
|
|
45
|
+
group_id: groupId,
|
|
46
|
+
date: todayStr(),
|
|
47
|
+
count: 1,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
export async function flushStatsBuffer(runtime) {
|
|
52
|
+
const targetBuffer = runtime?.statsBuffer ?? buffer;
|
|
53
|
+
const M = getStatsModel(runtime?.db);
|
|
54
|
+
if (!M || targetBuffer.size === 0)
|
|
55
|
+
return;
|
|
56
|
+
const entries = [...targetBuffer.values()];
|
|
57
|
+
targetBuffer.clear();
|
|
58
|
+
for (const entry of entries) {
|
|
59
|
+
try {
|
|
60
|
+
const existing = (await M.select().where({
|
|
61
|
+
user_id: entry.user_id,
|
|
62
|
+
group_id: entry.group_id,
|
|
63
|
+
date: entry.date,
|
|
64
|
+
}));
|
|
65
|
+
if (existing.length > 0) {
|
|
66
|
+
await M.update({
|
|
67
|
+
count: Number(existing[0].count || 0) + entry.count,
|
|
68
|
+
user_name: entry.user_name,
|
|
69
|
+
updated_at: ts(),
|
|
70
|
+
}).where({
|
|
71
|
+
user_id: entry.user_id,
|
|
72
|
+
group_id: entry.group_id,
|
|
73
|
+
date: entry.date,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
await M.insert({
|
|
78
|
+
user_id: entry.user_id,
|
|
79
|
+
user_name: entry.user_name,
|
|
80
|
+
group_id: entry.group_id,
|
|
81
|
+
date: entry.date,
|
|
82
|
+
count: entry.count,
|
|
83
|
+
updated_at: ts(),
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
/* single row failure */
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
export async function queryStats(groupId, fromDate, runtime) {
|
|
93
|
+
const M = getStatsModel(runtime?.db);
|
|
94
|
+
if (!M)
|
|
95
|
+
return new Map();
|
|
96
|
+
const all = (groupId
|
|
97
|
+
? await M.select().where({ group_id: groupId })
|
|
98
|
+
: await M.select());
|
|
99
|
+
const result = new Map();
|
|
100
|
+
for (const row of all) {
|
|
101
|
+
if (String(row.date) < fromDate)
|
|
102
|
+
continue;
|
|
103
|
+
const userId = String(row.user_id);
|
|
104
|
+
const existing = result.get(userId);
|
|
105
|
+
if (existing) {
|
|
106
|
+
existing.count += Number(row.count || 0);
|
|
107
|
+
if (row.user_name)
|
|
108
|
+
existing.name = String(row.user_name);
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
result.set(userId, {
|
|
112
|
+
name: String(row.user_name || row.user_id),
|
|
113
|
+
count: Number(row.count || 0),
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return result;
|
|
118
|
+
}
|
|
119
|
+
export async function statsRankText(input, cfg, fromDate, title, runtime) {
|
|
120
|
+
await flushStatsBuffer(runtime);
|
|
121
|
+
const groupId = resolveGroupId(input);
|
|
122
|
+
const stats = await queryStats(groupId, fromDate, runtime);
|
|
123
|
+
const { id: userId } = resolveSender(input);
|
|
124
|
+
const data = buildStatsRankReportData(stats, title, cfg.rankSize, userId);
|
|
125
|
+
return formatRankText(data);
|
|
126
|
+
}
|
|
127
|
+
export async function myStatsText(input, runtime) {
|
|
128
|
+
await flushStatsBuffer(runtime);
|
|
129
|
+
const M = getStatsModel(runtime?.db);
|
|
130
|
+
if (!M)
|
|
131
|
+
return '统计数据库尚未就绪';
|
|
132
|
+
const { id: userId, name: userName } = resolveSender(input);
|
|
133
|
+
if (!userId)
|
|
134
|
+
return '无法获取用户信息';
|
|
135
|
+
const groupId = resolveGroupId(input);
|
|
136
|
+
const rows = (groupId
|
|
137
|
+
? await M.select().where({ user_id: userId, group_id: groupId })
|
|
138
|
+
: await M.select().where({ user_id: userId }));
|
|
139
|
+
if (rows.length === 0)
|
|
140
|
+
return '暂无你的消息记录';
|
|
141
|
+
const today = todayStr();
|
|
142
|
+
const weekStart = weekStartStr();
|
|
143
|
+
const monthStart = monthStartStr();
|
|
144
|
+
let todayCount = 0;
|
|
145
|
+
let weekCount = 0;
|
|
146
|
+
let monthCount = 0;
|
|
147
|
+
let totalCount = 0;
|
|
148
|
+
for (const row of rows) {
|
|
149
|
+
const c = Number(row.count || 0);
|
|
150
|
+
totalCount += c;
|
|
151
|
+
if (String(row.date) >= monthStart)
|
|
152
|
+
monthCount += c;
|
|
153
|
+
if (String(row.date) >= weekStart)
|
|
154
|
+
weekCount += c;
|
|
155
|
+
if (row.date === today)
|
|
156
|
+
todayCount += c;
|
|
157
|
+
}
|
|
158
|
+
const data = {
|
|
159
|
+
userName: userName || '你',
|
|
160
|
+
scope: groupId ? '本群' : '全局',
|
|
161
|
+
todayCount,
|
|
162
|
+
weekCount,
|
|
163
|
+
monthCount,
|
|
164
|
+
totalCount,
|
|
165
|
+
activeDays: rows.length,
|
|
166
|
+
};
|
|
167
|
+
return formatMyStatsText(data);
|
|
168
|
+
}
|
|
169
|
+
/** Test helper */
|
|
170
|
+
export function resetStatsBuffer() {
|
|
171
|
+
buffer.clear();
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=stats-lib.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stats-lib.js","sourceRoot":"","sources":["../src/stats-lib.ts"],"names":[],"mappings":"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"}
|
package/lib/tables.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tables.d.ts","sourceRoot":"","sources":["../src/tables.ts"],"names":[],"mappings":"AASA,wBAAgB,sBAAsB,CACpC,EAAE,EAAE;IAAE,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAA;CAAE,GACtE,IAAI,CAkCN"}
|
package/lib/tables.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Group-suite table schemas for DatabaseHost / legacy DatabaseFeature.
|
|
3
|
+
*/
|
|
4
|
+
import { CHECKIN_TABLE, TEACH_TABLE, STATS_TABLE, } from './memory-store.js';
|
|
5
|
+
export function defineGroupSuiteTables(db) {
|
|
6
|
+
db.define(CHECKIN_TABLE, {
|
|
7
|
+
user_id: { type: 'text', nullable: false },
|
|
8
|
+
user_name: { type: 'text', default: '' },
|
|
9
|
+
points: { type: 'integer', default: 0 },
|
|
10
|
+
total_checkins: { type: 'integer', default: 0 },
|
|
11
|
+
streak: { type: 'integer', default: 0 },
|
|
12
|
+
max_streak: { type: 'integer', default: 0 },
|
|
13
|
+
last_checkin: { type: 'text', default: '' },
|
|
14
|
+
context_type: { type: 'text', default: 'global' },
|
|
15
|
+
context_id: { type: 'text', default: '' },
|
|
16
|
+
created_at: { type: 'text', default: '' },
|
|
17
|
+
updated_at: { type: 'text', default: '' },
|
|
18
|
+
});
|
|
19
|
+
db.define(TEACH_TABLE, {
|
|
20
|
+
question: { type: 'text', nullable: false },
|
|
21
|
+
answer: { type: 'text', nullable: false },
|
|
22
|
+
is_regex: { type: 'integer', default: 0 },
|
|
23
|
+
context_type: { type: 'text', default: 'global' },
|
|
24
|
+
context_id: { type: 'text', default: '' },
|
|
25
|
+
creator_id: { type: 'text', default: '' },
|
|
26
|
+
creator_name: { type: 'text', default: '' },
|
|
27
|
+
hit_count: { type: 'integer', default: 0 },
|
|
28
|
+
created_at: { type: 'text', default: '' },
|
|
29
|
+
updated_at: { type: 'text', default: '' },
|
|
30
|
+
});
|
|
31
|
+
db.define(STATS_TABLE, {
|
|
32
|
+
user_id: { type: 'text', nullable: false },
|
|
33
|
+
user_name: { type: 'text', default: '' },
|
|
34
|
+
group_id: { type: 'text', default: '' },
|
|
35
|
+
date: { type: 'text', nullable: false },
|
|
36
|
+
count: { type: 'integer', default: 0 },
|
|
37
|
+
updated_at: { type: 'text', default: '' },
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=tables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tables.js","sourceRoot":"","sources":["../src/tables.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EACL,aAAa,EACb,WAAW,EACX,WAAW,GACZ,MAAM,mBAAmB,CAAC;AAE3B,MAAM,UAAU,sBAAsB,CACpC,EAAuE;IAEvE,EAAE,CAAC,MAAM,CAAC,aAAa,EAAE;QACvB,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;QAC1C,SAAS,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;QACxC,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;QACvC,cAAc,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;QAC/C,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;QACvC,UAAU,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;QAC3C,YAAY,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;QAC3C,YAAY,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE;QACjD,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;QACzC,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;QACzC,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;KAC1C,CAAC,CAAC;IACH,EAAE,CAAC,MAAM,CAAC,WAAW,EAAE;QACrB,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;QAC3C,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;QACzC,QAAQ,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;QACzC,YAAY,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE;QACjD,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;QACzC,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;QACzC,YAAY,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;QAC3C,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;QAC1C,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;QACzC,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;KAC1C,CAAC,CAAC;IACH,EAAE,CAAC,MAAM,CAAC,WAAW,EAAE;QACrB,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;QAC1C,SAAS,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;QACxC,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;QACvC,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;QACvC,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE;QACtC,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;KAC1C,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { GroupSuiteConfig } from './config.js';
|
|
2
|
+
import type { GroupSuiteRuntime } from './runtime-state.js';
|
|
3
|
+
export declare const TEACH_USAGE_HINT = "\u683C\u5F0F\uFF1Ateach \u5173\u952E\u8BCD \u56DE\u7B54\uFF08\u56DE\u7B54\u53EF\u542B\u7A7A\u683C\uFF09\uFF0C\u6216 teach \u95EE\u9898|\u7B54\u6848";
|
|
4
|
+
export declare function parseTeachPair(raw: string): {
|
|
5
|
+
question: string;
|
|
6
|
+
answer: string;
|
|
7
|
+
} | null;
|
|
8
|
+
type MessageInput = {
|
|
9
|
+
sender?: string;
|
|
10
|
+
target?: string;
|
|
11
|
+
content?: unknown;
|
|
12
|
+
metadata?: Readonly<Record<string, unknown>>;
|
|
13
|
+
};
|
|
14
|
+
export declare function teachAdd(input: MessageInput, cfg: GroupSuiteConfig, payload: string, regex?: boolean, runtime?: GroupSuiteRuntime): Promise<string>;
|
|
15
|
+
export declare function teachList(input: MessageInput, cfg: GroupSuiteConfig, page?: number, runtime?: GroupSuiteRuntime): Promise<string>;
|
|
16
|
+
export declare function teachForget(input: MessageInput, questionRaw: string, runtime?: GroupSuiteRuntime): Promise<string>;
|
|
17
|
+
/** Try teach auto-reply; returns reply text or null. */
|
|
18
|
+
export declare function tryTeachReply(input: MessageInput, cfg: GroupSuiteConfig, runtime?: GroupSuiteRuntime): Promise<string | null>;
|
|
19
|
+
/** Test helper */
|
|
20
|
+
export declare function resetTeachCooldown(): void;
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=teach-lib.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"teach-lib.d.ts","sourceRoot":"","sources":["../src/teach-lib.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAOpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAI5D,eAAO,MAAM,gBAAgB,wJACY,CAAC;AAa1C,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAevF;AAkCD,KAAK,YAAY,GAAG;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAC9C,CAAC;AAiCF,wBAAsB,QAAQ,CAC5B,KAAK,EAAE,YAAY,EACnB,GAAG,EAAE,gBAAgB,EACrB,OAAO,EAAE,MAAM,EACf,KAAK,UAAQ,EACb,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAqEjB;AAED,wBAAsB,SAAS,CAC7B,KAAK,EAAE,YAAY,EACnB,GAAG,EAAE,gBAAgB,EACrB,IAAI,SAAI,EACR,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAsBjB;AAED,wBAAsB,WAAW,CAC/B,KAAK,EAAE,YAAY,EACnB,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAqBjB;AAED,wDAAwD;AACxD,wBAAsB,aAAa,CACjC,KAAK,EAAE,YAAY,EACnB,GAAG,EAAE,gBAAgB,EACrB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA6CxB;AAED,kBAAkB;AAClB,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC"}
|
package/lib/teach-lib.js
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { getTeachModel } from './db-store.js';
|
|
2
|
+
import { resolveContextKey, resolveSender, ts, } from './shared-runtime.js';
|
|
3
|
+
const cooldownMap = new Map();
|
|
4
|
+
export const TEACH_USAGE_HINT = '格式:teach 关键词 回答(回答可含空格),或 teach 问题|答案';
|
|
5
|
+
function isSafeRegex(pattern) {
|
|
6
|
+
if (pattern.length > 200)
|
|
7
|
+
return false;
|
|
8
|
+
if (/(\+|\*|\{)\)?(\+|\*|\{)/.test(pattern))
|
|
9
|
+
return false;
|
|
10
|
+
if (/\([^)]*(\+|\*)[^)]*(\+|\*)[^)]*\)[+*]/.test(pattern))
|
|
11
|
+
return false;
|
|
12
|
+
const altGroups = pattern.match(/\([^)]*\|[^)]*\)/g) || [];
|
|
13
|
+
for (const g of altGroups) {
|
|
14
|
+
if ((g.match(/\|/g) || []).length > 10)
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
export function parseTeachPair(raw) {
|
|
20
|
+
if (!raw)
|
|
21
|
+
return null;
|
|
22
|
+
const pipe = raw.indexOf('|');
|
|
23
|
+
if (pipe >= 0) {
|
|
24
|
+
const question = raw.slice(0, pipe).trim();
|
|
25
|
+
const answer = raw.slice(pipe + 1).trim();
|
|
26
|
+
if (question && answer)
|
|
27
|
+
return { question, answer };
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
const lastSpace = raw.lastIndexOf(' ');
|
|
31
|
+
if (lastSpace < 0)
|
|
32
|
+
return null;
|
|
33
|
+
const question = raw.slice(0, lastSpace).trim();
|
|
34
|
+
const answer = raw.slice(lastSpace + 1).trim();
|
|
35
|
+
if (!question || !answer)
|
|
36
|
+
return null;
|
|
37
|
+
return { question, answer };
|
|
38
|
+
}
|
|
39
|
+
function processAnswer(answer, sender, match) {
|
|
40
|
+
let result = answer;
|
|
41
|
+
result = result.replace(/\{sender\}/g, sender.name || '你');
|
|
42
|
+
result = result.replace(/\{sender\.id\}/g, sender.id || '');
|
|
43
|
+
result = result.replace(/\{time\}/g, new Date().toLocaleTimeString('zh-CN'));
|
|
44
|
+
result = result.replace(/\{date\}/g, new Date().toLocaleDateString('zh-CN'));
|
|
45
|
+
if (match) {
|
|
46
|
+
for (let i = 1; i < match.length; i++) {
|
|
47
|
+
result = result.replace(new RegExp(`\\$${i}`, 'g'), match[i] || '');
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return result;
|
|
51
|
+
}
|
|
52
|
+
function qaWhereKey(row) {
|
|
53
|
+
return {
|
|
54
|
+
question: row.question,
|
|
55
|
+
context_type: row.context_type,
|
|
56
|
+
context_id: row.context_id,
|
|
57
|
+
is_regex: row.is_regex ? 1 : 0,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
async function findMatch(content, ctxType, ctxId, cfg, runtime) {
|
|
61
|
+
const QA = getTeachModel(runtime?.db);
|
|
62
|
+
if (!QA)
|
|
63
|
+
return null;
|
|
64
|
+
const allItems = (await QA.select());
|
|
65
|
+
const candidates = allItems.filter((item) => item.context_type === 'global' ||
|
|
66
|
+
(item.context_type === ctxType && item.context_id === ctxId));
|
|
67
|
+
for (const item of candidates) {
|
|
68
|
+
if (!item.is_regex && item.question === content)
|
|
69
|
+
return item;
|
|
70
|
+
}
|
|
71
|
+
if (cfg.teachAllowRegex) {
|
|
72
|
+
for (const item of candidates) {
|
|
73
|
+
if (!item.is_regex)
|
|
74
|
+
continue;
|
|
75
|
+
try {
|
|
76
|
+
if (new RegExp(String(item.question), 'i').test(content))
|
|
77
|
+
return item;
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
export async function teachAdd(input, cfg, payload, regex = false, runtime) {
|
|
87
|
+
const QA = getTeachModel(runtime?.db);
|
|
88
|
+
if (!QA)
|
|
89
|
+
return '问答数据库尚未就绪,请稍后重试';
|
|
90
|
+
if (regex && !cfg.teachAllowRegex)
|
|
91
|
+
return '管理员已禁用正则问答';
|
|
92
|
+
const parsed = parseTeachPair(payload.trim());
|
|
93
|
+
if (!parsed) {
|
|
94
|
+
return regex
|
|
95
|
+
? '格式:teach-regex 正则 回答,或 teach-regex 正则|回答'
|
|
96
|
+
: TEACH_USAGE_HINT;
|
|
97
|
+
}
|
|
98
|
+
const { question, answer } = parsed;
|
|
99
|
+
if (regex) {
|
|
100
|
+
try {
|
|
101
|
+
new RegExp(question, 'i');
|
|
102
|
+
}
|
|
103
|
+
catch (e) {
|
|
104
|
+
return `正则表达式不合法: ${e.message}`;
|
|
105
|
+
}
|
|
106
|
+
if (!isSafeRegex(question))
|
|
107
|
+
return '该正则可能导致性能问题,请简化';
|
|
108
|
+
}
|
|
109
|
+
const { type: ctxType, id: ctxId } = resolveContextKey(input);
|
|
110
|
+
const sender = resolveSender(input);
|
|
111
|
+
if (ctxType === 'group') {
|
|
112
|
+
const existing = (await QA.select().where({
|
|
113
|
+
context_type: ctxType,
|
|
114
|
+
context_id: ctxId,
|
|
115
|
+
}));
|
|
116
|
+
if (existing.length >= cfg.teachMaxPerGroup) {
|
|
117
|
+
return `该群问答数已达上限 (${cfg.teachMaxPerGroup})`;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
const duplicate = (await QA.select().where({
|
|
121
|
+
question,
|
|
122
|
+
context_type: ctxType,
|
|
123
|
+
context_id: ctxId,
|
|
124
|
+
}));
|
|
125
|
+
if (duplicate.length > 0 && !regex) {
|
|
126
|
+
await QA.update({ answer, updated_at: ts() }).where(qaWhereKey(duplicate[0]));
|
|
127
|
+
return `已更新问答:「${question}」→「${answer}」`;
|
|
128
|
+
}
|
|
129
|
+
await QA.insert({
|
|
130
|
+
question,
|
|
131
|
+
answer,
|
|
132
|
+
is_regex: regex ? 1 : 0,
|
|
133
|
+
context_type: ctxType,
|
|
134
|
+
context_id: ctxId,
|
|
135
|
+
creator_id: sender.id,
|
|
136
|
+
creator_name: sender.name,
|
|
137
|
+
hit_count: 0,
|
|
138
|
+
created_at: ts(),
|
|
139
|
+
updated_at: ts(),
|
|
140
|
+
});
|
|
141
|
+
return regex
|
|
142
|
+
? `学会了!匹配 /${question}/ 的消息我会回复「${answer}」`
|
|
143
|
+
: `学会了!发送「${question}」我会回复「${answer}」`;
|
|
144
|
+
}
|
|
145
|
+
export async function teachList(input, cfg, page = 1, runtime) {
|
|
146
|
+
const QA = getTeachModel(runtime?.db);
|
|
147
|
+
if (!QA)
|
|
148
|
+
return '问答数据库尚未就绪';
|
|
149
|
+
const safePage = Math.max(1, page);
|
|
150
|
+
const { type: ctxType, id: ctxId } = resolveContextKey(input);
|
|
151
|
+
const allItems = (await QA.select().where(ctxType === 'global'
|
|
152
|
+
? { context_type: 'global' }
|
|
153
|
+
: { context_type: ctxType, context_id: ctxId }));
|
|
154
|
+
if (allItems.length === 0)
|
|
155
|
+
return '还没有教过任何问答哦~';
|
|
156
|
+
const totalPages = Math.ceil(allItems.length / cfg.teachPageSize);
|
|
157
|
+
const pageNum = Math.min(safePage, totalPages);
|
|
158
|
+
const start = (pageNum - 1) * cfg.teachPageSize;
|
|
159
|
+
const pageItems = allItems.slice(start, start + cfg.teachPageSize);
|
|
160
|
+
const lines = pageItems.map((item, i) => {
|
|
161
|
+
const prefix = item.is_regex ? '[正则]' : '[精确]';
|
|
162
|
+
const q = item.is_regex ? `/${item.question}/` : item.question;
|
|
163
|
+
return `${start + i + 1}. ${prefix} ${q} → ${item.answer}`;
|
|
164
|
+
});
|
|
165
|
+
const header = ctxType === 'global' ? '全局问答列表' : '本群问答列表';
|
|
166
|
+
return `${header}\n${lines.join('\n')}\n第 ${pageNum}/${totalPages} 页 · 共 ${allItems.length} 条`;
|
|
167
|
+
}
|
|
168
|
+
export async function teachForget(input, questionRaw, runtime) {
|
|
169
|
+
const QA = getTeachModel(runtime?.db);
|
|
170
|
+
if (!QA)
|
|
171
|
+
return '问答数据库尚未就绪';
|
|
172
|
+
const question = questionRaw.trim();
|
|
173
|
+
if (!question)
|
|
174
|
+
return '请提供要删除的问题';
|
|
175
|
+
const { type: ctxType, id: ctxId } = resolveContextKey(input);
|
|
176
|
+
const items = (await QA.select().where({
|
|
177
|
+
question,
|
|
178
|
+
context_type: ctxType,
|
|
179
|
+
context_id: ctxId,
|
|
180
|
+
}));
|
|
181
|
+
if (items.length === 0)
|
|
182
|
+
return `没有找到问题「${question}」`;
|
|
183
|
+
await QA.delete().where(qaWhereKey(items[0]));
|
|
184
|
+
return `已忘记「${question}」的回答`;
|
|
185
|
+
}
|
|
186
|
+
/** Try teach auto-reply; returns reply text or null. */
|
|
187
|
+
export async function tryTeachReply(input, cfg, runtime) {
|
|
188
|
+
const content = typeof input.content === 'string' ? input.content.trim() : '';
|
|
189
|
+
if (!content)
|
|
190
|
+
return null;
|
|
191
|
+
const { type: ctxType, id: ctxId } = resolveContextKey(input);
|
|
192
|
+
const matched = await findMatch(content, ctxType, ctxId, cfg, runtime);
|
|
193
|
+
if (!matched)
|
|
194
|
+
return null;
|
|
195
|
+
const cooldownKey = `${matched.question}:${ctxType}:${ctxId}:${matched.is_regex ?? 0}`;
|
|
196
|
+
const cooldowns = runtime?.teachCooldowns ?? cooldownMap;
|
|
197
|
+
const last = cooldowns.get(cooldownKey);
|
|
198
|
+
if (last && Date.now() - last < cfg.teachCooldownMs)
|
|
199
|
+
return null;
|
|
200
|
+
cooldowns.set(cooldownKey, Date.now());
|
|
201
|
+
const QA = getTeachModel(runtime?.db);
|
|
202
|
+
if (QA) {
|
|
203
|
+
try {
|
|
204
|
+
await QA.update({
|
|
205
|
+
hit_count: Number(matched.hit_count || 0) + 1,
|
|
206
|
+
updated_at: ts(),
|
|
207
|
+
}).where(qaWhereKey(matched));
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
/* ignore */
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
const sender = resolveSender(input);
|
|
214
|
+
let answer = String(matched.answer ?? '');
|
|
215
|
+
if (matched.is_regex) {
|
|
216
|
+
try {
|
|
217
|
+
const m = content.match(new RegExp(String(matched.question), 'i'));
|
|
218
|
+
answer = processAnswer(answer, sender, m || undefined);
|
|
219
|
+
}
|
|
220
|
+
catch {
|
|
221
|
+
/* ignore */
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
answer = processAnswer(answer, sender);
|
|
226
|
+
}
|
|
227
|
+
return answer;
|
|
228
|
+
}
|
|
229
|
+
/** Test helper */
|
|
230
|
+
export function resetTeachCooldown() {
|
|
231
|
+
cooldownMap.clear();
|
|
232
|
+
}
|
|
233
|
+
//# sourceMappingURL=teach-lib.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"teach-lib.js","sourceRoot":"","sources":["../src/teach-lib.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { defineMiddleware } from '@zhin.js/middleware';
|
|
2
|
+
import type { Message } from '@zhin.js/core/runtime';
|
|
3
|
+
import { resolveGroupSuiteConfig, type GroupSuiteConfig } from '../src/config.js';
|
|
4
|
+
import { matchKeyword } from '../src/keyword-store.js';
|
|
5
|
+
import { resolveGroupSuiteRuntime } from '../src/runtime-state.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Keyword auto-reply (enabled via config.keywordReply).
|
|
9
|
+
* Uses Runtime Message.content / metadata (legacy used $raw / $channel).
|
|
10
|
+
*/
|
|
11
|
+
export default defineMiddleware<Message, GroupSuiteConfig>({
|
|
12
|
+
target: 'inbound',
|
|
13
|
+
async handle(context, next) {
|
|
14
|
+
const config = resolveGroupSuiteConfig(context.config);
|
|
15
|
+
if (!config.keywordReply) {
|
|
16
|
+
await next();
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const meta = context.input.metadata ?? {};
|
|
20
|
+
const channelType = String(meta.type ?? meta.channelType ?? '');
|
|
21
|
+
if (channelType === 'private') {
|
|
22
|
+
await next();
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const text = typeof context.input.content === 'string' ? context.input.content.trim() : '';
|
|
26
|
+
if (!text) {
|
|
27
|
+
await next();
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const reply = matchKeyword(text, resolveGroupSuiteRuntime(context)?.keywords);
|
|
31
|
+
if (reply) {
|
|
32
|
+
await context.input.$reply(reply);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
await next();
|
|
36
|
+
},
|
|
37
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { defineMiddleware } from '@zhin.js/middleware';
|
|
2
|
+
import type { Message } from '@zhin.js/core/runtime';
|
|
3
|
+
import type { GroupSuiteConfig } from '../src/config.js';
|
|
4
|
+
import { recordMessage } from '../src/stats-lib.js';
|
|
5
|
+
import { resolveGroupSuiteRuntime } from '../src/runtime-state.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Buffer inbound messages into in-memory message_stats (flushed on query).
|
|
9
|
+
* Skips command messages (legacy used `isActionMessage` to skip interactive
|
|
10
|
+
* action/command messages; the Runtime pipeline represents commands as
|
|
11
|
+
* text starting with the dispatcher prefix '/').
|
|
12
|
+
*/
|
|
13
|
+
export default defineMiddleware<Message, GroupSuiteConfig>({
|
|
14
|
+
target: 'inbound',
|
|
15
|
+
async handle(context, next) {
|
|
16
|
+
const content = typeof context.input.content === 'string' ? context.input.content : '';
|
|
17
|
+
if (!content.startsWith('/')) {
|
|
18
|
+
recordMessage(context.input, resolveGroupSuiteRuntime(context));
|
|
19
|
+
}
|
|
20
|
+
await next();
|
|
21
|
+
},
|
|
22
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { defineMiddleware } from '@zhin.js/middleware';
|
|
2
|
+
import type { Message } from '@zhin.js/core/runtime';
|
|
3
|
+
import { resolveGroupSuiteConfig, type GroupSuiteConfig } from '../src/config.js';
|
|
4
|
+
import { tryTeachReply } from '../src/teach-lib.js';
|
|
5
|
+
import { resolveGroupSuiteRuntime } from '../src/runtime-state.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Teach Q&A auto-reply (exact / optional regex).
|
|
9
|
+
* Uses Runtime Message.content / metadata.
|
|
10
|
+
*/
|
|
11
|
+
export default defineMiddleware<Message, GroupSuiteConfig>({
|
|
12
|
+
target: 'inbound',
|
|
13
|
+
async handle(context, next) {
|
|
14
|
+
const config = resolveGroupSuiteConfig(context.config);
|
|
15
|
+
const reply = await tryTeachReply(context.input, config, resolveGroupSuiteRuntime(context));
|
|
16
|
+
if (reply) {
|
|
17
|
+
await context.input.$reply(reply);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
await next();
|
|
21
|
+
},
|
|
22
|
+
});
|