koishi-plugin-kbot
Version:
A muti-function qq bot for koishi
191 lines (190 loc) • 7.82 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.renderFunction = void 0;
/*
* @Author: Kabuda-czh
* @Date: 2023-02-03 13:38:46
* @LastEditors: Kabuda-czh
* @LastEditTime: 2023-07-24 12:02:05
* @FilePath: \KBot-App\plugins\kbot\src\plugins\bilibili\dynamic\render.ts
* @Description:
*
* Copyright (c) 2023 by Kabuda-czh, All Rights Reserved.
*/
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
const koishi_1 = require("koishi");
const utils_1 = require("../../utils");
const enum_1 = require("../enum");
const config_1 = __importDefault(require("../../../config"));
const _1 = require(".");
async function renderFunction(ctx, item, config) {
try {
if (config.useImage) {
if (ctx.puppeteer) {
if (config.device === 'pc')
return pcRenderImage(ctx, item);
else
return mobileRenderImage(ctx, item);
}
else {
return '未安装/启用 puppeteer 插件,无法使用图片渲染';
}
}
else {
return renderText(item);
}
}
catch (e) {
_1.logger.error('render error', e);
throw e;
}
}
exports.renderFunction = renderFunction;
async function pcRenderImage(ctx, item) {
let page;
try {
const { renderFontsDir, bilibiliCookiePath } = config_1.default.getInstance(ctx.baseDir).getGeneratePathData();
const needLoadFontList = await (0, utils_1.getFontsList)(renderFontsDir, _1.logger);
const url = `https://t.bilibili.com/${item.id_str}`;
page = await ctx.puppeteer.page();
await page.setViewport({ width: 1920 * 2, height: 1080 * 2 });
let cookie;
try {
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');
}
Object.entries(cookie).forEach(([key, value]) => {
page.setCookie({
url,
name: key,
value,
});
});
await page.goto(url);
await page.waitForNetworkIdle();
await page.addScriptTag({
path: node_path_1.default.resolve(__dirname, '../static/bilibiliStyle.js'),
});
await page.evaluate(() => {
let popover;
// eslint-disable-next-line no-cond-assign
while ((popover = document.querySelector('.van-popover')))
popover.remove();
});
await page.evaluate('getBilibiliStyle()');
if (needLoadFontList.length > 0)
await page.evaluate(`setFont(${JSON.stringify(needLoadFontList)})`);
await page.evaluate(() => document.fonts.ready);
const element = await page.$('.bili-dyn-item');
const elementClip = await element?.boundingBox();
return (`${item.modules.module_author.name} ${new Date(item.modules.module_author.pub_ts * 1000).toLocaleString()}\n${enum_1.BilibiliDynamicItemType[item.type] || '发布了动态'}:\n${koishi_1.segment.image(await element.screenshot({
clip: elementClip,
encoding: 'binary',
}), 'image/png')}\nhttps://t.bilibili.com/${item.id_str}`);
}
catch (e) {
throw e.message;
}
finally {
page?.close();
}
}
async function mobileRenderImage(ctx, item) {
let page;
try {
const { renderFontsDir, bilibiliCookiePath } = config_1.default.getInstance(ctx.baseDir).getGeneratePathData();
const needLoadFontList = await (0, utils_1.getFontsList)(renderFontsDir, _1.logger);
const url = `https://m.bilibili.com/dynamic/${item.id_str}`;
page = await ctx.puppeteer.page();
await page
.setViewport({
width: 460,
height: 720,
isMobile: true,
})
.then(() => page.setUserAgent('Mozilla/5.0 (Linux; Android 10; MI 9) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Mobile Safari/537.36'));
let cookie;
try {
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');
}
Object.entries(cookie).forEach(([key, value]) => {
page.setCookie({
url,
name: key,
value,
});
});
await page.goto(url, {
waitUntil: 'networkidle0',
timeout: 120000,
});
if (page.url().includes('bilibili.com/404')) {
_1.logger.warn(`[bilibili推送] ${item.id_str} 动态不存在`);
throw new Error('not found');
}
await page.addScriptTag({
path: node_path_1.default.resolve(__dirname, '../static/bilibiliStyle.js'),
});
await page.evaluate('getBilibiliStyle()');
await page.evaluate('imageComplete()');
if (needLoadFontList.length > 0)
await page.evaluate(`setFont(${JSON.stringify(needLoadFontList)})`);
await page.evaluate(() => document.fonts.ready);
const element = (await page.$('.opus-modules')) ?? (await page.$('.dyn-card'));
const elementClip = await element?.boundingBox();
return (`${item.modules.module_author.name} ${new Date(item.modules.module_author.pub_ts * 1000).toLocaleString()}\n${enum_1.BilibiliDynamicItemType[item.type] || '发布了动态'}:\n${koishi_1.segment.image(await page.screenshot({
clip: elementClip,
encoding: 'binary',
}), 'image/png')}\nhttps://t.bilibili.com/${item.id_str}`);
}
catch (e) {
throw e.message;
}
finally {
page?.close();
}
}
async function renderText(item) {
const author = item.modules.module_author;
let result = `${author.name} ${new Date(author.pub_ts * 1000).toLocaleString()}\n`;
if (item.type === 'DYNAMIC_TYPE_AV') {
const dynamic = item.modules.module_dynamic;
result += `发布了视频: \n${dynamic.major.archive.title}\n<image url="${dynamic.major.archive.cover}"/>`;
}
else if (item.type === 'DYNAMIC_TYPE_DRAW') {
const dynamic = item.modules.module_dynamic;
result += `发布了动态: \n${dynamic.desc.text}\n${dynamic.major.draw.items
.map(item => `<image url="${item.src}"/>`)
.join('')}`;
}
else if (item.type === 'DYNAMIC_TYPE_WORD') {
const dynamic = item.modules.module_dynamic;
result += `发布了动态: \n${dynamic.desc.text}`;
}
else if (item.type === 'DYNAMIC_TYPE_FORWARD') {
const dynamic = item.modules.module_dynamic;
result += `转发动态: \n${dynamic.desc.text}\n${await renderText(item.orig)}`;
}
else if (item.type === 'DYNAMIC_TYPE_LIVE_RCMD') {
const dynamic = item.modules.module_dynamic;
const info = JSON.parse(dynamic.major.live_rcmd.content);
result += `开始直播: \n${info.title || info.live_play_info.title}`;
if (info.cover)
result += `\n${koishi_1.segment.image(info.cover || info.live_play_info.cover)}`;
}
else {
result += `发布了未知类型的动态: \n${item.type}`;
}
return `${result}\nhttps://t.bilibili.com/${item.id_str}`;
}