karin-plugin-kkk 1.0.2-commit.9070931 → 1.0.2-commit.ced194c
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/apps/push.d.ts +2 -0
- package/lib/apps/push.js +8 -6
- package/lib/platform/bilibili/push.d.ts +10 -2
- package/lib/platform/bilibili/push.js +66 -23
- package/lib/platform/douyin/push.d.ts +4 -2
- package/lib/platform/douyin/push.js +55 -8
- package/package.json +2 -2
- package/resources/template/bilibili/css/userlist.css +77 -0
- package/resources/template/bilibili/html/userlist.html +31 -0
- package/resources/template/douyin/css/userlist.css +77 -0
- package/resources/template/douyin/html/userlist.html +26 -0
- package/resources/template/help/html/index.html +2 -0
package/lib/apps/push.d.ts
CHANGED
|
@@ -3,4 +3,6 @@ export declare const bilibiliPush: false | import("node-karin").Task;
|
|
|
3
3
|
export declare const forcePush: import("node-karin").Command<"message.group">;
|
|
4
4
|
export declare const setdyPush: import("node-karin").Command<"message.group">;
|
|
5
5
|
export declare const setbiliPush: import("node-karin").Command<"message.group">;
|
|
6
|
+
export declare const bilibiliPushList: import("node-karin").Command<keyof import("node-karin").MessageEventMap>;
|
|
7
|
+
export declare const douyinPushList: import("node-karin").Command<keyof import("node-karin").MessageEventMap>;
|
|
6
8
|
export declare const changeBotID: import("node-karin").Command<keyof import("node-karin").MessageEventMap>;
|
package/lib/apps/push.js
CHANGED
|
@@ -24,21 +24,23 @@ export const forcePush = karin.command(/#(抖音|B站)(全部)?强制推送/, as
|
|
|
24
24
|
}, { name: '𝑪𝒊𝒂𝒍𝒍𝒐~(∠・ω< )⌒★', perm: 'master', event: 'message.group' });
|
|
25
25
|
export const setdyPush = karin.command(/^#设置抖音推送/, async (e) => {
|
|
26
26
|
const data = await getDouyinData('搜索数据', Config.cookies.douyin, { query: e.msg.replace(/^#设置抖音推送/, '') });
|
|
27
|
-
await
|
|
28
|
-
if (Config.douyin.push.switch === false)
|
|
29
|
-
await e.reply('请发送「#kkk设置抖音推送开启」以进行推送');
|
|
27
|
+
await new DouYinpush(e).setting(data);
|
|
30
28
|
return true;
|
|
31
29
|
}, { name: 'kkk-推送功能-设置', event: 'message.group', perm: Config.douyin.push.permission, dsbAdapter: ['qqbot'] });
|
|
32
30
|
export const setbiliPush = karin.command(/^#设置[bB]站推送(?:[Uu][Ii][Dd]:)?(\d+)$/, async (e) => {
|
|
33
31
|
const match = /^#设置[bB]站推送(?:UID:)?(\d+)$/.exec(e.msg);
|
|
34
32
|
if (match && match[1]) {
|
|
35
33
|
const data = await getBilibiliData('用户主页数据', Config.cookies.bilibili, { host_mid: match[1] });
|
|
36
|
-
await
|
|
37
|
-
if (Config.bilibili.push.switch === false)
|
|
38
|
-
await e.reply('请发送「#kkk设置B站推送开启」以进行推送');
|
|
34
|
+
await new Bilibilipush(e).setting(data);
|
|
39
35
|
}
|
|
40
36
|
return true;
|
|
41
37
|
}, { name: 'kkk-推送功能-设置', event: 'message.group', perm: Config.bilibili.push.permission, dsbAdapter: ['qqbot'] });
|
|
38
|
+
export const bilibiliPushList = karin.command(/^#?[bB]站推送列表$/, async (e) => {
|
|
39
|
+
await new Bilibilipush(e).renderPushList(Config.pushlist.bilibili);
|
|
40
|
+
});
|
|
41
|
+
export const douyinPushList = karin.command(/^#?抖音推送列表$/, async (e) => {
|
|
42
|
+
await new DouYinpush(e).renderPushList(Config.pushlist.douyin);
|
|
43
|
+
});
|
|
42
44
|
export const changeBotID = karin.command(/^#kkk设置推送机器人/, async (e) => {
|
|
43
45
|
const newDouyinlist = Config.pushlist.douyin.map(item => {
|
|
44
46
|
// 操作每个 group_id
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Message } from 'node-karin';
|
|
2
2
|
import { AllDataType, Base, BilibiliDBType } from '../../module/index.js';
|
|
3
|
+
import { bilibiliPushItem } from '../../types/config/pushlist.js';
|
|
3
4
|
/** 已支持推送的动态类型 */
|
|
4
5
|
export declare enum DynamicType {
|
|
5
6
|
AV = "DYNAMIC_TYPE_AV",
|
|
@@ -50,7 +51,7 @@ export declare class Bilibilipush extends Base {
|
|
|
50
51
|
* 根据配置文件获取UP当天的动态列表。
|
|
51
52
|
* @returns
|
|
52
53
|
*/
|
|
53
|
-
getDynamicList(): Promise<{
|
|
54
|
+
getDynamicList(userList: bilibiliPushItem[]): Promise<{
|
|
54
55
|
willbepushlist: WillBePushList;
|
|
55
56
|
DBdata: Record<string, BilibiliDBType>;
|
|
56
57
|
}>;
|
|
@@ -66,7 +67,7 @@ export declare class Bilibilipush extends Base {
|
|
|
66
67
|
* @param data 包含 card 对象。
|
|
67
68
|
* @returns 操作成功或失败的消息字符串。
|
|
68
69
|
*/
|
|
69
|
-
setting(data: any): Promise<
|
|
70
|
+
setting(data: any): Promise<void>;
|
|
70
71
|
/**
|
|
71
72
|
* 检查并更新配置文件中指定用户的备注信息。
|
|
72
73
|
* 该函数会遍历配置文件中的用户列表,对于没有备注或备注为空的用户,会从外部数据源获取其备注信息,并更新到配置文件中。
|
|
@@ -77,5 +78,12 @@ export declare class Bilibilipush extends Base {
|
|
|
77
78
|
* @param data 处理完成的推送列表
|
|
78
79
|
*/
|
|
79
80
|
forcepush(data: WillBePushList): Promise<void>;
|
|
81
|
+
/**
|
|
82
|
+
* 渲染推送列表图片
|
|
83
|
+
* @param pushList B站配置文件的推送列表
|
|
84
|
+
* @param host_mid 优先展示的UP主的UID
|
|
85
|
+
* @returns
|
|
86
|
+
*/
|
|
87
|
+
renderPushList(pushList: bilibiliPushItem[], host_mid?: string): Promise<true | undefined>;
|
|
80
88
|
}
|
|
81
89
|
export {};
|
|
@@ -36,7 +36,7 @@ export class Bilibilipush extends Base {
|
|
|
36
36
|
if (await this.checkremark())
|
|
37
37
|
return true;
|
|
38
38
|
try {
|
|
39
|
-
const data = await this.getDynamicList();
|
|
39
|
+
const data = await this.getDynamicList(Config.pushlist.bilibili);
|
|
40
40
|
const pushdata = this.excludeAlreadyPushed(data.willbepushlist, data.DBdata);
|
|
41
41
|
if (Object.keys(pushdata).length === 0)
|
|
42
42
|
return true;
|
|
@@ -380,21 +380,11 @@ export class Bilibilipush extends Base {
|
|
|
380
380
|
* 根据配置文件获取UP当天的动态列表。
|
|
381
381
|
* @returns
|
|
382
382
|
*/
|
|
383
|
-
async getDynamicList() {
|
|
383
|
+
async getDynamicList(userList) {
|
|
384
384
|
const willbepushlist = {};
|
|
385
385
|
try {
|
|
386
|
-
for (const item of
|
|
386
|
+
for (const item of userList) {
|
|
387
387
|
const dynamic_list = await fetchBilibiliData('user_dynamic', { host_mid: item.host_mid });
|
|
388
|
-
const ALL_DBdata = await DB.FindAll('bilibili');
|
|
389
|
-
// 将数据库中的 group_id 转换为 Set,便于后续检查是否存在
|
|
390
|
-
const dbGroupIds = new Set(Object.keys(ALL_DBdata).map(groupIdStr => groupIdStr.split(':')[0]));
|
|
391
|
-
// 配置文件中的 group_id 转换为对象数组,每个对象包含群号和机器人账号
|
|
392
|
-
const configGroupIdObjs = item.group_id.map(groupIdStr => {
|
|
393
|
-
const [groupId, robotId] = groupIdStr.split(':');
|
|
394
|
-
return { groupId, robotId };
|
|
395
|
-
});
|
|
396
|
-
// 找出新添加的群组ID
|
|
397
|
-
const newGroupIds = configGroupIdObjs.filter(groupIdObj => !dbGroupIds.has(groupIdObj.groupId));
|
|
398
388
|
if (dynamic_list.data.items.length > 0) {
|
|
399
389
|
// 遍历接口返回的视频列表
|
|
400
390
|
for (const dynamic of dynamic_list.data.items) {
|
|
@@ -405,10 +395,10 @@ export class Bilibilipush extends Base {
|
|
|
405
395
|
const is_top = dynamic.modules.module_tag?.text === '置顶'; // 是否为置顶
|
|
406
396
|
let shouldPush = false; // 是否列入推送数组
|
|
407
397
|
// 条件判断,以下任何一项成立都将进行推送:如果是置顶且发布时间在一天内 || 如果是置顶作品且有新的群组且发布时间在一天内 || 如果有新的群组且发布时间在一天内
|
|
408
|
-
logger.debug(`前期获取该动态基本信息:\n动态ID:${dynamic.id_str}\n发布时间:${Common.convertTimestampToDateTime(Number(createTime))}\n发布时间戳(s):${createTime}\n时间差(ms):${timeDifference}\n是否置顶:${is_top}\n
|
|
409
|
-
if ((is_top && timeDifference < 86400000) || (timeDifference < 86400000)
|
|
398
|
+
logger.debug(`前期获取该动态基本信息:\n动态ID:${dynamic.id_str}\n发布时间:${Common.convertTimestampToDateTime(Number(createTime))}\n发布时间戳(s):${createTime}\n时间差(ms):${timeDifference}\n是否置顶:${is_top}\n是否在一天内:${timeDifference < 86400000 ? logger.green('true') : logger.red('false')}`);
|
|
399
|
+
if ((is_top && timeDifference < 86400000) || (timeDifference < 86400000)) {
|
|
410
400
|
shouldPush = true;
|
|
411
|
-
logger.debug(logger.green(`根据以上判断,shoulPush 为 true
|
|
401
|
+
logger.debug(logger.green(`根据以上判断,shoulPush 为 true,将对该动态纳入当天推送列表:https://t.bilibili.com/${dynamic.id_str}\n`));
|
|
412
402
|
}
|
|
413
403
|
else
|
|
414
404
|
logger.debug(logger.yellow(`根据以上判断,shoulPush 为 false,跳过该动态:https://t.bilibili.com/${dynamic.id_str}\n`));
|
|
@@ -499,7 +489,6 @@ export class Bilibilipush extends Base {
|
|
|
499
489
|
*/
|
|
500
490
|
async setting(data) {
|
|
501
491
|
const groupInfo = await this.e.bot.getGroupInfo('groupId' in this.e && this.e.groupId ? this.e.groupId : '');
|
|
502
|
-
let msg;
|
|
503
492
|
const host_mid = data.data.card.mid;
|
|
504
493
|
const config = Config.pushlist; // 读取配置文件
|
|
505
494
|
const group_id = 'groupId' in this.e && this.e.groupId ? this.e.groupId : '';
|
|
@@ -528,7 +517,7 @@ export class Bilibilipush extends Base {
|
|
|
528
517
|
// 如果已存在相同的 group_id,则删除它
|
|
529
518
|
existingItem.group_id.splice(groupIndexToRemove, 1);
|
|
530
519
|
logger.info(`\n删除成功!${data.data.card.name}\nUID:${host_mid}`);
|
|
531
|
-
|
|
520
|
+
await this.e.reply(`群:${groupInfo.groupName}(${group_id})\n删除成功!${data.data.card.name}\nUID:${host_mid}`);
|
|
532
521
|
// 如果删除后 group_id 数组为空,则删除整个属性
|
|
533
522
|
if (existingItem.group_id.length === 0) {
|
|
534
523
|
const index = config.bilibili.indexOf(existingItem);
|
|
@@ -542,8 +531,12 @@ export class Bilibilipush extends Base {
|
|
|
542
531
|
}
|
|
543
532
|
// 否则,将新的 group_id 添加到该 host_mid 对应的数组中
|
|
544
533
|
existingItem.group_id.push(`${group_id}:${this.e.selfId}`);
|
|
545
|
-
|
|
534
|
+
await this.e.reply(`群:${groupInfo.groupName}(${group_id})\n添加成功!${data.data.card.name}\nUID:${host_mid}`);
|
|
535
|
+
if (Config.bilibili.push.switch === false)
|
|
536
|
+
await this.e.reply('请发送「#kkk设置B站推送开启」以进行推送');
|
|
546
537
|
logger.info(`\n设置成功!${data.data.card.name}\nUID:${host_mid}`);
|
|
538
|
+
// 渲染状态图片
|
|
539
|
+
await this.renderPushList(config.bilibili, host_mid);
|
|
547
540
|
}
|
|
548
541
|
}
|
|
549
542
|
else {
|
|
@@ -553,11 +546,14 @@ export class Bilibilipush extends Base {
|
|
|
553
546
|
}
|
|
554
547
|
// 不存在相同的 host_mid,新增一个配置项
|
|
555
548
|
config.bilibili.push({ host_mid, group_id: [`${group_id}:${this.e.selfId}`], remark: data.data.card.name });
|
|
556
|
-
|
|
549
|
+
await this.e.reply(`群:${groupInfo.groupName}(${group_id})\n添加成功!${data.data.card.name}\nUID:${host_mid}`);
|
|
550
|
+
if (Config.bilibili.push.switch === false)
|
|
551
|
+
await this.e.reply('请发送「#kkk设置B站推送开启」以进行推送');
|
|
552
|
+
// 渲染状态图片
|
|
553
|
+
await this.renderPushList(config.bilibili, host_mid);
|
|
557
554
|
}
|
|
558
555
|
// 更新配置文件
|
|
559
556
|
Config.Modify('pushlist', 'bilibili', config.bilibili);
|
|
560
|
-
return msg;
|
|
561
557
|
}
|
|
562
558
|
/**
|
|
563
559
|
* 检查并更新配置文件中指定用户的备注信息。
|
|
@@ -606,6 +602,41 @@ export class Bilibilipush extends Base {
|
|
|
606
602
|
}
|
|
607
603
|
await this.getdata(data);
|
|
608
604
|
}
|
|
605
|
+
/**
|
|
606
|
+
* 渲染推送列表图片
|
|
607
|
+
* @param pushList B站配置文件的推送列表
|
|
608
|
+
* @param host_mid 优先展示的UP主的UID
|
|
609
|
+
* @returns
|
|
610
|
+
*/
|
|
611
|
+
async renderPushList(pushList, host_mid) {
|
|
612
|
+
const groupInfo = await this.e.bot.getGroupInfo('groupId' in this.e && this.e.groupId ? this.e.groupId : '');
|
|
613
|
+
const filteredList = pushList.filter(item => item.group_id.some(group => group.split(':')[0] === groupInfo.groupId));
|
|
614
|
+
if (filteredList.length === 0) {
|
|
615
|
+
await this.e.reply(`当前群:${groupInfo.groupName}(${groupInfo.groupId})\n没有设置任何B站UP推送!\n可使用「#设置B站推送 + UP主UID」进行设置`);
|
|
616
|
+
return true;
|
|
617
|
+
}
|
|
618
|
+
/** 用户的今日动态列表 */
|
|
619
|
+
const DynamicList = await this.getDynamicList(filteredList);
|
|
620
|
+
const renderOpt = [];
|
|
621
|
+
for (const dynamic_id in removeDuplicateHostMid(DynamicList.willbepushlist)) {
|
|
622
|
+
const item = DynamicList.willbepushlist[dynamic_id];
|
|
623
|
+
const userInfo = await getBilibiliData('用户主页数据', Config.cookies.bilibili, { host_mid: item.host_mid });
|
|
624
|
+
renderOpt.push({
|
|
625
|
+
avatar_img: userInfo.data.card.face,
|
|
626
|
+
username: userInfo.data.card.name,
|
|
627
|
+
host_mid,
|
|
628
|
+
fans: this.count(userInfo.data.follower),
|
|
629
|
+
total_favorited: this.count(userInfo.data.like_num),
|
|
630
|
+
following_count: this.count(userInfo.data.card.attention),
|
|
631
|
+
willPushNum: 999
|
|
632
|
+
});
|
|
633
|
+
}
|
|
634
|
+
// 将此次设置推送的用户排序到首位
|
|
635
|
+
if (host_mid)
|
|
636
|
+
renderOpt.sort((a, b) => (a.host_mid === host_mid ? -1 : b.host_mid === host_mid ? 1 : 0));
|
|
637
|
+
const img = await Render('bilibili/userlist', { renderOpt });
|
|
638
|
+
await this.e.reply(img);
|
|
639
|
+
}
|
|
609
640
|
}
|
|
610
641
|
/**
|
|
611
642
|
* 将换行符替换为HTML的<br>标签。
|
|
@@ -649,13 +680,13 @@ function extractEmojisData(data) {
|
|
|
649
680
|
* @returns
|
|
650
681
|
*/
|
|
651
682
|
const skipDynamic = (Dynamic_Data) => {
|
|
652
|
-
for (const banWord of Config.
|
|
683
|
+
for (const banWord of Config.bilibili.push.banWords) {
|
|
653
684
|
if (Dynamic_Data.modules.module_dynamic.major?.archive?.title.includes(banWord) || Dynamic_Data.modules.module_dynamic.desc?.text?.includes(banWord)) {
|
|
654
685
|
logger.mark(`动态:${logger.green(`https://t.bilibili.com/${Dynamic_Data.id_str}`)} 包含屏蔽词:「${logger.red(banWord)}」,跳过推送`);
|
|
655
686
|
return true;
|
|
656
687
|
}
|
|
657
688
|
}
|
|
658
|
-
if (Dynamic_Data.type ===
|
|
689
|
+
if (Dynamic_Data.type === DynamicType.DRAW || Dynamic_Data.type === DynamicType.FORWARD) {
|
|
659
690
|
for (const banTag of Config.bilibili.push.banTags) {
|
|
660
691
|
for (const tag of Dynamic_Data.modules.module_dynamic.desc.rich_text_nodes) {
|
|
661
692
|
if (tag.orig_text.includes(banTag)) {
|
|
@@ -667,3 +698,15 @@ const skipDynamic = (Dynamic_Data) => {
|
|
|
667
698
|
}
|
|
668
699
|
return false;
|
|
669
700
|
};
|
|
701
|
+
const removeDuplicateHostMid = (willBePushList) => {
|
|
702
|
+
const result = {};
|
|
703
|
+
const seenHostMids = new Set();
|
|
704
|
+
for (const key in willBePushList) {
|
|
705
|
+
const item = willBePushList[key];
|
|
706
|
+
if (!seenHostMids.has(item.host_mid)) {
|
|
707
|
+
result[key] = item;
|
|
708
|
+
seenHostMids.add(item.host_mid);
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
return result;
|
|
712
|
+
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Message } from 'node-karin';
|
|
2
2
|
import { AllDataType, Base, DouyinDBType } from '../../module/index.js';
|
|
3
|
+
import { douyinPushItem } from '../../types/config/pushlist.js';
|
|
3
4
|
/** 每个推送项的类型定义 */
|
|
4
5
|
interface PushItem {
|
|
5
6
|
/** 博主的昵称 */
|
|
@@ -44,7 +45,7 @@ export declare class DouYinpush extends Base {
|
|
|
44
45
|
* 根据配置文件获取UP当天的动态列表。
|
|
45
46
|
* @returns
|
|
46
47
|
*/
|
|
47
|
-
getDynamicList(): Promise<{
|
|
48
|
+
getDynamicList(userList: douyinPushItem[]): Promise<{
|
|
48
49
|
willbepushlist: WillBePushList;
|
|
49
50
|
DBdata: Record<string, DouyinDBType>;
|
|
50
51
|
}>;
|
|
@@ -67,6 +68,7 @@ export declare class DouYinpush extends Base {
|
|
|
67
68
|
* @param data 抖音的搜索结果数据。需要接口返回的原始数据
|
|
68
69
|
* @returns 操作成功或失败的消息字符串。
|
|
69
70
|
*/
|
|
70
|
-
setting(data: any): Promise<
|
|
71
|
+
setting(data: any): Promise<void>;
|
|
72
|
+
renderPushList(pushList: douyinPushItem[], short_id?: string): Promise<true | undefined>;
|
|
71
73
|
}
|
|
72
74
|
export {};
|
|
@@ -25,7 +25,7 @@ export class DouYinpush extends Base {
|
|
|
25
25
|
if (await this.checkremark())
|
|
26
26
|
return true;
|
|
27
27
|
try {
|
|
28
|
-
const data = await this.getDynamicList();
|
|
28
|
+
const data = await this.getDynamicList(Config.pushlist.douyin);
|
|
29
29
|
const pushdata = this.excludeAlreadyPushed(data.willbepushlist, data.DBdata);
|
|
30
30
|
if (Object.keys(pushdata).length === 0)
|
|
31
31
|
return true;
|
|
@@ -227,11 +227,11 @@ export class DouYinpush extends Base {
|
|
|
227
227
|
* 根据配置文件获取UP当天的动态列表。
|
|
228
228
|
* @returns
|
|
229
229
|
*/
|
|
230
|
-
async getDynamicList() {
|
|
230
|
+
async getDynamicList(userList) {
|
|
231
231
|
const willbepushlist = {};
|
|
232
232
|
const DBdata = await DB.FindAll('douyin');
|
|
233
233
|
try {
|
|
234
|
-
for (const item of
|
|
234
|
+
for (const item of userList) {
|
|
235
235
|
const videolist = await getDouyinData('用户主页视频列表数据', Config.cookies.douyin, { sec_uid: item.sec_uid });
|
|
236
236
|
const userinfo = await getDouyinData('用户主页数据', Config.cookies.douyin, { sec_uid: item.sec_uid });
|
|
237
237
|
if (videolist.aweme_list.length > 0) {
|
|
@@ -477,7 +477,7 @@ export class DouYinpush extends Base {
|
|
|
477
477
|
// 如果存在相同的 group_id,则删除它
|
|
478
478
|
existingItem.group_id.splice(groupIndexToRemove, 1);
|
|
479
479
|
logger.info(`\n删除成功!${UserInfoData.user.nickname}\n抖音号:${user_shortid}\nsec_uid${UserInfoData.user.sec_uid}`);
|
|
480
|
-
|
|
480
|
+
await this.e.reply(`群:${groupInfo.groupName}(${group_id})\n删除成功!${UserInfoData.user.nickname}\n抖音号:${user_shortid}`);
|
|
481
481
|
// 如果删除后 group_id 数组为空,则删除整个属性
|
|
482
482
|
if (existingItem.group_id.length === 0) {
|
|
483
483
|
const index = config.douyin.indexOf(existingItem);
|
|
@@ -491,8 +491,12 @@ export class DouYinpush extends Base {
|
|
|
491
491
|
}
|
|
492
492
|
// 否则,将新的 group_id 添加到该 sec_uid 对应的数组中
|
|
493
493
|
existingItem.group_id.push(`${group_id}:${this.e.selfId}`);
|
|
494
|
-
|
|
494
|
+
await this.e.reply(`群:${groupInfo.groupName}(${group_id})\n添加成功!${UserInfoData.user.nickname}\n抖音号:${user_shortid}`);
|
|
495
|
+
if (Config.douyin.push.switch === false)
|
|
496
|
+
await this.e.reply('请发送「#kkk设置B站推送开启」以进行推送');
|
|
495
497
|
logger.info(`\n设置成功!${UserInfoData.user.nickname}\n抖音号:${user_shortid}\nsec_uid${UserInfoData.user.sec_uid}`);
|
|
498
|
+
// 渲染状态图片
|
|
499
|
+
await this.renderPushList(config.douyin, user_shortid);
|
|
496
500
|
}
|
|
497
501
|
}
|
|
498
502
|
else {
|
|
@@ -502,16 +506,47 @@ export class DouYinpush extends Base {
|
|
|
502
506
|
}
|
|
503
507
|
// 如果不存在相同的 sec_uid,则新增一个属性
|
|
504
508
|
config.douyin.push({ sec_uid, group_id: [`${group_id}:${this.e.selfId}`], remark: UserInfoData.user.nickname, short_id: user_shortid });
|
|
505
|
-
|
|
509
|
+
await this.e.reply(`群:${groupInfo.groupName}(${group_id})\n添加成功!${UserInfoData.user.nickname}\n抖音号:${user_shortid}`);
|
|
510
|
+
if (Config.douyin.push.switch === false)
|
|
511
|
+
await this.e.reply('请发送「#kkk设置B站推送开启」以进行推送');
|
|
512
|
+
// 渲染状态图片
|
|
513
|
+
await this.renderPushList(config.douyin, user_shortid);
|
|
506
514
|
}
|
|
507
515
|
Config.Modify('pushlist', 'douyin', config.douyin);
|
|
508
|
-
return msg;
|
|
509
516
|
}
|
|
510
517
|
catch (error) {
|
|
511
518
|
logger.error(error);
|
|
512
|
-
return '无法获取用户信息,请确认抖音号是否正确';
|
|
513
519
|
}
|
|
514
520
|
}
|
|
521
|
+
async renderPushList(pushList, short_id) {
|
|
522
|
+
const groupInfo = await this.e.bot.getGroupInfo('groupId' in this.e && this.e.groupId ? this.e.groupId : '');
|
|
523
|
+
const filteredList = pushList.filter(item => item.group_id.some(group => group.split(':')[0] === groupInfo.groupId));
|
|
524
|
+
if (filteredList.length === 0) {
|
|
525
|
+
await this.e.reply(`当前群:${groupInfo.groupName}(${groupInfo.groupId})\n没有设置任何抖音博主推送!\n可使用「#设置抖音推送 + 抖音号」进行设置`);
|
|
526
|
+
return true;
|
|
527
|
+
}
|
|
528
|
+
/** 用户的今日动态列表 */
|
|
529
|
+
const DynamicList = await this.getDynamicList(filteredList);
|
|
530
|
+
const renderOpt = [];
|
|
531
|
+
for (const dynamic_id in removeDuplicateHostMid(DynamicList.willbepushlist)) {
|
|
532
|
+
const item = DynamicList.willbepushlist[dynamic_id];
|
|
533
|
+
const userInfo = await getDouyinData('用户主页数据', Config.cookies.douyin, { sec_uid: item.sec_uid });
|
|
534
|
+
renderOpt.push({
|
|
535
|
+
avatar_img: userInfo.user.avatar_larger.url_list[0],
|
|
536
|
+
username: userInfo.user.nickname,
|
|
537
|
+
short_id: userInfo.user.unique_id === '' ? userInfo.user.short_id : userInfo.user.unique_id,
|
|
538
|
+
fans: this.count(userInfo.user.follower_count),
|
|
539
|
+
total_favorited: this.count(userInfo.user.total_favorited),
|
|
540
|
+
following_count: this.count(userInfo.user.following_count),
|
|
541
|
+
willPushNum: 999
|
|
542
|
+
});
|
|
543
|
+
}
|
|
544
|
+
// 将此次设置推送的用户排序到首位
|
|
545
|
+
if (short_id)
|
|
546
|
+
renderOpt.sort((a, b) => (a.short_id === short_id ? -1 : b.short_id === short_id ? 1 : 0));
|
|
547
|
+
const img = await Render('douyin/userlist', { renderOpt });
|
|
548
|
+
await this.e.reply(img);
|
|
549
|
+
}
|
|
515
550
|
}
|
|
516
551
|
/**
|
|
517
552
|
* 判断标题是否有屏蔽词或屏蔽标签
|
|
@@ -596,3 +631,15 @@ const findMatchingSecUid = (DBdata, secUidToCheck) => {
|
|
|
596
631
|
}
|
|
597
632
|
return '';
|
|
598
633
|
};
|
|
634
|
+
const removeDuplicateHostMid = (willBePushList) => {
|
|
635
|
+
const result = {};
|
|
636
|
+
const seenHostMids = new Set();
|
|
637
|
+
for (const key in willBePushList) {
|
|
638
|
+
const item = willBePushList[key];
|
|
639
|
+
if (!seenHostMids.has(item.sec_uid)) {
|
|
640
|
+
result[key] = item;
|
|
641
|
+
seenHostMids.add(item.sec_uid);
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
return result;
|
|
645
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "karin-plugin-kkk",
|
|
3
|
-
"version": "1.0.2-commit.
|
|
3
|
+
"version": "1.0.2-commit.ced194c",
|
|
4
4
|
"description": "a Karin video parsing tool",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"karin-plugin",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"log": "karin log",
|
|
46
46
|
"up": "karin up",
|
|
47
47
|
"init": "karin init",
|
|
48
|
-
"dev": "
|
|
48
|
+
"dev": "tsx watch --include \"./src/**/*\" node_modules/node-karin/dist/index.js",
|
|
49
49
|
"ts": "karin ts",
|
|
50
50
|
"watch": "karin watch"
|
|
51
51
|
},
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
body.light-mode {
|
|
2
|
+
--background-color: #fff;
|
|
3
|
+
--text-color: #000;
|
|
4
|
+
--shadow-color: rgba(0, 0, 0, 0.3);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
body.dark-mode {
|
|
9
|
+
--background-color: #4d4d4d;
|
|
10
|
+
--text-color: #ededed;
|
|
11
|
+
--shadow-color: rgb(6 6 6);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.user-list {
|
|
15
|
+
display: flex;
|
|
16
|
+
list-style-type: none;
|
|
17
|
+
padding: 0;
|
|
18
|
+
align-items: center;
|
|
19
|
+
flex-direction: column-reverse;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.user-item {
|
|
23
|
+
display: flex;
|
|
24
|
+
width: 90%;
|
|
25
|
+
align-items: center;
|
|
26
|
+
background-color: var(--background-color);
|
|
27
|
+
padding: 35px 45px;
|
|
28
|
+
border-radius: 25px;
|
|
29
|
+
box-shadow: 0 4px 20px 0px var(--shadow-color);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.user-avatar {
|
|
33
|
+
width: 150px;
|
|
34
|
+
height: 150px;
|
|
35
|
+
border-radius: 50%;
|
|
36
|
+
margin-right: 50px;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.user-info {
|
|
40
|
+
flex-grow: 1;
|
|
41
|
+
display: flex;
|
|
42
|
+
justify-content: space-between;
|
|
43
|
+
align-items: center;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.user-details {
|
|
47
|
+
display: flex;
|
|
48
|
+
flex-direction: column;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.user-name {
|
|
52
|
+
color: var(--text-color);
|
|
53
|
+
font-size: 55px;
|
|
54
|
+
margin-bottom: 15px;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.user-stats {
|
|
58
|
+
display: flex;
|
|
59
|
+
gap: 30px;
|
|
60
|
+
color: var(--text-color);
|
|
61
|
+
font-size: 25px;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.pending-push {
|
|
65
|
+
color: #ffffff;
|
|
66
|
+
padding: 10px 20px;
|
|
67
|
+
border-radius: 10px;
|
|
68
|
+
font-size: 40px;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.pending-push.active {
|
|
72
|
+
background-color: #00a1d6;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.pending-push.inactive {
|
|
76
|
+
background-color: #dddddd;
|
|
77
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{{extend defaultLayout}} {{block 'css'}}
|
|
2
|
+
<script src="{{_res_path}}template/extend/js/qrcode.min.js"></script>
|
|
3
|
+
<link rel="stylesheet" type="text/css" href="{{_res_path}}template/bilibili/css/userlist.css" />
|
|
4
|
+
{{/block}} {{block 'main'}}
|
|
5
|
+
|
|
6
|
+
<ul class="user-list">
|
|
7
|
+
{{each renderOpt val}}
|
|
8
|
+
<li class="user-item">
|
|
9
|
+
<img src="{{val.avatar_img}}" alt="用户头像" class="user-avatar">
|
|
10
|
+
<div class="user-info">
|
|
11
|
+
<div class="user-details">
|
|
12
|
+
<span class="user-name">{{val.username}}</span>
|
|
13
|
+
<div class="user-stats">
|
|
14
|
+
<span>UID: {{val.host_mid}}</span>
|
|
15
|
+
<span>粉丝: {{val.fans}}</span>
|
|
16
|
+
<span>获赞: {{val.total_favorited}}</span>
|
|
17
|
+
<span>关注: {{val.following_count}}</span>
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
<!-- {{if val.willPushNum > 0}}
|
|
21
|
+
<span class="pending-push active">待推送: {{val.willPushNum}}</span>
|
|
22
|
+
{{else}}
|
|
23
|
+
<span class="pending-push inactive">待推送: {{val.willPushNum}}</span>
|
|
24
|
+
{{/if}} -->
|
|
25
|
+
</div>
|
|
26
|
+
</li>
|
|
27
|
+
<div style="height: 40px;"></div>
|
|
28
|
+
{{/each}}
|
|
29
|
+
</ul>
|
|
30
|
+
|
|
31
|
+
{{/block}}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
body.light-mode {
|
|
2
|
+
--background-color: #fff;
|
|
3
|
+
--text-color: #000;
|
|
4
|
+
--shadow-color: rgba(0, 0, 0, 0.3);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
body.dark-mode {
|
|
9
|
+
--background-color: #4d4d4d;
|
|
10
|
+
--text-color: #ededed;
|
|
11
|
+
--shadow-color: rgb(6 6 6);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.user-list {
|
|
15
|
+
display: flex;
|
|
16
|
+
list-style-type: none;
|
|
17
|
+
padding: 0;
|
|
18
|
+
align-items: center;
|
|
19
|
+
flex-direction: column-reverse;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.user-item {
|
|
23
|
+
display: flex;
|
|
24
|
+
width: 90%;
|
|
25
|
+
align-items: center;
|
|
26
|
+
background-color: var(--background-color);
|
|
27
|
+
padding: 35px 45px;
|
|
28
|
+
border-radius: 25px;
|
|
29
|
+
box-shadow: 0 4px 20px 0px var(--shadow-color);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.user-avatar {
|
|
33
|
+
width: 150px;
|
|
34
|
+
height: 150px;
|
|
35
|
+
border-radius: 50%;
|
|
36
|
+
margin-right: 50px;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.user-info {
|
|
40
|
+
flex-grow: 1;
|
|
41
|
+
display: flex;
|
|
42
|
+
justify-content: space-between;
|
|
43
|
+
align-items: center;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.user-details {
|
|
47
|
+
display: flex;
|
|
48
|
+
flex-direction: column;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.user-name {
|
|
52
|
+
color: var(--text-color);
|
|
53
|
+
font-size: 55px;
|
|
54
|
+
margin-bottom: 15px;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.user-stats {
|
|
58
|
+
display: flex;
|
|
59
|
+
gap: 30px;
|
|
60
|
+
color: var(--text-color);
|
|
61
|
+
font-size: 25px;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.pending-push {
|
|
65
|
+
color: #ffffff;
|
|
66
|
+
padding: 10px 20px;
|
|
67
|
+
border-radius: 10px;
|
|
68
|
+
font-size: 40px;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.pending-push.active {
|
|
72
|
+
background-color: #00a1d6;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.pending-push.inactive {
|
|
76
|
+
background-color: #dddddd;
|
|
77
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{{extend defaultLayout}} {{block 'css'}}
|
|
2
|
+
<script src="{{_res_path}}template/extend/js/qrcode.min.js"></script>
|
|
3
|
+
<link rel="stylesheet" type="text/css" href="{{_res_path}}template/bilibili/css/userlist.css" />
|
|
4
|
+
{{/block}} {{block 'main'}}
|
|
5
|
+
|
|
6
|
+
<ul class="user-list">
|
|
7
|
+
{{each renderOpt val index}}
|
|
8
|
+
<li class="user-item" data-index="{{index}}">
|
|
9
|
+
<img src="{{val.avatar_img}}" alt="用户头像" class="user-avatar">
|
|
10
|
+
<div class="user-info">
|
|
11
|
+
<div class="user-details">
|
|
12
|
+
<span class="user-name">{{val.username}}</span>
|
|
13
|
+
<div class="user-stats">
|
|
14
|
+
<span>UID: {{val.short_id}}</span>
|
|
15
|
+
<span>粉丝: {{val.fans}}</span>
|
|
16
|
+
<span>获赞: {{val.total_favorited}}</span>
|
|
17
|
+
<span>关注: {{val.following_count}}</span>
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
</li>
|
|
22
|
+
<div style="height: 40px;"></div>
|
|
23
|
+
{{/each}}
|
|
24
|
+
</ul>
|
|
25
|
+
|
|
26
|
+
{{/block}}
|
|
@@ -24,6 +24,8 @@
|
|
|
24
24
|
<div class="menu-description">全部强制推送:手动模拟一次定时任务;<br />强制推送:只在触发群模拟一次定时任务;<br />已推送过的不会再推送</div>
|
|
25
25
|
<div class="menu-item">#kkk设置推送机器人 + Bot ID</div>
|
|
26
26
|
<div class="menu-description">一键更换推送机器人</div>
|
|
27
|
+
<div class="menu-item">#抖音/B站推送列表</div>
|
|
28
|
+
<div class="menu-description">查看当前群的订阅推送列表</div>
|
|
27
29
|
</div>
|
|
28
30
|
</div>
|
|
29
31
|
<div class="menu-container">
|