koishi-plugin-wordpress-notifier 2.5.5 → 2.5.9
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 +60 -19
- package/lib/index.js +162 -106
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -339,26 +339,67 @@ npm install
|
|
|
339
339
|
|
|
340
340
|
## 版本历史
|
|
341
341
|
|
|
342
|
-
### 2.
|
|
343
|
-
|
|
344
|
-
-
|
|
345
|
-
- ✅
|
|
346
|
-
- ✅
|
|
347
|
-
- ✅
|
|
348
|
-
- ✅
|
|
349
|
-
- ✅
|
|
350
|
-
- ✅
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
-
|
|
356
|
-
- ✅
|
|
357
|
-
- ✅
|
|
358
|
-
|
|
359
|
-
|
|
342
|
+
### 2.5.9 (2026-01-25)
|
|
343
|
+
|
|
344
|
+
- 🐛 彻底修复11255错误,严格遵循QQ接口规范
|
|
345
|
+
- ✅ 移除所有非必要特殊符号,只保留1个极简表情
|
|
346
|
+
- ✅ 自定义时间格式:年-月-日 时:分,避免本地化特殊字符
|
|
347
|
+
- ✅ 使用encodeURI强制编码WordPress链接
|
|
348
|
+
- ✅ 双级长度控制:标题60字符,整体300字符
|
|
349
|
+
- ✅ 严格限制换行:仅2次换行,无连续或尾部换行
|
|
350
|
+
- ✅ 强化清洗规则:标准化所有空白符为单个半角空格
|
|
351
|
+
|
|
352
|
+
### 2.5.8 (2026-01-25)
|
|
353
|
+
|
|
354
|
+
- 🐛 修复推送失败的11255错误
|
|
355
|
+
- ✅ 修正消息发送逻辑,确保正确处理单个消息段
|
|
356
|
+
- ✅ 统一变量命名,将segments改为message
|
|
357
|
+
- ✅ 确保bot.sendMessage接收正确的消息类型
|
|
358
|
+
|
|
359
|
+
### 2.5.7 (2026-01-25)
|
|
360
|
+
|
|
361
|
+
- 🔧 适配QQ官方bot,优化bot获取逻辑
|
|
362
|
+
- ✅ 优先选择QQ官方bot(platform === 'qq')
|
|
363
|
+
- ✅ 优化消息格式,确保兼容QQ官方bot要求
|
|
364
|
+
- ✅ 调整消息长度限制,更严格控制在350字符内
|
|
365
|
+
- ✅ 简化消息格式,使用更兼容的分隔符
|
|
366
|
+
- ✅ 确保@全体成员格式符合QQ官方bot规范
|
|
367
|
+
|
|
368
|
+
### 2.5.6 (2026-01-25)
|
|
369
|
+
|
|
370
|
+
- 🔧 修复11255错误,重构消息构造函数
|
|
371
|
+
- ✅ 移除多段消息拼接,改为单段纯文本
|
|
372
|
+
- ✅ 强制截断长文本,控制消息长度
|
|
373
|
+
- ✅ 标准化特殊符号,使用|分隔关键信息
|
|
374
|
+
- ✅ 直接返回h.text()封装的单段消息
|
|
375
|
+
|
|
376
|
+
### 2.5.5 (2026-01-25)
|
|
377
|
+
|
|
378
|
+
- 🔧 修复wordpress.status命令Bad Request错误
|
|
379
|
+
- ✅ 为所有命令添加h.text()封装
|
|
380
|
+
- ✅ 精简字段描述,缩短消息长度
|
|
381
|
+
- ✅ 添加消息长度验证
|
|
382
|
+
- ✅ 优化消息格式,确保兼容Satorijs QQ适配器
|
|
383
|
+
|
|
384
|
+
### 2.3.0 (2026-01-25)
|
|
385
|
+
|
|
386
|
+
- 🔧 增强命令权限管理,限制敏感命令仅超级管理员可用
|
|
387
|
+
- ✅ 为`wordpress.set-url`命令添加超级管理员权限检查
|
|
388
|
+
- ✅ 为`wordpress.clean [days]`命令添加超级管理员权限检查
|
|
389
|
+
- ✅ 为`wordpress.toggle`命令添加超级管理员权限检查
|
|
390
|
+
- ✅ 为`wordpress.toggle-update`命令添加超级管理员权限检查
|
|
391
|
+
- ✅ 为`wordpress.toggle-user`命令添加超级管理员权限检查
|
|
392
|
+
- ✅ 为`wordpress.mention`命令添加超级管理员权限检查
|
|
393
|
+
- ✅ 添加了详细的日志记录,便于追踪非授权访问尝试
|
|
394
|
+
|
|
395
|
+
### 2.2.0 (2026-01-25)
|
|
396
|
+
|
|
397
|
+
- 🐛 修复重复推送问题,清理未使用的数据库表
|
|
398
|
+
- ✅ 移除了未使用的`wordpress_posts`表,统一使用`wordpress_group_pushes`表进行推送记录管理
|
|
399
|
+
- ✅ 修复了`wordpress.pushed`命令,使用`wordpress_group_pushes`表获取已推送记录
|
|
400
|
+
- ✅ 修复了`wordpress.clean`命令,移除了对`wordpress_posts`表的引用
|
|
401
|
+
- ✅ 增强了推送日志,添加了详细的调试信息,便于追踪推送流程
|
|
360
402
|
- ✅ 优化了`isGroupPushed`和`markGroupAsPushed`函数,添加了更多日志
|
|
361
|
-
|
|
362
403
|
### 2.1.0 (2026-01-25)
|
|
363
404
|
|
|
364
405
|
- 🔧 更新文档结构,将"如何获取用户注册日期"内容从版本历史移至常见问题部分
|
package/lib/index.js
CHANGED
|
@@ -240,41 +240,64 @@ function apply(ctx, config) {
|
|
|
240
240
|
}
|
|
241
241
|
}
|
|
242
242
|
function formatPostMessage(post, mention = false, isUpdate = false) {
|
|
243
|
-
//
|
|
243
|
+
// 强化清洗规则:标准化所有空白符为单个半角空格
|
|
244
244
|
const sanitizeText = (text) => {
|
|
245
245
|
return text
|
|
246
246
|
.replace(/<[^>]*>/g, '') // 移除所有 HTML 标签
|
|
247
247
|
.replace(/[\x00-\x1F\x7F]/g, '') // 移除控制字符
|
|
248
|
-
.replace(
|
|
248
|
+
.replace(/\s+/g, ' ') // 标准化所有空白符为单个半角空格
|
|
249
249
|
.trim();
|
|
250
250
|
};
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
251
|
+
// 严格截断标题为 60 字符
|
|
252
|
+
let title = sanitizeText(post.title.rendered);
|
|
253
|
+
if (title.length > 60) {
|
|
254
|
+
title = title.substring(0, 57) + '...';
|
|
255
|
+
}
|
|
256
|
+
// 自定义时间格式:年-月-日 时:分
|
|
257
|
+
const formatDate = (dateString) => {
|
|
258
|
+
const date = new Date(dateString);
|
|
259
|
+
const year = date.getFullYear();
|
|
260
|
+
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
261
|
+
const day = String(date.getDate()).padStart(2, '0');
|
|
262
|
+
const hours = String(date.getHours()).padStart(2, '0');
|
|
263
|
+
const minutes = String(date.getMinutes()).padStart(2, '0');
|
|
264
|
+
return `${year}-${month}-${day} ${hours}:${minutes}`;
|
|
265
|
+
};
|
|
266
|
+
const date = formatDate(post.date);
|
|
267
|
+
// 链接强制编码
|
|
268
|
+
const encodedLink = encodeURI(post.link);
|
|
269
|
+
// 构建 @全体成员 文本(适配 QQ 官方 bot 和其他适配器)
|
|
270
|
+
const atAllText = mention && config.mentionAll ? '@全体成员 ' : '';
|
|
271
|
+
// 只使用一个极简表情
|
|
272
|
+
const messageType = isUpdate ? '�' : '📝';
|
|
273
|
+
// 构建核心消息内容,严格控制格式
|
|
274
|
+
// 格式:[表情] [@全体] [时间] - [标题]
|
|
275
|
+
// [链接]
|
|
276
|
+
let message = `${messageType} ${atAllText}${date} - ${title}\n${encodedLink}`;
|
|
277
|
+
// 双级长度控制:整体消息兜底 300 字符
|
|
278
|
+
if (message.length > 300) {
|
|
279
|
+
message = message.substring(0, 297) + '...';
|
|
280
|
+
ctx.logger.warn(`文章消息超长,已截断,文章 ID: ${post.id}`);
|
|
281
|
+
}
|
|
282
|
+
// 返回单段文本,使用 h.text() 封装,确保兼容性
|
|
283
|
+
return koishi_1.h.text(message);
|
|
265
284
|
}
|
|
266
285
|
function formatUserMessage(user, mention = false) {
|
|
267
|
-
//
|
|
286
|
+
// 强化清洗规则:标准化所有空白符为单个半角空格
|
|
268
287
|
const sanitizeText = (text) => {
|
|
269
288
|
return text
|
|
270
289
|
.replace(/<[^>]*>/g, '') // 移除所有 HTML 标签
|
|
271
290
|
.replace(/[\x00-\x1F\x7F]/g, '') // 移除控制字符
|
|
272
|
-
.replace(
|
|
291
|
+
.replace(/\s+/g, ' ') // 标准化所有空白符为单个半角空格
|
|
273
292
|
.trim();
|
|
274
293
|
};
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
294
|
+
// 严格截断用户名为 50 字符
|
|
295
|
+
let username = sanitizeText(user.name);
|
|
296
|
+
if (username.length > 50) {
|
|
297
|
+
username = username.substring(0, 47) + '...';
|
|
298
|
+
}
|
|
299
|
+
// 安全处理日期,避免显示 "Invalid Date",自定义格式
|
|
300
|
+
let registerDate = '未知时间';
|
|
278
301
|
try {
|
|
279
302
|
ctx.logger.info(`正在处理用户 ${username} 的注册日期`);
|
|
280
303
|
// 尝试所有可能的日期字段,按优先级排序
|
|
@@ -301,54 +324,60 @@ function apply(ctx, config) {
|
|
|
301
324
|
ctx.logger.info(`用户 ${username} 的原始数据: ${JSON.stringify(user)}`);
|
|
302
325
|
}
|
|
303
326
|
if (dateStr) {
|
|
304
|
-
//
|
|
305
|
-
// 或者可能是其他格式,需要安全处理
|
|
327
|
+
// 尝试解析日期,使用自定义格式:年-月-日 时:分
|
|
306
328
|
const date = new Date(dateStr);
|
|
307
329
|
ctx.logger.info(`解析日期 ${dateStr} 结果: ${date.toString()}`);
|
|
308
330
|
if (!isNaN(date.getTime())) {
|
|
309
|
-
|
|
331
|
+
const year = date.getFullYear();
|
|
332
|
+
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
333
|
+
const day = String(date.getDate()).padStart(2, '0');
|
|
334
|
+
const hours = String(date.getHours()).padStart(2, '0');
|
|
335
|
+
const minutes = String(date.getMinutes()).padStart(2, '0');
|
|
336
|
+
registerDate = `${year}-${month}-${day} ${hours}:${minutes}`;
|
|
310
337
|
ctx.logger.info(`格式化后的日期: ${registerDate}`);
|
|
311
338
|
}
|
|
312
|
-
else {
|
|
313
|
-
// 如果日期解析失败,使用原始字符串或占位符
|
|
314
|
-
registerDate = dateStr || '未知时间';
|
|
315
|
-
ctx.logger.info(`日期解析失败,使用原始字符串: ${registerDate}`);
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
else {
|
|
319
|
-
// 如果日期字段不存在,使用占位符
|
|
320
|
-
registerDate = '未知时间';
|
|
321
|
-
ctx.logger.info(`未找到日期字段,使用默认值: ${registerDate}`);
|
|
322
339
|
}
|
|
323
340
|
}
|
|
324
341
|
catch (error) {
|
|
325
342
|
// 捕获任何异常,确保消息能正常生成
|
|
326
343
|
ctx.logger.error(`处理用户 ${username} 日期时出错: ${error}`);
|
|
327
|
-
registerDate = '未知时间';
|
|
328
|
-
}
|
|
329
|
-
const segments = [];
|
|
330
|
-
if (mention && config.mentionAll) {
|
|
331
|
-
segments.push(koishi_1.h.at('all'));
|
|
332
344
|
}
|
|
333
|
-
//
|
|
334
|
-
const
|
|
335
|
-
|
|
336
|
-
|
|
345
|
+
// 构建 @全体成员 文本(适配 QQ 官方 bot 和其他适配器)
|
|
346
|
+
const atAllText = mention && config.mentionAll ? '@全体成员 ' : '';
|
|
347
|
+
// 只使用一个极简表情
|
|
348
|
+
const messageType = '👤';
|
|
349
|
+
// 构建核心消息内容,严格控制格式和换行
|
|
350
|
+
// 格式:[表情] [@全体] 新用户注册 - [用户名]
|
|
351
|
+
// 注册时间: [时间]
|
|
352
|
+
let message = `${messageType} ${atAllText}新用户注册 - ${username}\n注册时间: ${registerDate}`;
|
|
353
|
+
// 严格控制整体消息长度为 300 字符
|
|
354
|
+
if (message.length > 300) {
|
|
355
|
+
message = message.substring(0, 297) + '...';
|
|
356
|
+
ctx.logger.warn(`用户消息超长,已截断,用户 ID: ${user.id}`);
|
|
357
|
+
}
|
|
358
|
+
// 返回单段文本,使用 h.text() 封装,确保兼容性
|
|
359
|
+
return koishi_1.h.text(message);
|
|
337
360
|
}
|
|
338
361
|
async function pushNewPosts() {
|
|
339
|
-
// 健壮获取 QQ Bot
|
|
362
|
+
// 健壮获取 QQ Bot 实例,兼容多种适配器,优先选择 QQ 官方 bot
|
|
340
363
|
const getValidBot = () => {
|
|
341
|
-
// 支持的 QQ
|
|
364
|
+
// 支持的 QQ 相关适配器列表,'qq' 为 QQ 官方 bot
|
|
342
365
|
const qqAdapters = ['qq', 'onebot', 'milky', 'satori'];
|
|
343
366
|
// ctx.bots 是对象,需转换为数组后遍历
|
|
344
367
|
const botList = Object.values(ctx.bots);
|
|
345
|
-
//
|
|
368
|
+
// 1. 优先选择 QQ 官方 bot(platform === 'qq')
|
|
369
|
+
for (const bot of botList) {
|
|
370
|
+
if (bot.platform === 'qq') {
|
|
371
|
+
return bot;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
// 2. 其次选择其他 QQ 适配器 Bot
|
|
346
375
|
for (const bot of botList) {
|
|
347
376
|
if (bot.platform && qqAdapters.includes(bot.platform)) {
|
|
348
377
|
return bot;
|
|
349
378
|
}
|
|
350
379
|
}
|
|
351
|
-
//
|
|
380
|
+
// 3. 最后选择任何可用 Bot
|
|
352
381
|
return botList[0];
|
|
353
382
|
};
|
|
354
383
|
const bot = getValidBot();
|
|
@@ -378,9 +407,9 @@ function apply(ctx, config) {
|
|
|
378
407
|
ctx.logger.info(`正在处理目标: ${target}`);
|
|
379
408
|
// 直接使用原始目标字符串,不进行数字转换,避免丢失平台前缀等信息
|
|
380
409
|
const stringTarget = target;
|
|
381
|
-
const
|
|
410
|
+
const message = formatPostMessage(post, true, false);
|
|
382
411
|
ctx.logger.info(`准备推送新文章到目标: ${stringTarget}`);
|
|
383
|
-
await bot.sendMessage(stringTarget,
|
|
412
|
+
await bot.sendMessage(stringTarget, message);
|
|
384
413
|
ctx.logger.info(`已推送新文章到 ${stringTarget}: ${post.title.rendered}`);
|
|
385
414
|
}
|
|
386
415
|
catch (error) {
|
|
@@ -413,9 +442,9 @@ function apply(ctx, config) {
|
|
|
413
442
|
try {
|
|
414
443
|
ctx.logger.info(`正在处理目标: ${target}`);
|
|
415
444
|
const stringTarget = target;
|
|
416
|
-
const
|
|
445
|
+
const message = formatPostMessage(post, true, true);
|
|
417
446
|
ctx.logger.info(`准备推送文章更新到目标: ${stringTarget}`);
|
|
418
|
-
await bot.sendMessage(stringTarget,
|
|
447
|
+
await bot.sendMessage(stringTarget, message);
|
|
419
448
|
ctx.logger.info(`已推送文章更新到 ${stringTarget}: ${post.title.rendered}`);
|
|
420
449
|
}
|
|
421
450
|
catch (error) {
|
|
@@ -441,9 +470,9 @@ function apply(ctx, config) {
|
|
|
441
470
|
ctx.logger.info(`正在处理目标: ${target}`);
|
|
442
471
|
// 直接使用原始目标字符串,与新文章推送逻辑保持一致
|
|
443
472
|
const stringTarget = target;
|
|
444
|
-
const
|
|
473
|
+
const message = formatUserMessage(user, true);
|
|
445
474
|
ctx.logger.info(`准备推送新用户到目标: ${stringTarget}`);
|
|
446
|
-
await bot.sendMessage(stringTarget,
|
|
475
|
+
await bot.sendMessage(stringTarget, message);
|
|
447
476
|
ctx.logger.info(`已推送新用户到 ${stringTarget}: ${user.name}`);
|
|
448
477
|
}
|
|
449
478
|
catch (error) {
|
|
@@ -464,7 +493,7 @@ function apply(ctx, config) {
|
|
|
464
493
|
const posts = await fetchLatestPosts();
|
|
465
494
|
if (posts.length === 0) {
|
|
466
495
|
ctx.logger.info('没有找到文章');
|
|
467
|
-
return '暂无文章';
|
|
496
|
+
return koishi_1.h.text('暂无文章');
|
|
468
497
|
}
|
|
469
498
|
let message = '📰 最新文章:\n\n';
|
|
470
499
|
for (const post of posts) {
|
|
@@ -473,27 +502,27 @@ function apply(ctx, config) {
|
|
|
473
502
|
message += `${title}\n📅 ${date}\n🔗 ${post.link}\n\n`;
|
|
474
503
|
}
|
|
475
504
|
ctx.logger.info(`准备返回消息,长度: ${message.length}`);
|
|
476
|
-
return message;
|
|
505
|
+
return koishi_1.h.text(message);
|
|
477
506
|
});
|
|
478
507
|
ctx.command('wordpress.list', '查看文章列表')
|
|
479
508
|
.action(async () => {
|
|
480
509
|
ctx.logger.info('命令 wordpress.list 被调用');
|
|
481
510
|
const posts = await fetchLatestPosts();
|
|
482
511
|
if (posts.length === 0) {
|
|
483
|
-
return '暂无文章';
|
|
512
|
+
return koishi_1.h.text('暂无文章');
|
|
484
513
|
}
|
|
485
514
|
let message = '📚 文章列表:\n\n';
|
|
486
515
|
for (const post of posts) {
|
|
487
516
|
const title = post.title.rendered.replace(/<[^>]*>/g, '');
|
|
488
517
|
message += `${post.id}. ${title}\n`;
|
|
489
518
|
}
|
|
490
|
-
return message;
|
|
519
|
+
return koishi_1.h.text(message);
|
|
491
520
|
});
|
|
492
521
|
ctx.command('wordpress.push', '手动推送最新文章')
|
|
493
522
|
.action(async () => {
|
|
494
523
|
ctx.logger.info('命令 wordpress.push 被调用');
|
|
495
524
|
await pushNewPosts();
|
|
496
|
-
return '已检查并推送最新文章';
|
|
525
|
+
return koishi_1.h.text('已检查并推送最新文章');
|
|
497
526
|
});
|
|
498
527
|
ctx.command('wordpress.status', '查看插件状态')
|
|
499
528
|
.action(({ session }) => {
|
|
@@ -502,107 +531,120 @@ function apply(ctx, config) {
|
|
|
502
531
|
const currentGroup = session?.channelId || '未知群聊';
|
|
503
532
|
// 推送目标仅显示本群
|
|
504
533
|
const targetText = `🎯 推送目标: ${currentGroup}`;
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
${
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
534
|
+
// 使用数组拼接消息,便于控制格式和长度
|
|
535
|
+
const messageParts = [
|
|
536
|
+
'📊 WordPress 插件状态',
|
|
537
|
+
`🌐 站点: ${config.wordpressUrl}`,
|
|
538
|
+
`⏰ 间隔: ${config.interval / 1000} 秒`,
|
|
539
|
+
targetText,
|
|
540
|
+
`🔔 自动推送: ${config.enableAutoPush ? '开启' : '关闭'}`,
|
|
541
|
+
`🔄 更新推送: ${config.enableUpdatePush ? '开启' : '关闭'}`,
|
|
542
|
+
`👤 用户推送: ${config.enableUserPush ? '开启' : '关闭'}`,
|
|
543
|
+
`📢 @全体: ${config.mentionAll ? '开启' : '关闭'}`,
|
|
544
|
+
`📝 最多推送: ${config.maxArticles} 篇`
|
|
545
|
+
];
|
|
546
|
+
// 合并为单行文本,统一换行符
|
|
547
|
+
let message = messageParts.join('\n');
|
|
548
|
+
// 长度验证,超过 450 字符则精简
|
|
549
|
+
if (message.length > 450) {
|
|
550
|
+
ctx.logger.warn(`消息过长,长度: ${message.length},将进行精简`);
|
|
551
|
+
message = messageParts.slice(0, 5).join('\n') + '\n... 更多配置请查看完整状态';
|
|
552
|
+
}
|
|
553
|
+
ctx.logger.info(`准备返回消息,长度: ${message.length}`);
|
|
554
|
+
// 使用 h.text() 封装消息,确保兼容性
|
|
555
|
+
return koishi_1.h.text(message);
|
|
514
556
|
});
|
|
515
557
|
ctx.command('wordpress.toggle-update', '切换文章更新推送开关')
|
|
516
558
|
.action(async ({ session }) => {
|
|
517
559
|
// 检查是否为超级管理员
|
|
518
560
|
if (!session || !session.userId) {
|
|
519
561
|
ctx.logger.warn('匿名用户尝试调用 wordpress.toggle-update 命令');
|
|
520
|
-
return '您不是超级管理员,无法执行此命令';
|
|
562
|
+
return koishi_1.h.text('您不是超级管理员,无法执行此命令');
|
|
521
563
|
}
|
|
522
564
|
// 获取当前用户的QQ号(兼容不同平台格式,如 onebot:123456789 -> 123456789)
|
|
523
565
|
const userId = session.userId.replace(/^\w+:/, '');
|
|
524
566
|
// 检查当前用户是否在插件配置的超级管理员列表中
|
|
525
567
|
if (!config.superAdmins || !config.superAdmins.includes(userId)) {
|
|
526
568
|
ctx.logger.warn(`非超级管理员 ${userId} 尝试调用 wordpress.toggle-update 命令`);
|
|
527
|
-
return '您不是超级管理员,无法执行此命令';
|
|
569
|
+
return koishi_1.h.text('您不是超级管理员,无法执行此命令');
|
|
528
570
|
}
|
|
529
571
|
ctx.logger.info('命令 wordpress.toggle-update 被调用');
|
|
530
572
|
config.enableUpdatePush = !config.enableUpdatePush;
|
|
531
|
-
return `文章更新推送已${config.enableUpdatePush ? '开启' : '关闭'}
|
|
573
|
+
return koishi_1.h.text(`文章更新推送已${config.enableUpdatePush ? '开启' : '关闭'}`);
|
|
532
574
|
});
|
|
533
575
|
ctx.command('wordpress.toggle-user', '切换新用户注册推送开关')
|
|
534
576
|
.action(async ({ session }) => {
|
|
535
577
|
// 检查是否为超级管理员
|
|
536
578
|
if (!session || !session.userId) {
|
|
537
579
|
ctx.logger.warn('匿名用户尝试调用 wordpress.toggle-user 命令');
|
|
538
|
-
return '您不是超级管理员,无法执行此命令';
|
|
580
|
+
return koishi_1.h.text('您不是超级管理员,无法执行此命令');
|
|
539
581
|
}
|
|
540
582
|
// 获取当前用户的QQ号(兼容不同平台格式,如 onebot:123456789 -> 123456789)
|
|
541
583
|
const userId = session.userId.replace(/^\w+:/, '');
|
|
542
584
|
// 检查当前用户是否在插件配置的超级管理员列表中
|
|
543
585
|
if (!config.superAdmins || !config.superAdmins.includes(userId)) {
|
|
544
586
|
ctx.logger.warn(`非超级管理员 ${userId} 尝试调用 wordpress.toggle-user 命令`);
|
|
545
|
-
return '您不是超级管理员,无法执行此命令';
|
|
587
|
+
return koishi_1.h.text('您不是超级管理员,无法执行此命令');
|
|
546
588
|
}
|
|
547
589
|
ctx.logger.info('命令 wordpress.toggle-user 被调用');
|
|
548
590
|
config.enableUserPush = !config.enableUserPush;
|
|
549
|
-
return `新用户注册推送已${config.enableUserPush ? '开启' : '关闭'}
|
|
591
|
+
return koishi_1.h.text(`新用户注册推送已${config.enableUserPush ? '开启' : '关闭'}`);
|
|
550
592
|
});
|
|
551
593
|
ctx.command('wordpress.toggle', '切换自动推送开关')
|
|
552
594
|
.action(async ({ session }) => {
|
|
553
595
|
// 检查是否为超级管理员
|
|
554
596
|
if (!session || !session.userId) {
|
|
555
597
|
ctx.logger.warn('匿名用户尝试调用 wordpress.toggle 命令');
|
|
556
|
-
return '您不是超级管理员,无法执行此命令';
|
|
598
|
+
return koishi_1.h.text('您不是超级管理员,无法执行此命令');
|
|
557
599
|
}
|
|
558
600
|
// 获取当前用户的QQ号(兼容不同平台格式,如 onebot:123456789 -> 123456789)
|
|
559
601
|
const userId = session.userId.replace(/^\w+:/, '');
|
|
560
602
|
// 检查当前用户是否在插件配置的超级管理员列表中
|
|
561
603
|
if (!config.superAdmins || !config.superAdmins.includes(userId)) {
|
|
562
604
|
ctx.logger.warn(`非超级管理员 ${userId} 尝试调用 wordpress.toggle 命令`);
|
|
563
|
-
return '您不是超级管理员,无法执行此命令';
|
|
605
|
+
return koishi_1.h.text('您不是超级管理员,无法执行此命令');
|
|
564
606
|
}
|
|
565
607
|
ctx.logger.info('命令 wordpress.toggle 被调用');
|
|
566
608
|
config.enableAutoPush = !config.enableAutoPush;
|
|
567
|
-
return `自动推送已${config.enableAutoPush ? '开启' : '关闭'}
|
|
609
|
+
return koishi_1.h.text(`自动推送已${config.enableAutoPush ? '开启' : '关闭'}`);
|
|
568
610
|
});
|
|
569
611
|
ctx.command('wordpress.mention', '切换 @全体成员 开关')
|
|
570
612
|
.action(async ({ session }) => {
|
|
571
613
|
// 检查是否为超级管理员
|
|
572
614
|
if (!session || !session.userId) {
|
|
573
615
|
ctx.logger.warn('匿名用户尝试调用 wordpress.mention 命令');
|
|
574
|
-
return '您不是超级管理员,无法执行此命令';
|
|
616
|
+
return koishi_1.h.text('您不是超级管理员,无法执行此命令');
|
|
575
617
|
}
|
|
576
618
|
// 获取当前用户的QQ号(兼容不同平台格式,如 onebot:123456789 -> 123456789)
|
|
577
619
|
const userId = session.userId.replace(/^\w+:/, '');
|
|
578
620
|
// 检查当前用户是否在插件配置的超级管理员列表中
|
|
579
621
|
if (!config.superAdmins || !config.superAdmins.includes(userId)) {
|
|
580
622
|
ctx.logger.warn(`非超级管理员 ${userId} 尝试调用 wordpress.mention 命令`);
|
|
581
|
-
return '您不是超级管理员,无法执行此命令';
|
|
623
|
+
return koishi_1.h.text('您不是超级管理员,无法执行此命令');
|
|
582
624
|
}
|
|
583
625
|
ctx.logger.info('命令 wordpress.mention 被调用');
|
|
584
626
|
config.mentionAll = !config.mentionAll;
|
|
585
|
-
return
|
|
627
|
+
return koishi_1.h.text(`@全体 已${config.mentionAll ? '开启' : '关闭'}`);
|
|
586
628
|
});
|
|
587
629
|
ctx.command('wordpress.set-url <url>', '修改 WordPress 站点地址')
|
|
588
630
|
.action(async ({ session }, url) => {
|
|
589
631
|
// 检查是否为超级管理员
|
|
590
632
|
if (!session || !session.userId) {
|
|
591
633
|
ctx.logger.warn('匿名用户尝试调用 wordpress.set-url 命令');
|
|
592
|
-
return '您不是超级管理员,无法执行此命令';
|
|
634
|
+
return koishi_1.h.text('您不是超级管理员,无法执行此命令');
|
|
593
635
|
}
|
|
594
636
|
// 获取当前用户的QQ号(兼容不同平台格式,如 onebot:123456789 -> 123456789)
|
|
595
637
|
const userId = session.userId.replace(/^\w+:/, '');
|
|
596
638
|
// 检查当前用户是否在插件配置的超级管理员列表中
|
|
597
639
|
if (!config.superAdmins || !config.superAdmins.includes(userId)) {
|
|
598
640
|
ctx.logger.warn(`非超级管理员 ${userId} 尝试调用 wordpress.set-url 命令`);
|
|
599
|
-
return '您不是超级管理员,无法执行此命令';
|
|
641
|
+
return koishi_1.h.text('您不是超级管理员,无法执行此命令');
|
|
600
642
|
}
|
|
601
643
|
ctx.logger.info(`命令 wordpress.set-url 被调用,调用者:${userId},新地址:${url}`);
|
|
602
644
|
// 修改站点地址
|
|
603
645
|
config.wordpressUrl = url;
|
|
604
646
|
ctx.logger.info(`站点地址已修改为:${url}`);
|
|
605
|
-
return `WordPress 站点地址已修改为:${url}
|
|
647
|
+
return koishi_1.h.text(`WordPress 站点地址已修改为:${url}`);
|
|
606
648
|
});
|
|
607
649
|
ctx.command('wordpress.pushed', '查看已推送的文章列表')
|
|
608
650
|
.action(async () => {
|
|
@@ -614,34 +656,42 @@ ${targetText}
|
|
|
614
656
|
}
|
|
615
657
|
});
|
|
616
658
|
if (records.length === 0) {
|
|
617
|
-
return '暂无已推送文章记录';
|
|
659
|
+
return koishi_1.h.text('暂无已推送文章记录');
|
|
618
660
|
}
|
|
619
|
-
|
|
661
|
+
// 使用数组拼接消息,便于控制格式和长度
|
|
662
|
+
const messageParts = ['📋 已推送文章列表(按时间倒序):'];
|
|
620
663
|
for (const record of records) {
|
|
621
|
-
|
|
622
|
-
|
|
664
|
+
messageParts.push(`${record.id}. 文章 ID: ${record.postId}`);
|
|
665
|
+
messageParts.push(`📅 推送时间: ${new Date(record.pushedAt).toLocaleString('zh-CN')}`);
|
|
666
|
+
messageParts.push(''); // 空行分隔
|
|
667
|
+
}
|
|
668
|
+
let message = messageParts.join('\n');
|
|
669
|
+
// 长度验证,超过 450 字符则精简
|
|
670
|
+
if (message.length > 450) {
|
|
671
|
+
ctx.logger.warn(`消息过长,长度: ${message.length},将进行精简`);
|
|
672
|
+
message = messageParts.slice(0, 10).join('\n') + '\n... 更多记录请查看完整列表';
|
|
623
673
|
}
|
|
624
|
-
return message;
|
|
674
|
+
return koishi_1.h.text(message);
|
|
625
675
|
});
|
|
626
676
|
ctx.command('wordpress.clean [days]', '清理指定天数前的推送记录(默认 30 天)')
|
|
627
677
|
.action(async ({ session }, days) => {
|
|
628
678
|
// 检查是否为超级管理员
|
|
629
679
|
if (!session || !session.userId) {
|
|
630
680
|
ctx.logger.warn('匿名用户尝试调用 wordpress.clean 命令');
|
|
631
|
-
return '您不是超级管理员,无法执行此命令';
|
|
681
|
+
return koishi_1.h.text('您不是超级管理员,无法执行此命令');
|
|
632
682
|
}
|
|
633
683
|
// 获取当前用户的QQ号(兼容不同平台格式,如 onebot:123456789 -> 123456789)
|
|
634
684
|
const userId = session.userId.replace(/^\w+:/, '');
|
|
635
685
|
// 检查当前用户是否在插件配置的超级管理员列表中
|
|
636
686
|
if (!config.superAdmins || !config.superAdmins.includes(userId)) {
|
|
637
687
|
ctx.logger.warn(`非超级管理员 ${userId} 尝试调用 wordpress.clean 命令`);
|
|
638
|
-
return '您不是超级管理员,无法执行此命令';
|
|
688
|
+
return koishi_1.h.text('您不是超级管理员,无法执行此命令');
|
|
639
689
|
}
|
|
640
690
|
ctx.logger.info(`命令 wordpress.clean 被调用,天数:${days || '默认'}`);
|
|
641
691
|
// 设置默认天数
|
|
642
692
|
const daysToKeep = days ? parseInt(days) : 30;
|
|
643
693
|
if (isNaN(daysToKeep) || daysToKeep <= 0) {
|
|
644
|
-
return '请输入有效的天数';
|
|
694
|
+
return koishi_1.h.text('请输入有效的天数');
|
|
645
695
|
}
|
|
646
696
|
// 计算清理时间点
|
|
647
697
|
const cutoffDate = new Date();
|
|
@@ -667,26 +717,32 @@ ${targetText}
|
|
|
667
717
|
result++;
|
|
668
718
|
}
|
|
669
719
|
ctx.logger.info(`已清理 ${result} 条 ${daysToKeep} 天前的推送记录`);
|
|
670
|
-
return `已清理 ${result} 条 ${daysToKeep}
|
|
720
|
+
return koishi_1.h.text(`已清理 ${result} 条 ${daysToKeep} 天前的推送记录`);
|
|
671
721
|
});
|
|
672
722
|
ctx.command('wordpress', 'WordPress 推送插件菜单')
|
|
673
723
|
.action(() => {
|
|
674
724
|
ctx.logger.info('命令 wordpress 被调用');
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
🔹 /wordpress.
|
|
680
|
-
🔹 /wordpress.
|
|
681
|
-
🔹 /wordpress.
|
|
682
|
-
🔹 /wordpress.
|
|
683
|
-
🔹 /wordpress.
|
|
684
|
-
🔹 /wordpress.
|
|
685
|
-
🔹 /wordpress.
|
|
686
|
-
🔹 /wordpress.toggle
|
|
687
|
-
🔹 /wordpress.
|
|
688
|
-
|
|
689
|
-
|
|
725
|
+
// 使用数组拼接消息,便于控制格式和长度
|
|
726
|
+
const messageParts = [
|
|
727
|
+
'📚 WordPress 推送插件菜单:',
|
|
728
|
+
'',
|
|
729
|
+
'🔹 /wordpress.status - 查看插件状态',
|
|
730
|
+
'🔹 /wordpress.latest - 查看最新文章',
|
|
731
|
+
'🔹 /wordpress.list - 查看文章列表',
|
|
732
|
+
'🔹 /wordpress.push - 手动推送最新文章',
|
|
733
|
+
'🔹 /wordpress.set-url <url> - 修改 WordPress 站点地址',
|
|
734
|
+
'🔹 /wordpress.pushed - 查看已推送文章列表',
|
|
735
|
+
'🔹 /wordpress.clean [days] - 清理旧推送记录',
|
|
736
|
+
'🔹 /wordpress.toggle - 切换自动推送开关(仅超级管理员)',
|
|
737
|
+
'🔹 /wordpress.toggle-update - 切换文章更新推送开关(仅超级管理员)',
|
|
738
|
+
'🔹 /wordpress.toggle-user - 切换新用户注册推送开关(仅超级管理员)',
|
|
739
|
+
'🔹 /wordpress.mention - 切换 @全体 开关(仅超级管理员)',
|
|
740
|
+
'',
|
|
741
|
+
'💡 提示:所有命令都需要加 / 前缀'
|
|
742
|
+
];
|
|
743
|
+
let message = messageParts.join('\n');
|
|
744
|
+
ctx.logger.info(`准备返回消息,长度: ${message.length}`);
|
|
745
|
+
return koishi_1.h.text(message);
|
|
690
746
|
});
|
|
691
747
|
ctx.setInterval(() => {
|
|
692
748
|
pushNewPosts();
|