lampdiscordbot/pixiv-embedder.js

90 lines
3.3 KiB
JavaScript

var fetch = require("node-fetch");
var client = require("./client");
var config = require("./config");
var commands = require("./commands");
client.on("messageCreate", async message => {
if (message.guild?.id != config.guild) return;
if (message.author.bot) return;
if (message.author.id == client.user.id) return;
let pixiv_urls = new Set(message.content.match(/(?<!\/)https?:\/\/(?:www\.)?pixiv\.net(?:\/en)?\/artworks\/\d+\b/g));
if (!pixiv_urls.size) return;
message.suppressEmbeds();
// suppressing embeds doesn't work on embeds that load after
client.on("messageUpdate", function arf(g,updatedMessage) {
if (updatedMessage.id == message.id) {
updatedMessage.suppressEmbeds();
// sometimes it still doesn't work
setTimeout(() => {
updatedMessage.suppressEmbeds();
}, 1000);
client.removeListener("messageUpdate", arf);
}
});
message.channel.sendTyping();
try {
await embedPixiv(message.channel, pixiv_urls, message.channel.send.bind(message.channel), pixiv_urls.size > 1);
} catch (error) {
if (pixiv_urls.size == 1) message.react('⚠');
}
});
commands.push({
name: "miku",
description: "Random Miku pic",
exec: async i => {
var mikutachi = require('./mikutachi');
await i.deferReply();
await embedPixiv(i.channel, [`https://www.pixiv.net/en/artworks/${random(mikutachi)}`], i.editReply.bind(i), true);
}
});
// using this code for embedding links and for slash commands
async function embedPixiv(/*message*/ channel, /*array of*/ links, send = channel.send.bind(channel) /* or interaction.reply function */, showLinks /* include pixiv links in response content */) {
for (let link of links) {
try {
let illust = Object.values(JSON.parse((await (await fetch(link)).text()).match(/<meta name="preload-data" id="meta-preload-data" content='(.*)'>/)[1]).illust)[0];
let content = `**${illust.title}**\n`;
if (showLinks || illust.illustType == 2) {
content += `<${link}>${illust.illustType == 2 ? " is an animation (must open link to play)" : ''}`;
}
let images = [];
for (let i = 0; i < illust.pageCount; i++) images.push({url: illust.urls.original.replace('p0', 'p'+i)});
if (images.length <= 10) {
try {
for (let image of images) {
image.data = await (await fetch(image.url, {headers: {"Referer": "https://www.pixiv.net/"}})).buffer();
}
await send({
content,
files: images.map(image => ({attachment: image.data || "error", name: ((illust.xRestrict && !channel.nsfw) ? 'SPOILER_' : '') + image.url.split('/').pop()}))
});
} catch (error) {
if (error.message == "Request entity too large") await fallback();
else throw error;
}
} else await fallback();
function fallback() {
let urls = images.map(image => image.url.replace("i.pximg.net", "px.owo39.me"));
if (illust.xRestrict && !channel.nsfw) urls = urls.map(url => `||${url} ||`);
urls = urls.join('\n');
if (urls.length > 2000) {
return send({content, files:[{attachment: Buffer.from(urls), name:"message.txt"}]});
} else {
return send((content ? content + '\n' : '') + urls);
}
}
} catch (error) {
console.error("pixiv embed error,", error.stack);
if (showLinks) {
send(`<${link}> failed to be embedded`);
} else {
throw error;
}
}
}
}
module.exports.embedPixiv = embedPixiv;