koishi-plugin-kbot
Version:
A muti-function qq bot for koishi
246 lines (245 loc) • 10.1 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.bilibiliSearch = exports.bilibiliList = exports.bilibiliRemove = exports.bilibiliBatch = exports.bilibiliAdd = void 0;
/*
* @Author: Kabuda-czh
* @Date: 2023-02-03 12:57:50
* @LastEditors: Kabuda-czh
* @LastEditTime: 2023-07-24 12:00:30
* @FilePath: \KBot-App\plugins\kbot\src\plugins\bilibili\dynamic\common.ts
* @Description:
*
* Copyright (c) 2023 by Kabuda-czh, All Rights Reserved.
*/
const crypto = __importStar(require("node:crypto"));
const node_fs_1 = __importDefault(require("node:fs"));
const utils_1 = require("../utils");
const config_1 = __importDefault(require("../../../config"));
const enum_1 = require("../enum");
const render_1 = require("./render");
const _1 = require(".");
async function _getSalt(http, cookieString) {
const response = await http.get(enum_1.BilibiliDynamicType.UserNav, { headers: { cookie: cookieString } });
const data = response.data;
const { img_url, sub_url } = data.wbi_img;
const img_key = (/wbi\/(.*?)\.png/g.exec(img_url))[1] || '';
const sub_key = (/wbi\/(.*?)\.png/g.exec(sub_url))[1] || '';
const array = Array.from(img_key + sub_key);
const order = [46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5, 49, 33, 9, 42, 19, 29, 28, 14, 39, 12, 38, 41, 13, 37, 48, 7, 16, 24, 55, 40, 61, 26, 17, 0, 1, 60, 51, 30, 4, 22, 25, 54, 21, 56, 59, 6, 63, 57, 62, 11, 36, 20, 34, 44, 52];
const salt = order.map(i => array[i]).join('').slice(0, 32);
return salt;
}
async function _encrypt_w_rid(params, http, cookieString) {
const wts = Math.floor(Date.now() / 1000).toString(); // 获得时间戳
let paramsList;
if (typeof params === 'string') {
paramsList = (`${params}&wts=${wts}`).split('&');
}
else if (typeof params === 'object') {
params.wts = wts;
paramsList = Object.entries(params).map(([key, value]) => `${key}=${value}`);
}
else {
throw new TypeError(`Invalid type of params: ${typeof params}`);
}
paramsList.sort();
const salt = await _getSalt(http, cookieString);
const hash = crypto.createHash('md5');
const w_rid = hash.update(paramsList.join('&') + salt).digest('hex');
return [w_rid, wts];
}
async function fetchUserInfo(uid, ctx) {
let cookie;
try {
const { bilibiliCookiePath } = config_1.default.getInstance(ctx.baseDir).getGeneratePathData();
cookie = JSON.parse(await node_fs_1.default.promises.readFile(bilibiliCookiePath, 'utf-8'));
}
catch (e) {
_1.logger.error(`Failed to get cookie info. ${e}`);
throw new Error('cookie信息未找到, 请使用 --ck 或 --cookie 更新cookie信息');
}
const cookieString = Object.entries(cookie)
.map(([key, value]) => `${key}=${value}`)
.join('; ');
const defaultParams = {
token: '',
platform: 'web',
web_location: '1550101',
mid: uid,
};
const [w_rid, wts] = await _encrypt_w_rid(defaultParams, ctx.http, cookieString);
let res = await ctx.http.axios(enum_1.BilibiliDynamicType.UserInfo, {
method: 'GET',
params: {
...defaultParams,
w_rid,
wts,
},
headers: {
'Referer': `https://space.bilibili.com/${uid}`,
'Content-Type': 'application/json',
'Accept': 'application/json, text/plain, */*',
'Origin': 'https://space.bilibili.com',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36',
'Cookie': cookieString,
},
});
// 对接 code -509 异常返回
if (res.data.code === undefined) {
const regex = /(?<=})\s*(?={)/g;
const jsonStrings = res.data.split(regex);
if (+JSON.parse(jsonStrings[0]).code === -509)
res = JSON.parse(jsonStrings[1]);
}
if (res.data.code !== 0)
throw new Error(`[code: ${res.data.code}, message: ${res.data.message}] 请更新 cookie 信息 或 联系管理员`);
return res.data.data;
}
async function bilibiliAdd({ session }, up, list, ctx) {
let { uid, upName } = up;
if (session.channel.bilibili.dynamic.find(notification => notification.bilibiliId === uid || +notification.bilibiliId === +uid))
return '该用户已在监听列表中。';
try {
let userData;
if (uid === upName)
userData = await fetchUserInfo(uid, ctx);
if (userData)
upName = userData.name || upName;
uid = String(uid);
const notification = {
botId: `${session.platform}:${session.bot.userId || session.bot.selfId}`,
bilibiliId: uid,
bilibiliName: upName || uid,
};
session.channel.bilibili.dynamic.push(notification);
(list[uid] || (list[uid] = [])).push([
{
id: session.channel.id,
guildId: session.channel.guildId,
platform: session.platform,
bilibili: session.channel.bilibili,
},
notification,
]);
return `成功添加 up主: ${upName || uid}`;
}
catch (e) {
_1.logger.error(e);
return `请求失败,请检查 uid 是否正确或重试,${e.message}`;
}
}
exports.bilibiliAdd = bilibiliAdd;
async function bilibiliBatch({ session }, up, list, ctx) {
const { uid: uids, upName: upNames } = up;
const result = [];
const error = [];
for (let i = 0; i < uids.length; i++) {
let uid = uids[i];
let upName = upNames[i];
if (session.channel.bilibili.dynamic.find(notification => notification.bilibiliId === uid || +notification.bilibiliId === +uid))
continue;
try {
const userData = await fetchUserInfo(uid, ctx);
upName = userData.name || upName;
uid = String(uid);
const notification = {
botId: `${session.platform}:${session.bot.userId || session.bot.selfId}`,
bilibiliId: uid,
bilibiliName: upName || uid,
};
session.channel.bilibili.dynamic.push(notification);
(list[uid] || (list[uid] = [])).push([
{
id: session.channel.id,
guildId: session.channel.guildId,
platform: session.platform,
bilibili: session.channel.bilibili,
},
notification,
]);
result.push(`${upName || uid}`);
}
catch (e) {
_1.logger.error(e);
error.push(`${upName || uid}「${e.message}」`);
}
}
if (result.length)
return `成功添加 up主: \n${result.join('\n')}`;
else if (error.length)
return `添加以下 up主 失败: \n${error.join('\n')}`;
else
return '所有用户已在监听列表中。';
}
exports.bilibiliBatch = bilibiliBatch;
async function bilibiliRemove({ session }, up, list) {
let { uid } = up;
uid = String(uid);
const { channel } = session;
const index = channel.bilibili.dynamic.findIndex(notification => notification.bilibiliId === uid || +notification.bilibiliId === +uid);
if (index === -1)
return '该用户不在监听列表中。';
channel.bilibili.dynamic.splice(index, 1);
const listIndex = list[uid].findIndex(([{ id, guildId, platform }, notification]) => {
return (channel.id === id
&& channel.guildId === guildId
&& channel.platform === platform
&& notification.bilibiliId === uid);
});
if (listIndex === -1)
throw new Error('Data is out of sync.');
const name = list[uid][listIndex]?.[1].bilibiliName;
delete list[uid];
return `成功删除 up主: ${name}`;
}
exports.bilibiliRemove = bilibiliRemove;
async function bilibiliList({ session, }) {
if (session.channel.bilibili.dynamic.length === 0)
return '监听列表为空。';
return session.channel.bilibili.dynamic
.map(notification => `- ${notification.bilibiliId} 「${notification.bilibiliName}」`)
.join('\n');
}
exports.bilibiliList = bilibiliList;
async function bilibiliSearch(_, up, _list, ctx, config) {
const { uid } = up;
try {
const { data } = await (0, utils_1.getDynamic)(ctx, uid, _1.logger);
const items = data.items;
if (items.length === 0)
return '该 up 没有动态';
const dynamic = items[0].modules.module_tag?.text === '置顶' ? items[1] : items[0];
return (0, render_1.renderFunction)(ctx, dynamic, config);
}
catch (e) {
_1.logger.error(`${uid} 动态获取失败: [${e}]`);
return `动态获取失败${e.message}`;
}
}
exports.bilibiliSearch = bilibiliSearch;