Commit 834d64ee authored by nanahira's avatar nanahira

support puppeteer

parent 0089393f
import { Context } from 'koishi'; import { Context } from 'koishi';
import DataviewPlugin from '@koishijs/plugin-dataview'; import DataviewPlugin from '@koishijs/plugin-dataview';
import Puppeteer from 'koishi-plugin-puppeteer';
export default class ExtrasInDev { export default class ExtrasInDev {
constructor(ctx: Context) { constructor(ctx: Context) {
ctx.plugin(DataviewPlugin); ctx.plugin(DataviewPlugin);
ctx.plugin(Puppeteer);
} }
} }
This diff is collapsed.
...@@ -51,14 +51,14 @@ ...@@ -51,14 +51,14 @@
"moment": "^2.29.4" "moment": "^2.29.4"
}, },
"peerDependencies": { "peerDependencies": {
"koishi": "^4.11.1" "koishi": "^4.11.4"
}, },
"devDependencies": { "devDependencies": {
"@koishijs/plugin-console": "^5.1.0", "@koishijs/plugin-console": "^5.2.1",
"@koishijs/plugin-database-memory": "^2.2.2", "@koishijs/plugin-database-memory": "^2.2.2",
"@koishijs/plugin-dataview": "^2.2.0", "@koishijs/plugin-dataview": "^2.2.0",
"@koishijs/plugin-help": "^2.0.2", "@koishijs/plugin-help": "^2.0.2",
"@koishijs/plugin-sandbox": "^2.5.0", "@koishijs/plugin-sandbox": "^2.6.1",
"@types/jest": "^29.2.3", "@types/jest": "^29.2.3",
"@types/lodash": "^4.14.189", "@types/lodash": "^4.14.189",
"@types/node": "^18.11.9", "@types/node": "^18.11.9",
...@@ -68,6 +68,7 @@ ...@@ -68,6 +68,7 @@
"eslint-config-prettier": "^8.5.0", "eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^4.2.1", "eslint-plugin-prettier": "^4.2.1",
"jest": "^29.3.1", "jest": "^29.3.1",
"koishi-plugin-puppeteer": "^3.4.1",
"prettier": "^2.7.1", "prettier": "^2.7.1",
"raw-loader": "^4.0.2", "raw-loader": "^4.0.2",
"ts-jest": "^29.0.3", "ts-jest": "^29.0.3",
...@@ -82,6 +83,9 @@ ...@@ -82,6 +83,9 @@
"service": { "service": {
"required": [ "required": [
"database" "database"
],
"optional": [
"puppeteer"
] ]
} }
} }
......
...@@ -36,6 +36,11 @@ export class RetweetNotifierPluginConfig { ...@@ -36,6 +36,11 @@ export class RetweetNotifierPluginConfig {
default: ['帮忙给转个推~', '帮忙转个推~', '帮忙转个推好不好~'], default: ['帮忙给转个推~', '帮忙转个推~', '帮忙转个推好不好~'],
}) })
message: string[]; message: string[];
@SchemaProperty({
description: '是否在截图失败时放弃发送。需要使用 Puppeteer。',
})
safe: boolean;
} }
export type RetweetNotifierPluginConfigLike = export type RetweetNotifierPluginConfigLike =
......
...@@ -9,10 +9,11 @@ import { ...@@ -9,10 +9,11 @@ import {
UseModel, UseModel,
} from 'koishi-thirdeye'; } from 'koishi-thirdeye';
import { SchedulePlugin } from 'koishi-schedule-send'; import { SchedulePlugin } from 'koishi-schedule-send';
import { Database, Quester, Random, Tables } from 'koishi'; import { Database, Quester, Random, segment, Tables } from 'koishi';
import moment from 'moment'; import moment from 'moment';
import _ from 'lodash'; import _ from 'lodash';
export * from './config'; export * from './config';
import type {} from 'koishi-plugin-puppeteer';
declare module 'koishi' { declare module 'koishi' {
interface Tables { interface Tables {
...@@ -102,6 +103,31 @@ export default class RetweetNotifierPlugin extends SchedulePlugin( ...@@ -102,6 +103,31 @@ export default class RetweetNotifierPlugin extends SchedulePlugin(
return !existing?.length; return !existing?.length;
} }
private async renderTweet(url: string) {
if (!this.ctx.puppeteer) return url;
this.logger.info(`Rendering tweet ${url}...`);
const page = await this.ctx.puppeteer.page();
try {
await page.goto(url, { timeout: 300000, waitUntil: 'networkidle2' });
const tweetComponent = await page.$(
'#react-root > div > div > div:nth-child(2) > main > div > div > div > div > div > section > div > div > div:nth-child(1) > div > div > div:nth-child(1)',
);
// const tweetComponent = page;
if (!tweetComponent) {
this.logger.warn(`Component not found for tweet ${url}`);
return url;
}
this.logger.info(`Taking screenshot of ${url}...`);
const screenshot = await tweetComponent.screenshot({ fullPage: false });
return segment.image(screenshot, 'image/png').toString();
} catch (e) {
this.logger.error(`Failed to render tweet ${url}: ${e}`);
return url;
} finally {
await page.close();
}
}
async send() { async send() {
let { data: tweets } = await this.http.post<{ data: Tweet[] }>( let { data: tweets } = await this.http.post<{ data: Tweet[] }>(
this.config.endpoint + '/Profile', this.config.endpoint + '/Profile',
...@@ -132,13 +158,14 @@ export default class RetweetNotifierPlugin extends SchedulePlugin( ...@@ -132,13 +158,14 @@ export default class RetweetNotifierPlugin extends SchedulePlugin(
(t) => (t.retweets_count << 16) | (t.replies_count << 8) | t.likes_count, // pick the least retweeted tweet (t) => (t.retweets_count << 16) | (t.replies_count << 8) | t.likes_count, // pick the least retweeted tweet
); );
const headerDisplay = await this.renderTweet(leastRetweet.link);
if (this.config.safe && headerDisplay.startsWith('https://')) return;
await this.database.upsert('retweeted', [ await this.database.upsert('retweeted', [
{ {
id: leastRetweet.id_str, id: leastRetweet.id_str,
payload: leastRetweet, payload: leastRetweet,
}, },
]); ]);
return headerDisplay + '\n' + Random.pick(this.config.message);
return leastRetweet.link + '\n' + Random.pick(this.config.message);
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment