koishi-plugin-bilibili-notify 1.0.0 → 1.0.1
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/lib/biliAPI.d.ts +3 -0
- package/lib/biliAPI.js +31 -10
- package/lib/comRegister.js +14 -8
- package/lib/generateImg.js +8 -8
- package/lib/index.d.ts +1 -0
- package/lib/index.js +21 -1
- package/package.json +1 -1
- package/readme.md +14 -5
package/lib/biliAPI.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Context, Service } from "koishi";
|
|
2
2
|
import { CookieJar } from 'tough-cookie';
|
|
3
|
+
import { Notifier } from "@koishijs/plugin-notifier";
|
|
3
4
|
declare module 'koishi' {
|
|
4
5
|
interface Context {
|
|
5
6
|
biliAPI: BiliAPI;
|
|
@@ -10,6 +11,7 @@ declare class BiliAPI extends Service {
|
|
|
10
11
|
jar: CookieJar;
|
|
11
12
|
client: any;
|
|
12
13
|
loginData: any;
|
|
14
|
+
loginNotifier: Notifier;
|
|
13
15
|
constructor(ctx: Context);
|
|
14
16
|
protected start(): void | Promise<void>;
|
|
15
17
|
getTimeNow(): Promise<any>;
|
|
@@ -21,6 +23,7 @@ declare class BiliAPI extends Service {
|
|
|
21
23
|
getLoginStatus(qrcodeKey: string): Promise<any>;
|
|
22
24
|
getLiveRoomInfo(roomId: string): Promise<any>;
|
|
23
25
|
getMasterInfo(mid: string): Promise<any>;
|
|
26
|
+
disposeNotifier(): void;
|
|
24
27
|
createNewClient(): void;
|
|
25
28
|
getCookies(): string;
|
|
26
29
|
loadCookiesFromDatabase(): Promise<void>;
|
package/lib/biliAPI.js
CHANGED
|
@@ -8,7 +8,7 @@ const axios_1 = __importDefault(require("axios"));
|
|
|
8
8
|
const tough_cookie_1 = require("tough-cookie");
|
|
9
9
|
const axios_cookiejar_support_1 = require("axios-cookiejar-support");
|
|
10
10
|
const jsdom_1 = require("jsdom");
|
|
11
|
-
const GET_DYNAMIC_LIST = 'https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/all'
|
|
11
|
+
// const GET_DYNAMIC_LIST = 'https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/all'
|
|
12
12
|
const GET_USER_SPACE_DYNAMIC_LIST = 'https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/space';
|
|
13
13
|
const GET_COOKIES_INFO = 'https://passport.bilibili.com/x/passport-login/web/cookie/info';
|
|
14
14
|
const GET_USER_INFO = 'https://api.bilibili.com/x/space/wbi/acc/info';
|
|
@@ -19,10 +19,11 @@ const GET_LIVE_ROOM_INFO = 'https://api.live.bilibili.com/room/v1/Room/get_info'
|
|
|
19
19
|
const GET_MASTER_INFO = 'https://api.live.bilibili.com/live_user/v1/Master/info';
|
|
20
20
|
const GET_TIME_NOW = 'https://api.bilibili.com/x/report/click/now';
|
|
21
21
|
class BiliAPI extends koishi_1.Service {
|
|
22
|
-
static inject = ['database', 'wbi'];
|
|
22
|
+
static inject = ['database', 'wbi', 'notifier'];
|
|
23
23
|
jar;
|
|
24
24
|
client;
|
|
25
25
|
loginData;
|
|
26
|
+
loginNotifier;
|
|
26
27
|
constructor(ctx) {
|
|
27
28
|
super(ctx, 'biliAPI');
|
|
28
29
|
}
|
|
@@ -117,6 +118,7 @@ class BiliAPI extends koishi_1.Service {
|
|
|
117
118
|
throw new Error('网络异常,本次请求失败!');
|
|
118
119
|
}
|
|
119
120
|
}
|
|
121
|
+
disposeNotifier() { this.loginNotifier && this.loginNotifier.dispose(); }
|
|
120
122
|
createNewClient() {
|
|
121
123
|
this.jar = new tough_cookie_1.CookieJar();
|
|
122
124
|
this.client = (0, axios_cookiejar_support_1.wrapper)(axios_1.default.create({ jar: this.jar, headers: { 'Content-Type': 'application/json' } }));
|
|
@@ -133,9 +135,15 @@ class BiliAPI extends koishi_1.Service {
|
|
|
133
135
|
async loadCookiesFromDatabase() {
|
|
134
136
|
// 读取数据库获取cookies
|
|
135
137
|
const data = (await this.ctx.database.get('loginBili', 1))[0];
|
|
136
|
-
//
|
|
137
|
-
if (data === undefined)
|
|
138
|
+
// 判断是否登录
|
|
139
|
+
if (data === undefined) { // 没有数据则直接返回
|
|
140
|
+
// 未登录,在控制台提示
|
|
141
|
+
this.loginNotifier = this.ctx.notifier.create({
|
|
142
|
+
type: 'warning',
|
|
143
|
+
content: '您尚未登录,将无法使用插件提供的指令'
|
|
144
|
+
});
|
|
138
145
|
return;
|
|
146
|
+
}
|
|
139
147
|
// 定义解密信息
|
|
140
148
|
let decryptedCookies;
|
|
141
149
|
let decryptedRefreshToken;
|
|
@@ -173,8 +181,10 @@ class BiliAPI extends koishi_1.Service {
|
|
|
173
181
|
});
|
|
174
182
|
this.jar.setCookieSync(cookie, `http${cookie.secure ? 's' : ''}://${cookie.domain}${cookie.path}`, {});
|
|
175
183
|
});
|
|
176
|
-
//
|
|
177
|
-
this.
|
|
184
|
+
// Open scheduled tasks and check if token need refresh
|
|
185
|
+
this.ctx.setInterval(() => {
|
|
186
|
+
this.checkIfTokenNeedRefresh(decryptedRefreshToken, csrf);
|
|
187
|
+
}, 43200000);
|
|
178
188
|
}
|
|
179
189
|
async checkIfTokenNeedRefresh(refreshToken, csrf, times = 0) {
|
|
180
190
|
let data;
|
|
@@ -215,22 +225,30 @@ class BiliAPI extends koishi_1.Service {
|
|
|
215
225
|
const refresh_csrf = targetElement ? targetElement.textContent : null;
|
|
216
226
|
// 发送刷新请求
|
|
217
227
|
const { data: refreshData } = await this.client.post('https://passport.bilibili.com/x/passport-login/web/cookie/refresh', {
|
|
218
|
-
csrf,
|
|
228
|
+
csrf: csrf.trim(),
|
|
219
229
|
refresh_csrf,
|
|
220
230
|
source: 'main_web',
|
|
221
231
|
refresh_token: refreshToken
|
|
222
232
|
});
|
|
233
|
+
const notifyAndError = (info) => {
|
|
234
|
+
// 设置控制台通知
|
|
235
|
+
this.loginNotifier = this.ctx.notifier.create({
|
|
236
|
+
type: 'warning',
|
|
237
|
+
content: info
|
|
238
|
+
});
|
|
239
|
+
throw new Error(info);
|
|
240
|
+
};
|
|
223
241
|
// 检查是否有其他问题
|
|
224
242
|
switch (refreshData.code) {
|
|
225
243
|
// 账号未登录
|
|
226
244
|
case -101: return this.createNewClient();
|
|
227
245
|
case -111: {
|
|
228
246
|
await this.ctx.database.remove('loginBili', [1]);
|
|
229
|
-
|
|
247
|
+
notifyAndError('csrf 校验错误,请重新登录');
|
|
230
248
|
}
|
|
231
249
|
case 86095: {
|
|
232
250
|
await this.ctx.database.remove('loginBili', [1]);
|
|
233
|
-
|
|
251
|
+
notifyAndError('refresh_csrf 错误或 refresh_token 与 cookie 不匹配,请重新登录');
|
|
234
252
|
}
|
|
235
253
|
}
|
|
236
254
|
// 更新 新的cookies和refresh_token
|
|
@@ -258,7 +276,10 @@ class BiliAPI extends koishi_1.Service {
|
|
|
258
276
|
});
|
|
259
277
|
// 检查是否有其他问题
|
|
260
278
|
switch (aceeptData.code) {
|
|
261
|
-
case -111:
|
|
279
|
+
case -111: {
|
|
280
|
+
await this.ctx.database.remove('loginBili', [1]);
|
|
281
|
+
notifyAndError('csrf 校验失败,请重新登录');
|
|
282
|
+
}
|
|
262
283
|
case -400: throw new Error('请求错误');
|
|
263
284
|
}
|
|
264
285
|
// 没有问题,cookies已更新完成
|
package/lib/comRegister.js
CHANGED
|
@@ -172,6 +172,8 @@ class ComRegister {
|
|
|
172
172
|
}]);
|
|
173
173
|
// 销毁定时器
|
|
174
174
|
dispose();
|
|
175
|
+
// 清除控制台通知
|
|
176
|
+
ctx.biliAPI.disposeNotifier();
|
|
175
177
|
// 发送成功登录推送
|
|
176
178
|
await session.send('登录成功!');
|
|
177
179
|
// 订阅之前的订阅
|
|
@@ -244,7 +246,7 @@ class ComRegister {
|
|
|
244
246
|
.option('live', '-l')
|
|
245
247
|
.option('dynamic', '-d')
|
|
246
248
|
.usage('订阅用户动态和直播通知,若需要订阅直播请加上-l,需要订阅动态则加上-d。若没有加任何参数,之后会向你单独询问,尖括号中为必选参数,中括号为可选参数,目标群号若不填,则默认为当前群聊')
|
|
247
|
-
.example('bili sub
|
|
249
|
+
.example('bili sub 1194210119 目标QQ群号(暂不支持) -l -d 订阅UID为1194210119的UP主的动态和直播')
|
|
248
250
|
.action(async ({ session, options }, mid, guildId) => {
|
|
249
251
|
this.logger.info('调用bili.sub指令');
|
|
250
252
|
// 检查是否登录
|
|
@@ -382,7 +384,7 @@ class ComRegister {
|
|
|
382
384
|
.subcommand('.dynamic <uid:string> <guildId:string>', '订阅用户动态推送', { hidden: true })
|
|
383
385
|
.option('bot', '-b <type:string>')
|
|
384
386
|
.usage('订阅用户动态推送')
|
|
385
|
-
.example('bili dynamic
|
|
387
|
+
.example('bili dynamic 1194210119 订阅UID为1194210119的动态')
|
|
386
388
|
.action(async ({ session, options }, uid, guildId) => {
|
|
387
389
|
this.logger.info('调用bili.dynamic指令');
|
|
388
390
|
// 如果uid为空则返回
|
|
@@ -411,7 +413,7 @@ class ComRegister {
|
|
|
411
413
|
default: return '非法调用';
|
|
412
414
|
}
|
|
413
415
|
// 开始循环检测
|
|
414
|
-
const dispose = ctx.setInterval(this.dynamicDetect(ctx, bot, guildId, uid),
|
|
416
|
+
const dispose = ctx.setInterval(this.dynamicDetect(ctx, bot, guildId, uid), config.dynamicLoopTime * 1000);
|
|
415
417
|
// 将销毁函数保存到订阅管理对象
|
|
416
418
|
this.subManager[index].dynamicDispose = dispose;
|
|
417
419
|
});
|
|
@@ -419,7 +421,7 @@ class ComRegister {
|
|
|
419
421
|
.subcommand('.live <roomId:string> <guildId:string>', '订阅主播开播通知', { hidden: true })
|
|
420
422
|
.option('bot', '-b <type:string>')
|
|
421
423
|
.usage('订阅主播开播通知')
|
|
422
|
-
.example('bili live
|
|
424
|
+
.example('bili live 26316137 订阅房间号为26316137的直播间')
|
|
423
425
|
.action(async ({ options }, roomId, guildId) => {
|
|
424
426
|
this.logger.info('调用bili.live指令');
|
|
425
427
|
// 如果room_id为空则返回
|
|
@@ -446,7 +448,7 @@ class ComRegister {
|
|
|
446
448
|
default: return '非法调用';
|
|
447
449
|
}
|
|
448
450
|
// 开始循环检测
|
|
449
|
-
const dispose = ctx.setInterval(this.liveDetect(ctx, bot, guildId, roomId),
|
|
451
|
+
const dispose = ctx.setInterval(this.liveDetect(ctx, bot, guildId, roomId), config.liveLoopTime * 1000);
|
|
450
452
|
// 保存销毁函数
|
|
451
453
|
this.subManager[index].liveDispose = dispose;
|
|
452
454
|
});
|
|
@@ -548,11 +550,15 @@ class ComRegister {
|
|
|
548
550
|
if (num === 0) {
|
|
549
551
|
timePoint = items[num].modules.module_author.pub_ts
|
|
550
552
|
} */
|
|
551
|
-
|
|
553
|
+
// 检查最一条动态是否是置顶动态
|
|
554
|
+
if (num === 0) {
|
|
552
555
|
// 如果是置顶动态,则跳过
|
|
553
|
-
|
|
556
|
+
if (items[num].modules.module_tag) {
|
|
557
|
+
// 将上一条动态的发布时间设为时间点
|
|
558
|
+
timePoint = items[num + 1].modules.module_author.pub_ts;
|
|
554
559
|
continue;
|
|
555
|
-
|
|
560
|
+
}
|
|
561
|
+
timePoint = items[num].modules.module_author.pub_ts;
|
|
556
562
|
}
|
|
557
563
|
// 推送该条动态
|
|
558
564
|
let attempts = 3;
|
package/lib/generateImg.js
CHANGED
|
@@ -25,14 +25,14 @@ const DYNAMIC_TYPE_BANNER = 'DYNAMIC_TYPE_BANNER';
|
|
|
25
25
|
const DYNAMIC_TYPE_UGC_SEASON = 'DYNAMIC_TYPE_UGC_SEASON';
|
|
26
26
|
const DYNAMIC_TYPE_SUBSCRIPTION_NEW = 'DYNAMIC_TYPE_SUBSCRIPTION_NEW';
|
|
27
27
|
// 内容卡片类型
|
|
28
|
-
const ADDITIONAL_TYPE_NONE = 'ADDITIONAL_TYPE_NONE'
|
|
29
|
-
const ADDITIONAL_TYPE_PGC = 'ADDITIONAL_TYPE_PGC'
|
|
30
|
-
const ADDITIONAL_TYPE_GOODS = 'ADDITIONAL_TYPE_GOODS'
|
|
31
|
-
const ADDITIONAL_TYPE_VOTE = 'ADDITIONAL_TYPE_VOTE'
|
|
32
|
-
const ADDITIONAL_TYPE_COMMON = 'ADDITIONAL_TYPE_COMMON'
|
|
33
|
-
const ADDITIONAL_TYPE_MATCH = 'ADDITIONAL_TYPE_MATCH'
|
|
34
|
-
const ADDITIONAL_TYPE_UP_RCMD = 'ADDITIONAL_TYPE_UP_RCMD'
|
|
35
|
-
const ADDITIONAL_TYPE_UGC = 'ADDITIONAL_TYPE_UGC'
|
|
28
|
+
/* const ADDITIONAL_TYPE_NONE = 'ADDITIONAL_TYPE_NONE'
|
|
29
|
+
const ADDITIONAL_TYPE_PGC = 'ADDITIONAL_TYPE_PGC'
|
|
30
|
+
const ADDITIONAL_TYPE_GOODS = 'ADDITIONAL_TYPE_GOODS'
|
|
31
|
+
const ADDITIONAL_TYPE_VOTE = 'ADDITIONAL_TYPE_VOTE'
|
|
32
|
+
const ADDITIONAL_TYPE_COMMON = 'ADDITIONAL_TYPE_COMMON'
|
|
33
|
+
const ADDITIONAL_TYPE_MATCH = 'ADDITIONAL_TYPE_MATCH'
|
|
34
|
+
const ADDITIONAL_TYPE_UP_RCMD = 'ADDITIONAL_TYPE_UP_RCMD'
|
|
35
|
+
const ADDITIONAL_TYPE_UGC = 'ADDITIONAL_TYPE_UGC' */
|
|
36
36
|
const ADDITIONAL_TYPE_RESERVE = 'ADDITIONAL_TYPE_RESERVE';
|
|
37
37
|
class GenerateImg extends koishi_1.Service {
|
|
38
38
|
static inject = ['puppeteer', 'biliAPI'];
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -52,6 +52,10 @@ exports.Config = koishi_1.Schema.object({
|
|
|
52
52
|
.step(1)
|
|
53
53
|
.default(5)
|
|
54
54
|
.description('设定每次检查动态的数量。若订阅的UP主经常在短时间内连着发多条动态可以将该值提高,若订阅的UP主有置顶动态,在计算该值时应-1。默认值为5条'),
|
|
55
|
+
dynamicLoopTime: koishi_1.Schema.union(['1分钟', '2分钟', '3分钟', '5分钟'])
|
|
56
|
+
.role('')
|
|
57
|
+
.default('2分钟')
|
|
58
|
+
.description('设定多久检测一次动态。若需动态的时效性,可以设置为1分钟。若订阅的UP主经常在短时间内连着发多条动态应该将该值提高,否则会出现动态漏推送和晚推送的问题,默认值为2分钟'),
|
|
55
59
|
cardColorStart: koishi_1.Schema.string()
|
|
56
60
|
.pattern(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/)
|
|
57
61
|
.default('#F38AB5')
|
|
@@ -78,7 +82,23 @@ function apply(ctx, config) {
|
|
|
78
82
|
ctx.plugin(biliAPI_1.default);
|
|
79
83
|
// load plugin
|
|
80
84
|
// ctx.plugin(Authority)
|
|
81
|
-
|
|
85
|
+
// 转换为具体时间
|
|
86
|
+
let dynamicLoopTime;
|
|
87
|
+
switch (config.dynamicLoopTime) {
|
|
88
|
+
case '1分钟':
|
|
89
|
+
dynamicLoopTime = 60;
|
|
90
|
+
break;
|
|
91
|
+
case '2分钟':
|
|
92
|
+
dynamicLoopTime = 120;
|
|
93
|
+
break;
|
|
94
|
+
case '3分钟':
|
|
95
|
+
dynamicLoopTime = 180;
|
|
96
|
+
break;
|
|
97
|
+
case '5分钟':
|
|
98
|
+
dynamicLoopTime = 300;
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
ctx.plugin(comRegister_1.default, { pushTime: config.pushTime, dynamicCheckNumber: config.dynamicCheckNumber, dynamicLoopTime });
|
|
82
102
|
// 当用户输入“恶魔兔,启动!”时,执行 help 指令
|
|
83
103
|
ctx.middleware((session, next) => {
|
|
84
104
|
if (session.content === '恶魔兔,启动!') {
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
<div align="center"
|
|
2
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
# Bilibili-Botify
|
|
3
3
|
</div>
|
|
4
4
|
|
|
5
|
+
|
|
5
6
|
基于 [koishi](../../../../koishijs/koishi) 框架的B站推送插件
|
|
6
7
|
|
|
7
8
|
---
|
|
@@ -27,11 +28,11 @@
|
|
|
27
28
|
|
|
28
29
|
## 使用方法
|
|
29
30
|
|
|
30
|
-
|
|
31
|
+
登录B站:进行任何操作前,请先登录B站
|
|
31
32
|
|
|
32
33
|
- 使用指令 `bili login` 获取登录二维码,使用B站扫码登录
|
|
33
34
|
|
|
34
|
-
|
|
35
|
+
订阅UP主:订阅你想要推送的UP主
|
|
35
36
|
|
|
36
37
|
- 使用指令 `bili sub <uid>` 订阅需要订阅的UP主
|
|
37
38
|
- 参数说明:`uid` 为必填参数,为 `up主` 的 `uid`
|
|
@@ -46,7 +47,7 @@
|
|
|
46
47
|
- Tips:
|
|
47
48
|
- 除非使用指令 `bili sub 1194210119 -ld` ,没有加选项或只加了一个选项的指令都会再次询问是否需要订阅另一项。例如:使用指令 `bili sub 1194210119 -d` 机器人会询问是否需要订阅直播间
|
|
48
49
|
|
|
49
|
-
|
|
50
|
+
取消订阅UP主:取消订阅不需要推送的UP主
|
|
50
51
|
|
|
51
52
|
- 使用指令 `bili unsub <uid>` 取消订阅不需要订阅的UP主
|
|
52
53
|
- 参数说明:`uid` 为必填参数,为 `up主` 的 `uid`
|
|
@@ -58,6 +59,10 @@
|
|
|
58
59
|
- `bili unsub 123456 -d` 取消订阅UID为123456的UP主动态推送
|
|
59
60
|
- `bili unsub 123456 -dl` 取消订阅UID为123456的UP主动态推送和直播间
|
|
60
61
|
|
|
62
|
+
查看目前已订阅的UP主:
|
|
63
|
+
|
|
64
|
+
- 使用指令 `bili show`
|
|
65
|
+
|
|
61
66
|
## 注意事项
|
|
62
67
|
|
|
63
68
|
1. 此插件依赖于 `database` 和 `puppeteer` 服务,同时受权限控制,需要具备 `authority:3` 及以上的权限才能使用本插件提供的指令,你可以参考下方配置登录插件中的方法得到一个超级管理员账号(具有 `authority:5` 的最高权限)
|
|
@@ -71,6 +76,10 @@
|
|
|
71
76
|
3. 指令使用方法请参考 `help bili`,子命令使用方法请加 `-h` ,例如 `bili login -h`
|
|
72
77
|
4. 登录方式为二维码,输入命令 `bili login` 之后扫码登录,您的登录凭证将存储在您的本地数据库,并由您自己填写的密钥加密,所以请保管好你的密钥
|
|
73
78
|
|
|
79
|
+
## 更新日志
|
|
80
|
+
|
|
81
|
+
ver 1.0.1 修复了一些bug,提供用户自己选择动态检测时间的选项
|
|
82
|
+
|
|
74
83
|
## 感谢
|
|
75
84
|
|
|
76
85
|
感谢 [koishijs](https://github.com/koishijs/koishi) 官方提供的插件开发框架, 以及技术指导
|