UNPKG

akiraa-scrape

Version:

Module & tools for bot whatsApp

250 lines (240 loc) 6.43 kB
const fs = require("fs"); const path = require("path"); const crypto = require("crypto"); const fetch = require("node-fetch"); const { ffmpeg } = require("./converter"); const { spawn } = require("child_process"); const uploadFile = require("./uploadFile"); const { fromBuffer } = require("file-type"); const uploadImage = require("./uploadImage"); const tmp = path.join(__dirname, "../tmp"); /** * Image to Sticker * @param {Buffer} img Image Buffer * @param {String} url Image URL */ function sticker2(img, url) { return new Promise(async (resolve, reject) => { try { if (url) { let res = await fetch(url); if (res.status !== 200) throw await res.text(); img = await res.buffer(); } let inp = path.join(tmp, +new Date() + ".jpeg"); await fs.promises.writeFile(inp, img); let ff = spawn("ffmpeg", [ "-y", "-i", inp, "-vf", "scale=512:512:flags=lanczos:force_original_aspect_ratio=decrease,format=rgba,pad=512:512:(ow-iw)/2:(oh-ih)/2:color=#00000000,setsar=1", "-f", "png", "-", ]); ff.on("error", reject); ff.on("close", async () => { await fs.promises.unlink(inp); }); let bufs = []; const [_spawnprocess, ..._spawnargs] = [ ...(module.exports.support.gm ? ["gm"] : module.exports.magick ? ["magick"] : []), "convert", "png:-", "webp:-", ]; let im = spawn(_spawnprocess, _spawnargs); im.on("error", (e) => conn.reply(m.chat, util.format(e), m)); im.stdout.on("data", (chunk) => bufs.push(chunk)); ff.stdout.pipe(im.stdin); im.on("exit", () => { resolve(Buffer.concat(bufs)); }); } catch (e) { reject(e); } }); } async function canvas(code, type = "png", quality = 0.92) { let res = await fetch( "https://nurutomo.herokuapp.com/api/canvas?" + queryURL({ type, quality, }), { method: "POST", headers: { "Content-Type": "text/plain", "Content-Length": code.length, }, body: code, }, ); let image = await res.buffer(); return image; } function queryURL(queries) { return new URLSearchParams(Object.entries(queries)); } /** * Image to Sticker * @param {Buffer} img Image Buffer * @param {String} url Image URL */ async function sticker1(img, url) { url = url ? url : await uploadImage(img); let { mime } = url ? { mime: "image/jpeg" } : await fromBuffer(img); let sc = `let im = await loadImg('data:${mime};base64,'+(await window.loadToDataURI('${url}'))) c.width = c.height = 512 let max = Math.max(im.width, im.height) let w = 512 * im.width / max let h = 512 * im.height / max ctx.drawImage(im, 256 - w / 2, 256 - h / 2, w, h) `; return await canvas(sc, "webp"); } /** * Image/Video to Sticker * @param {Buffer} img Image/Video Buffer * @param {String} url Image/Video URL * @param {String} packname EXIF Packname * @param {String} author EXIF Author */ async function sticker3(img, url, packname, author) { url = url ? url : await uploadFile(img); let res = await fetch( "https://api.xteam.xyz/sticker/wm?" + new URLSearchParams( Object.entries({ url, packname, author, }), ), ); return await res.buffer(); } /** * Image to Sticker * @param {Buffer} img Image/Video Buffer * @param {String} url Image/Video URL */ async function sticker4(img, url) { if (url) { let res = await fetch(url); if (res.status !== 200) throw await res.text(); img = await res.buffer(); } return await ffmpeg( img, [ "-vf", "scale=512:512:flags=lanczos:force_original_aspect_ratio=decrease,format=rgba,pad=512:512:(ow-iw)/2:(oh-ih)/2:color=#00000000,setsar=1", ], "jpeg", "webp", ); } async function sticker5(img, url, packname, author, categories = [""]) { const WSF = require("wa-sticker-formatter"); const stickerMetadata = { type: "full", pack: packname, author, categories, }; return await new WSF.Sticker(img ? img : url, stickerMetadata).build(); } /** * Add WhatsApp JSON Exif Metadata * Taken from https://github.com/pedroslopez/whatsapp-web.js/pull/527/files * @param {Buffer} webpSticker * @param {String} packname * @param {String} author * @param {String} categories * @param {Object} extra * @returns */ async function addExif( webpSticker, packname, author, categories = [""], extra = {}, ) { const webp = require("node-webpmux"); // Optional Feature const img = new webp.Image(); const stickerPackId = crypto.randomBytes(32).toString("hex"); const json = { "sticker-pack-id": stickerPackId, "sticker-pack-name": packname, "sticker-pack-publisher": author, emojis: categories, ...extra, }; let exifAttr = Buffer.from([ 0x49, 0x49, 0x2a, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x41, 0x57, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, ]); let jsonBuffer = Buffer.from(JSON.stringify(json), "utf8"); let exif = Buffer.concat([exifAttr, jsonBuffer]); exif.writeUIntLE(jsonBuffer.length, 14, 4); await img.loadBuffer(webpSticker); img.exif = exif; return await img.saveBuffer(); } module.exports = { /** * Image/Video to Sticker * @param {Buffer} img Image/Video Buffer * @param {String} url Image/Video URL * @param {...String} */ async sticker(img, url, ...args) { let lastError; for (let func of [ sticker3, // sticker5, this.support.ffmpeg && this.support.ffmpegWebp && sticker4, this.support.ffmpeg && (this.support.convert || this.support.magick || this.support.gm) && sticker2, sticker1, ].filter((f) => f)) { try { let stiker = await func(img, url, ...args); if (stiker.includes("RIFF")) { try { return await addExif(stiker, ...args); } catch (e) { return stiker; } } throw stiker.toString(); } catch (err) { lastError = err; } } return lastError; }, sticker1, sticker2, sticker3, sticker4, sticker5, addExif, support: { ffmpeg: true, ffprobe: true, ffmpegWebp: true, convert: true, magick: false, gm: false, find: false, }, };