koishi-plugin-stock 2.1.6 → 2.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 +41 -24
- package/lib/core/broadcast.js +75 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -65,55 +65,72 @@ npm install koishi-plugin-stock
|
|
|
65
65
|
|
|
66
66
|
## 更新日志
|
|
67
67
|
|
|
68
|
-
### v2.1.
|
|
68
|
+
### v2.1.8 (2026-03-02)
|
|
69
|
+
- 🎯 **用户体验优化**:为定时广播消息添加"[定时广播 - 内容]"前缀标识
|
|
70
|
+
- ✅ **消息识别**:用户可以清楚区分定时推送和手动触发的消息
|
|
71
|
+
- 📦 保持所有功能逻辑不变,仅优化消息格式
|
|
72
|
+
|
|
73
|
+
### v2.1.7 (2026-03-02)
|
|
74
|
+
- 🐛 **核心修复**:修复定时广播任务只发送提示消息的问题
|
|
75
|
+
- ✅ **功能完善**:定时任务现在直接获取并发送真实数据(活跃市值、涨跌停看板)
|
|
76
|
+
- 🔧 **重试机制**:为定时任务添加HTTP重试机制和错误处理
|
|
77
|
+
- 📊 **用户体验**:用户无需手动触发,定时任务自动推送完整数据
|
|
69
78
|
- ⚡ **性能优化**:超时时间从15秒调整为10秒
|
|
70
79
|
- 🔁 **重试机制**:添加3次重试机制,使用指数退避策略(2s/4s/8s)
|
|
71
80
|
- 🔄 **统一处理**:所有API请求使用统一的重试函数
|
|
72
81
|
- 📊 **可观测性**:增强日志记录,便于问题排查
|
|
73
|
-
|
|
74
|
-
### v2.1.5 (2026-03-02)
|
|
75
82
|
- 🚀 **性能优化**:增加API请求超时时间至15秒
|
|
76
83
|
- 🔧 **错误处理增强**:添加详细的错误类型识别和针对性提示
|
|
77
84
|
- 🔒 **安全性提升**:统一使用HTTPS协议替代HTTP
|
|
78
85
|
- 📊 **用户体验改善**:区分超时错误与其他网络错误,提供更准确的错误信息
|
|
86
|
+
|
|
87
|
+
### v2.1.4 (2026-02-28)
|
|
79
88
|
- 🎉 **新增心法**:添加第58条心法 "我能怎么办,我真的我,我,我真的没招了,我"
|
|
80
89
|
- ✅ 心法总数更新为58条
|
|
81
90
|
- 📦 保持所有功能稳定运行
|
|
91
|
+
|
|
92
|
+
### v2.1.3 (2026-02-28)
|
|
82
93
|
- 🐛 **紧急修复**:修复"骑"命令图片读取问题
|
|
83
94
|
- ✅ 改为从本地images/qi.jpeg读取图片而非网络请求
|
|
84
95
|
- 🔧 增强错误日志,提供更详细的调试信息
|
|
85
96
|
- 📦 保持所有其他功能不变
|
|
97
|
+
|
|
98
|
+
### v2.1.2 (2026-02-28)
|
|
86
99
|
- 🐛 **紧急修复**:修复插件指令注册问题
|
|
87
100
|
- ✅ 恢复所有股票相关指令:活跃市值、异动、涨停看板、跌停看板、选股、骑
|
|
88
101
|
- 🔧 将middleware方式改为ctx.command方式,确保指令在插件界面正确显示
|
|
89
102
|
- 📦 保持所有功能逻辑不变,仅修复指令注册方式
|
|
103
|
+
|
|
104
|
+
### v2.1.1 (2026-02-28)
|
|
90
105
|
- 🐛 **紧急修复**:修复插件配置项声明问题
|
|
91
106
|
- ✅ 正确导出Config和ConfigSchema供Koishi识别
|
|
92
107
|
- 📦 保持所有功能不变,仅修复配置导出问题
|
|
93
|
-
- 🎉 **重大架构重构**:全面模块化设计,代码结构更清晰
|
|
94
|
-
- 📁 新增模块化目录结构:`core/`, `commands/`, `utils/`
|
|
95
|
-
- 🔧 核心功能解耦:心法数据、交易日判断、广播调度独立模块
|
|
96
|
-
- 🚀 提升可维护性:主入口文件从39KB精简至5.7KB
|
|
97
|
-
- 📦 更好的扩展性:新增功能模块更容易集成
|
|
98
|
-
- 新增"我要验牌"命令:支持查看指定序号的心法语音或查看全部心法文本
|
|
99
|
-
- 新增验牌功能黑白名单配置:支持为验牌功能单独设置用户和频道黑名单
|
|
100
|
-
- 增强用户体验:提供清晰的参数使用说明和错误提示
|
|
101
|
-
- 优化交易日判断:使用stock.svip886.com提供的专业交易日API替代timor.tech节假日接口
|
|
102
|
-
- 改进API调用:直接解析JSON响应,提高判断准确性
|
|
103
|
-
- 增强错误处理:API请求失败时默认跳过任务,确保安全性
|
|
104
108
|
|
|
105
|
-
### v2.0
|
|
106
|
-
-
|
|
107
|
-
-
|
|
108
|
-
-
|
|
109
|
+
### v2.1.0 (2026-02-28)
|
|
110
|
+
- 🏗️ **架构重构**:将代码拆分为多个模块文件
|
|
111
|
+
- 📁 **模块化**:分离commands、core、utils等不同功能模块
|
|
112
|
+
- 🔧 **代码组织**:提高代码可维护性和可读性
|
|
113
|
+
- 📦 保持所有功能不变,仅重构代码结构
|
|
114
|
+
|
|
115
|
+
### v2.0.15 (2026-02-28)
|
|
116
|
+
- 🐛 **紧急修复**:修复交易日API返回格式问题
|
|
117
|
+
- ✅ 正确解析{"code":1,"msg":"success","data":{"is_trading_day":true}}格式
|
|
118
|
+
- 🔧 增强错误处理,提供更友好的错误提示
|
|
119
|
+
- 📦 保持所有其他功能稳定运行
|
|
120
|
+
|
|
121
|
+
### v2.0.14 (2026-02-28)
|
|
122
|
+
- 🐛 **紧急修复**:修复定时广播任务未触发问题
|
|
123
|
+
- ✅ 恢复每日9:30和15:00的定时广播功能
|
|
124
|
+
- 🔧 增强日志输出,便于调试和监控
|
|
125
|
+
- 📦 保持所有其他功能不变
|
|
109
126
|
|
|
110
|
-
### v2.0.
|
|
111
|
-
-
|
|
112
|
-
-
|
|
113
|
-
-
|
|
127
|
+
### v2.0.13 (2026-02-25)
|
|
128
|
+
- 🐛 **紧急修复**:修复心法数据JSON解析错误
|
|
129
|
+
- ✅ 将心法数据直接嵌入TypeScript源码,避免编码问题
|
|
130
|
+
- 🔧 增强错误处理和日志记录
|
|
131
|
+
- 📦 保持所有其他功能稳定运行
|
|
114
132
|
|
|
115
|
-
|
|
116
|
-
- 修复JSON文件BOM字符处理问题:在跨平台环境下正确解析UTF-8 with BOM格式的JSON文件
|
|
133
|
+
*注:更早版本历史请查看Git提交记录*
|
|
117
134
|
- 增强编码兼容性:自动检测并移除BOM字符确保JSON解析成功
|
|
118
135
|
|
|
119
136
|
### v2.0.10 (2026-02-25)
|
package/lib/core/broadcast.js
CHANGED
|
@@ -2,6 +2,33 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.BroadcastScheduler = void 0;
|
|
4
4
|
const trading_day_1 = require("../core/trading-day");
|
|
5
|
+
// 带重试机制的HTTP请求函数
|
|
6
|
+
async function httpRequestWithRetry(ctx, url, options, maxRetries = 3) {
|
|
7
|
+
const logger = ctx.logger('stock');
|
|
8
|
+
let lastError = new Error('Unknown error');
|
|
9
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
10
|
+
try {
|
|
11
|
+
logger.info(`[定时任务] 第${attempt}次尝试请求: ${url}`);
|
|
12
|
+
const result = await ctx.http.get(url, {
|
|
13
|
+
...options,
|
|
14
|
+
timeout: 10000
|
|
15
|
+
});
|
|
16
|
+
logger.info(`[定时任务] 第${attempt}次请求成功`);
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
lastError = error;
|
|
21
|
+
logger.warn(`[定时任务] 第${attempt}次请求失败:`, error.message);
|
|
22
|
+
if (attempt < maxRetries) {
|
|
23
|
+
const delay = Math.pow(2, attempt) * 1000;
|
|
24
|
+
logger.info(`[定时任务] 等待${delay}ms后进行第${attempt + 1}次重试`);
|
|
25
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
logger.error(`[定时任务] 所有${maxRetries}次重试都失败了`);
|
|
30
|
+
throw lastError;
|
|
31
|
+
}
|
|
5
32
|
class BroadcastScheduler {
|
|
6
33
|
static setup(ctx, config, tasks) {
|
|
7
34
|
const logger = ctx.logger('stock');
|
|
@@ -23,13 +50,57 @@ class BroadcastScheduler {
|
|
|
23
50
|
logger.info('[定时任务跳过] 今日非交易日');
|
|
24
51
|
continue;
|
|
25
52
|
}
|
|
53
|
+
// 获取实际数据
|
|
54
|
+
let messageContent = '';
|
|
55
|
+
if (task.content === '活跃市值') {
|
|
56
|
+
try {
|
|
57
|
+
const responseText = await httpRequestWithRetry(ctx, 'https://stock.svip886.com/api/indexes', {
|
|
58
|
+
responseType: 'text'
|
|
59
|
+
});
|
|
60
|
+
messageContent = `📊指数看板:\n\n${responseText}`;
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
logger.error('[定时任务] 获取活跃市值数据失败:', error);
|
|
64
|
+
messageContent = '获取活跃市值数据失败,请稍后重试。';
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
else if (task.content === '涨停看板') {
|
|
68
|
+
try {
|
|
69
|
+
const imageUrl = 'https://stock.svip886.com/api/limit_up.png';
|
|
70
|
+
const imageBuffer = await httpRequestWithRetry(ctx, imageUrl, {
|
|
71
|
+
responseType: 'arraybuffer'
|
|
72
|
+
});
|
|
73
|
+
const base64Image = Buffer.from(imageBuffer).toString('base64');
|
|
74
|
+
messageContent = `<img src="data:image/png;base64,${base64Image}" />`;
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
logger.error('[定时任务] 获取涨停看板图片失败:', error);
|
|
78
|
+
messageContent = '获取涨停看板图片失败,请稍后重试。';
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
else if (task.content === '跌停看板') {
|
|
82
|
+
try {
|
|
83
|
+
const imageUrl = 'https://stock.svip886.com/api/limit_down.png';
|
|
84
|
+
const imageBuffer = await httpRequestWithRetry(ctx, imageUrl, {
|
|
85
|
+
responseType: 'arraybuffer'
|
|
86
|
+
});
|
|
87
|
+
const base64Image = Buffer.from(imageBuffer).toString('base64');
|
|
88
|
+
messageContent = `<img src="data:image/png;base64,${base64Image}" />`;
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
logger.error('[定时任务] 获取跌停看板图片失败:', error);
|
|
92
|
+
messageContent = '获取跌停看板图片失败,请稍后重试。';
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// 添加定时广播前缀
|
|
96
|
+
messageContent = `[定时广播 - ${task.content}] ${messageContent}`;
|
|
26
97
|
// 执行广播任务
|
|
27
98
|
const targets = task.targetIds.split(',').map(id => id.trim()).filter(id => id);
|
|
28
99
|
if (task.type === 'private') {
|
|
29
100
|
targets.forEach(targetId => {
|
|
30
101
|
ctx.bots.forEach(bot => {
|
|
31
|
-
bot.sendPrivateMessage(targetId,
|
|
32
|
-
logger.error(
|
|
102
|
+
bot.sendPrivateMessage(targetId, messageContent).catch(e => {
|
|
103
|
+
logger.error(`[定时任务] 私聊消息发送失败: ${e.message}`);
|
|
33
104
|
});
|
|
34
105
|
});
|
|
35
106
|
});
|
|
@@ -37,8 +108,8 @@ class BroadcastScheduler {
|
|
|
37
108
|
else {
|
|
38
109
|
targets.forEach(targetId => {
|
|
39
110
|
ctx.bots.forEach(bot => {
|
|
40
|
-
bot.sendMessage(targetId,
|
|
41
|
-
logger.error(
|
|
111
|
+
bot.sendMessage(targetId, messageContent).catch(e => {
|
|
112
|
+
logger.error(`[定时任务] 频道消息发送失败: ${e.message}`);
|
|
42
113
|
});
|
|
43
114
|
});
|
|
44
115
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "koishi-plugin-stock",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.8",
|
|
4
4
|
"description": "A Koishi plugin that fetches stock data and provides market analysis, including active market cap, stock alerts, limit-up board, stock selection features, and heart method card drawing with configurable blacklists for each command.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"typings": "lib/index.d.ts",
|