dsh-qq-moony 0.9.0 → 0.9.2
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/CHANGELOG.md +9 -0
- package/client.js +3 -3
- package/index.js +63 -12
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
|
+
## 0.9.2 — 2026-10-25(本地,未发布)
|
|
2
|
+
|
|
3
|
+
- **新增 `qq_qzone_history`**:发过的说说记在本地账本 `<DSH_HOME>/qq-moony/qzone.jsonl`(时间 / tid / 正文),可以按条数翻。不读空间接口。
|
|
4
|
+
- 为什么只记账不读空间:NapCat 只提供「发说说 / 删说说」两个接口,读动态、点赞、评论一律"不支持的 Api"。要真读,得另扫码登空间网页版,那条通道脆且容易触风控。
|
|
1
5
|
# CHANGELOG
|
|
2
6
|
|
|
7
|
+
## 0.9.1 — 2026-10-25
|
|
8
|
+
|
|
9
|
+
- **每小时 / 每天的额度一律按「轮」算**,不再看拆条开关。一轮 = 一次回复(可能拆成几条),只占一份额度。
|
|
10
|
+
- 每分钟上限仍然按真实条数算,不受影响——它是防封兜底。
|
|
11
|
+
- 设置页文案同步:「每小时上限」→「一小时内最多回几轮」;状态栏改成"今天回了 N 轮(M 条)"。
|
|
3
12
|
## 0.9.0 — 2026-10-25
|
|
4
13
|
|
|
5
14
|
一句一句地说,额度按"轮"算。
|
package/client.js
CHANGED
|
@@ -206,7 +206,7 @@ window.__ModuleLoader__.load({
|
|
|
206
206
|
'div',
|
|
207
207
|
{ style: 说明 },
|
|
208
208
|
状态.online
|
|
209
|
-
?
|
|
209
|
+
? `今天回了 ${状态.roundsToday ?? 0} 轮(${状态.sentToday ?? 0} 条),这一小时 ${状态.roundsThisHour ?? 0} 轮(上限 ${状态.perDay}/天、${状态.perHour}/时)`
|
|
210
210
|
: '检查 NapCat 有没有启动、3000 端口通不通、token 对不对',
|
|
211
211
|
),
|
|
212
212
|
),
|
|
@@ -302,7 +302,7 @@ window.__ModuleLoader__.load({
|
|
|
302
302
|
'div',
|
|
303
303
|
null,
|
|
304
304
|
h('div', { style: 标题 }, '每小时上限'),
|
|
305
|
-
h('div', { style: 说明 }, '
|
|
305
|
+
h('div', { style: 说明 }, '一小时内最多回几轮(1–200),到顶直接拒发'),
|
|
306
306
|
),
|
|
307
307
|
h('input', {
|
|
308
308
|
type: 'number',
|
|
@@ -320,7 +320,7 @@ window.__ModuleLoader__.load({
|
|
|
320
320
|
'div',
|
|
321
321
|
null,
|
|
322
322
|
h('div', { style: 标题 }, '每天上限'),
|
|
323
|
-
h('div', { style: 说明 }, '
|
|
323
|
+
h('div', { style: 说明 }, '一天内最多回几轮(1–1000),按自然日算'),
|
|
324
324
|
),
|
|
325
325
|
h('input', {
|
|
326
326
|
type: 'number',
|
package/index.js
CHANGED
|
@@ -165,7 +165,8 @@ export function apply(ctx, 配置) {
|
|
|
165
165
|
const c = { ...默认配置, ...(配置 ?? {}), ...读取本地配置() };
|
|
166
166
|
const 账本 = join(家目录(), 'sent.log');
|
|
167
167
|
const 收件箱 = join(家目录(), 'inbox.jsonl');
|
|
168
|
-
const 轮次账 = join(家目录(), 'rounds.log');
|
|
168
|
+
const 轮次账 = join(家目录(), 'rounds.log');
|
|
169
|
+
const 说说账 = join(家目录(), 'qzone.jsonl');
|
|
169
170
|
|
|
170
171
|
ctx.logger?.info?.(`qq-moony: 接到 ${c.baseUrl}(限额 ${c.perHour}/时、${c.perDay}/天)`);
|
|
171
172
|
|
|
@@ -808,7 +809,9 @@ export function apply(ctx, 配置) {
|
|
|
808
809
|
stickerCount: 读表情库().length,
|
|
809
810
|
perHour: Number(c.perHour ?? 20),
|
|
810
811
|
perDay: Number(c.perDay ?? 60),
|
|
811
|
-
sentToday: 记录.filter((t) => 现在 - t < 86400).length,
|
|
812
|
+
sentToday: 记录.filter((t) => 现在 - t < 86400).length,
|
|
813
|
+
roundsToday: 读账(轮次账).filter((t) => 现在 - t < 86400).length,
|
|
814
|
+
roundsThisHour: 读账(轮次账).filter((t) => 现在 - t < 3600).length,
|
|
812
815
|
sentThisHour: 记录.filter((t) => 现在 - t < 3600).length,
|
|
813
816
|
});
|
|
814
817
|
return;
|
|
@@ -924,17 +927,12 @@ export function apply(ctx, 配置) {
|
|
|
924
927
|
if (一分钟 >= 上限分钟) return `这一分钟已经发了 ${一分钟} 条,喘口气再说`;
|
|
925
928
|
const 一小时 = 记录.filter((t) => 现在 - t < 3600).length;
|
|
926
929
|
const 一天 = 记录.filter((t) => 现在 - t < 86400).length;
|
|
927
|
-
//
|
|
930
|
+
// 小时/天的额度一律按「轮」算;每分钟的硬上限永远按「条」算
|
|
928
931
|
const 轮记录 = 读账(轮次账);
|
|
929
932
|
const 轮小时 = 轮记录.filter((t) => 现在 - t < 3600).length;
|
|
930
933
|
const 轮一天 = 轮记录.filter((t) => 现在 - t < 86400).length;
|
|
931
|
-
if (c.
|
|
932
|
-
|
|
933
|
-
if (轮一天 >= c.perDay) return `今天已经回了 ${轮一天} 轮,到顶了,明天再聊`;
|
|
934
|
-
return '';
|
|
935
|
-
}
|
|
936
|
-
if (一小时 >= c.perHour) return `这一小时已经发了 ${一小时} 条,到顶了,等会儿再说`;
|
|
937
|
-
if (一天 >= c.perDay) return `今天已经发了 ${一天} 条,到顶了,明天再聊`;
|
|
934
|
+
if (轮小时 >= c.perHour) return `这一小时已经回了 ${轮小时} 轮,到顶了,等会儿再说`;
|
|
935
|
+
if (轮一天 >= c.perDay) return `今天已经回了 ${轮一天} 轮,到顶了,明天再聊`;
|
|
938
936
|
return '';
|
|
939
937
|
}
|
|
940
938
|
|
|
@@ -995,7 +993,9 @@ export function apply(ctx, 配置) {
|
|
|
995
993
|
ok: true,
|
|
996
994
|
uin: Number(r.data?.user_id ?? 0),
|
|
997
995
|
nickname: String(r.data?.nickname ?? ''),
|
|
998
|
-
sentToday: 记录.filter((t) => 现在 - t < 86400).length,
|
|
996
|
+
sentToday: 记录.filter((t) => 现在 - t < 86400).length,
|
|
997
|
+
roundsToday: 读账(轮次账).filter((t) => 现在 - t < 86400).length,
|
|
998
|
+
roundsThisHour: 读账(轮次账).filter((t) => 现在 - t < 3600).length,
|
|
999
999
|
sentThisHour: 记录.filter((t) => 现在 - t < 3600).length,
|
|
1000
1000
|
};
|
|
1001
1001
|
} catch (e) {
|
|
@@ -1253,6 +1253,50 @@ export function apply(ctx, 配置) {
|
|
|
1253
1253
|
}),
|
|
1254
1254
|
);
|
|
1255
1255
|
|
|
1256
|
+
// ---------- qq_qzone_history ----------
|
|
1257
|
+
ctx.effect(() =>
|
|
1258
|
+
ctx.tools.register({
|
|
1259
|
+
name: 'qq_qzone_history',
|
|
1260
|
+
name_display: '说说账本',
|
|
1261
|
+
description:
|
|
1262
|
+
'看自己发过哪些说说(本地账本,不读空间接口)。返回时间、内容和条数。',
|
|
1263
|
+
parameters: {
|
|
1264
|
+
type: 'object',
|
|
1265
|
+
properties: {
|
|
1266
|
+
count: { type: 'number', description: '要几条,默认 10' },
|
|
1267
|
+
},
|
|
1268
|
+
additionalProperties: false,
|
|
1269
|
+
},
|
|
1270
|
+
output: 工具输出({ lines: { type: 'array', items: { type: 'string' } } }, (v) => {
|
|
1271
|
+
if (!v.ok) return `读不到:${v.reason ?? '未知原因'}`;
|
|
1272
|
+
if (!v.lines || v.lines.length === 0) return '这个账本还是空的——还没发过说说。';
|
|
1273
|
+
return v.lines.join('\n');
|
|
1274
|
+
}),
|
|
1275
|
+
async execute(args) {
|
|
1276
|
+
const 数量 = Math.min(Math.max(Number(args?.count ?? 10), 1), 50);
|
|
1277
|
+
try {
|
|
1278
|
+
if (!existsSync(说说账)) return { ok: true, lines: [] };
|
|
1279
|
+
const 行 = readFileSync(说说账, 'utf8')
|
|
1280
|
+
.split('\n')
|
|
1281
|
+
.filter(Boolean)
|
|
1282
|
+
.slice(-数量)
|
|
1283
|
+
.reverse()
|
|
1284
|
+
.map((s) => {
|
|
1285
|
+
try {
|
|
1286
|
+
const x = JSON.parse(s);
|
|
1287
|
+
return `${x.t.slice(0, 16).replace('T', ' ')}|${x.content.replace(/\n/g, ' ')}`;
|
|
1288
|
+
} catch {
|
|
1289
|
+
return s;
|
|
1290
|
+
}
|
|
1291
|
+
});
|
|
1292
|
+
return { ok: true, lines: 行 };
|
|
1293
|
+
} catch (e) {
|
|
1294
|
+
return { ok: false, lines: [], reason: e.message };
|
|
1295
|
+
}
|
|
1296
|
+
},
|
|
1297
|
+
}),
|
|
1298
|
+
);
|
|
1299
|
+
|
|
1256
1300
|
// ---------- qq_qzone ----------
|
|
1257
1301
|
ctx.effect(() =>
|
|
1258
1302
|
ctx.tools.register({
|
|
@@ -1276,7 +1320,14 @@ export function apply(ctx, 配置) {
|
|
|
1276
1320
|
try {
|
|
1277
1321
|
const r = await 调('send_qzone_msg', { content: 正文 });
|
|
1278
1322
|
记账(账本, 'qzone', 正文);
|
|
1279
|
-
|
|
1323
|
+
const tid = String(r.data?.tid ?? '');
|
|
1324
|
+
try {
|
|
1325
|
+
mkdirSync(家目录(), { recursive: true });
|
|
1326
|
+
appendFileSync(说说账, JSON.stringify({ t: new Date().toISOString(), tid, content: 正文 }) + '\n', 'utf8');
|
|
1327
|
+
} catch {
|
|
1328
|
+
/* 记账失败不影响发出去 */
|
|
1329
|
+
}
|
|
1330
|
+
return { ok: true, tid };
|
|
1280
1331
|
} catch (e) {
|
|
1281
1332
|
return { ok: false, tid: '', reason: e.message };
|
|
1282
1333
|
}
|