koishi-plugin-kbot
Version:
A muti-function qq bot for koishi
160 lines (159 loc) • 6.58 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-11 11:29:37
* @FilePath: \KBot-App\plugins\kbot\src\plugins\twitter\dynamic\render.ts
* @Description:
*
* Copyright (c) 2023 by Kabuda-czh, All Rights Reserved.
*/
const node_fs_1 = __importDefault(require("node:fs"));
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, entry, config, isListen = true) {
try {
if (ctx.puppeteer && config.useImage)
return renderImage(ctx, entry);
else
return renderText(ctx, entry, isListen, config.onlyMedia);
}
catch (err) {
_1.logger.error('推特渲染失败: ', err);
throw err;
}
}
exports.renderFunction = renderFunction;
async function renderImage(ctx, entry) {
// 判断时间线
let isRankTweet = false;
if (entry?.content?.clientEventInfo?.component === 'suggest_ranked_organic_tweet')
isRankTweet = true;
const content = isRankTweet ? entry?.content?.items?.[0]?.item : entry?.content;
const twitterRestId = content?.itemContent?.tweet_results?.result?.rest_id;
const twitterScreenName = content?.itemContent?.tweet_results?.result?.core?.user_results?.result
?.legacy?.screen_name;
const twitterName = content?.itemContent?.tweet_results?.result?.core?.user_results?.result
?.legacy?.name;
let page;
try {
const { twitterCookiePath } = config_1.default.getInstance(ctx.baseDir).getGeneratePathData();
const url = (0, utils_1.StringFormat)(enum_1.TwitterDynamicType.UserStatusURL, twitterScreenName, twitterRestId);
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(twitterCookiePath, 'utf-8'));
}
catch (e) {
_1.logger.error(`Failed to get cookie info. ${e}`);
throw new Error('cookie 信息未找到, 请使用 --ck <cookie> 添加 cookie');
}
cookie.cookieString.match(/([^=;\s]+)=([^=;\s]*)/g).forEach((item) => {
const [key, value] = item.split('=');
page.setCookie({
url,
name: key,
value,
});
});
await page.goto(url, {
waitUntil: 'networkidle0',
timeout: 120000,
});
await page.waitForNetworkIdle();
const element = await page.$('article');
const elementClip = await element?.boundingBox();
const URL = `https://twitter.com/${twitterScreenName}/status/${twitterRestId}`;
return (`${twitterName} 发布了动态:\n${koishi_1.segment.image(await element.screenshot({
clip: elementClip,
encoding: 'binary',
}), 'image/png')}\n${URL}`);
}
catch (e) {
_1.logger.error('推特图片渲染失败:', e);
throw e.message;
}
finally {
page?.close();
}
}
async function renderText(ctx, entry, isListen = true, onlyMedia = false) {
const entryResult = entry?.content?.itemContent?.tweet_results?.result;
if (!entryResult)
throw new Error('数据获取失败');
try {
const name = entryResult.core.user_results?.result?.legacy?.name;
const screenName = entryResult.core.user_results?.result?.legacy?.screen_name;
const quote = entryResult?.quoted_status_result?.result;
const is_quote = !!quote;
const retweet = entryResult?.legacy?.retweeted_status_result?.result;
const is_retweet = !!retweet;
const data = entryResult?.legacy;
const tweetId = data.id_str;
const url = `推文地址: \nhttps://twitter.com/${screenName}/status/${tweetId}`;
let text = '';
let hasShortURL = false;
const media = [];
if (is_quote) {
text = `${name} 发布了动态: \n${data.full_text}\n`;
const mediaData = data.entities;
if (mediaData?.media) {
mediaData.media.forEach((item) => {
media.push(item.media_url_https);
});
}
const quoteName = quote?.core?.user_results?.result?.legacy?.name || '';
const quoteText = quote?.legacy?.full_text || '';
text += `引用了 ${quoteName} 的推文: \n${quoteText}\n`;
const mediaEntities = quote?.legacy?.entities;
if (mediaEntities?.media) {
mediaEntities.media.forEach((item) => {
media.push(item.media_url_https);
});
}
}
else if (is_retweet) {
text = `${name} 发布了动态: \n`;
const retweetName = retweet?.core?.user_results?.result?.legacy?.name;
const retweetText = retweet?.legacy?.full_text;
text += `转发了 ${retweetName} 的推文:
${retweetText}\n`;
const mediaData = retweet?.legacy?.entities;
if (mediaData?.media) {
mediaData.media.forEach((item) => {
media.push(item.media_url_https);
});
}
}
else {
text = `${name} 发布了动态: \n${data.full_text}\n`;
const mediaData = data.entities;
if (mediaData?.media) {
mediaData.media.forEach((item) => {
media.push(item.media_url_https);
});
}
}
hasShortURL
= data.full_text.includes('https://t.co')
|| (is_quote && quote?.legacy?.full_text?.includes('https://t.co'))
|| (is_retweet && retweet?.legacy?.full_text?.includes('https://t.co'));
if (isListen && onlyMedia && media.length === 0)
return;
return `${koishi_1.segment.escape(text)}\n${media.reduce((str, httpStr) => (str += `<image url="${httpStr}" />\n`), '')}${hasShortURL ? '' : `\n${url}`}`;
}
catch (err) {
_1.logger.error('推特文字渲染失败: ', err);
throw err.message;
}
}