"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const fs_1 = require("fs"); const axios_1 = require("axios"); const CallableInstance = require("callable-instance"); const html_entities_1 = require("html-entities"); const temp = require("temp"); const loggers_1 = require("./loggers"); const koishi_1 = require("./koishi"); const xmlEntities = new html_entities_1.XmlEntities(); const ZHType = (type) => new class extends String { constructor() { super(...arguments); this.type = super.toString(); this.toString = () => `[${super.toString()}]`; } }(type); const typeInZH = { photo: ZHType('图片'), video: ZHType('视频'), animated_gif: ZHType('GIF'), }; const logger = loggers_1.getLogger('webshot'); class Webshot extends CallableInstance { constructor(_wsUrl, mode, onready) { super('webshot'); this.fetchMedia = (url) => new Promise((resolve, reject) => { logger.info(`fetching ${url}`); axios_1.default({ method: 'get', url, responseType: 'arraybuffer', timeout: 150000, }).then(res => { if (res.status === 200) { logger.info(`successfully fetched ${url}`); resolve(res.data); } else { logger.error(`failed to fetch ${url}: ${res.status}`); reject(); } }).catch(err => { logger.error(`failed to fetch ${url}: ${err instanceof Error ? err.message : err}`); reject(); }); }).then(data => { var _a; return (ext => { const mediaTempFilePath = temp.path({ suffix: `.${ext}` }); fs_1.writeFileSync(mediaTempFilePath, Buffer.from(data)); const path = `file://${mediaTempFilePath}`; switch (ext) { case 'jpg': case 'png': return koishi_1.Message.Image(path); case 'mp4': return koishi_1.Message.Video(path); } logger.warn('unable to find MIME type of fetched media, failing this fetch'); throw Error(); })(((_a = (/\?format=([a-z]+)&/.exec(url))) !== null && _a !== void 0 ? _a : (/.*\/.*\.([^?]+)/.exec(url)))[1]); }); this.mode = mode; onready(); } webshot(user, fleets, callback, webshotDelay) { let promise = new Promise(resolve => { resolve(); }); fleets.forEach(fleet => { var _a, _b; promise = promise.then(() => { logger.info(`working on ${user.screen_name}/${fleet.fleet_id}`); }); let messageChain = ''; const author = `${user.name} (@${user.screen_name}):\n`; const date = `${new Date(fleet.created_at)}\n`; let text = (_b = author + date + ((_a = fleet.media_bounding_boxes) === null || _a === void 0 ? void 0 : _a.map(box => box.entity.value).join('\n'))) !== null && _b !== void 0 ? _b : ''; messageChain += author + date; if (1 - this.mode % 2) promise = promise.then(() => { const media = fleet.media_entity; let url; if (fleet.media_key.media_category === 'TWEET_IMAGE') { media.type = 'photo'; url = media.media_url_https.replace(/\.([a-z]+)$/, '?format=$1') + '&name=orig'; } else { media.type = fleet.media_key.media_category === 'TWEET_VIDEO' ? 'video' : 'animated_gif'; media.video_info = media.media_info.video_info; text += `[${typeInZH[media.type].type}]`; url = media.video_info.variants .filter(variant => variant.bit_rate !== undefined) .sort((var1, var2) => var2.bit_rate - var1.bit_rate) .map(variant => variant.url)[0]; } const altMessage = `\n[失败的${typeInZH[media.type].type}:${url}]`; return this.fetchMedia(url) .catch(error => { logger.warn('unable to fetch media, sending plain text instead...'); return altMessage; }) .then(msg => { messageChain += msg; }); }); promise.then(() => { logger.info(`done working on ${user.screen_name}/${fleet.fleet_id}, message chain:`); logger.info(JSON.stringify(messageChain)); callback(messageChain, xmlEntities.decode(text)); }); }); return promise; } } exports.default = Webshot;