discord_bot/commands/misc/tdoss.js
SileNce5k 6a0350f13c
All checks were successful
CI / CI (push) Successful in 1m22s
Fix problem if content-type isn't provided by server
2025-05-10 15:09:53 +02:00

107 lines
4.3 KiB
JavaScript

const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
const { writeFile } = require('node:fs/promises')
const { Readable } = require('node:stream')
module.exports = {
name: 'tdoss',
description: 'Combine picture with tdoss album cover template',
async execute({ message, args }) {
let tdossDir = path.resolve(process.cwd, 'data', 'tdoss');
const directory = path.resolve(tdossDir, Math.floor(new Date).toString())
fs.mkdirSync(directory, {recursive: true})
let url = "";
if(message.attachments.size > 0){
url = message.attachments.first().url
} else if(args[0] && args[0].startsWith("https://") ){
url = args[0];
}else if(message.reference){
let referencedMessage = await message.fetchReference();
if(referencedMessage.attachments.size > 0){
url = await referencedMessage.attachments.first().url;
}
else {
message.channel.send("The message you replied to doesn't have any attachments.");
return;
}
}
else {
let lastMessages = await message.channel.messages.fetch({limit: 20, cache: false});
let lastMessageWithAttachment = lastMessages.find(m => m.attachments.size > 0);
if(!lastMessageWithAttachment){
message.channel.send("Couldn't find an image to use this command on.")
fs.rmSync(`${directory}`, {recursive: true})
return
}
url = lastMessageWithAttachment.attachments.first().url;
}
// TODO: Download with correct extension.
message.channel.sendTyping();
let downloadResult = await this.downloadImage(url, path.resolve(directory, "input.png"));
if(downloadResult.value != 0){
if(downloadResult.value === 3){
message.channel.send(`Failed to download the provided image, got error '${downloadResult.errorMessage}'`);
}else if (downloadResult.value === 1){
message.channel.send(`Failed to download the provided image, got response status '${downloadResult.errorMessage}'`);
}else if(downloadResult.value === 2){
message.channel.send(`The provided url was not an image.`)
}
fs.rmSync(`${directory}`, {recursive: true})
return;
}
const command = `magick ${tdossDir}/tdoss_template.png \\( ${directory}/input.png -resize 800x800^ -gravity center -extent 1000x1000 \\) -compose dst-over -composite ${directory}/tdoss_result.png`;
if (this.executeCommand(command).error === true) {
message.channel.send("Something went wrong during image manipulation.\nTry again and if it keeps happening, contact the owner of the bot.")
fs.rmSync(`${directory}`, {recursive: true})
return
}
let final_image = {
attachment: path.resolve(`${directory}/tdoss_result.png`),
name: "tdoss_result.png"
}
await message.channel.send({files: [final_image]})
fs.rmSync(`${directory}`, {recursive: true})
},
executeCommand(command) {
console.log("Executing:", command)
try {
const output = execSync(command, { encoding: 'utf-8' })
if (output.length != 0)
console.log(output)
} catch (error) {
console.error(`Error executing ${command.split(" ")[0]} command:`, error);
return { error: true };
}
return { error: false };
},
// https://stackoverflow.com/a/77210219
async downloadImage(url, path) {
let res = new Response()
try {
res = await fetch(url);
} catch (error) {
return {value: 3, errorMessage: error.cause.message};
}
if(!res.ok) return {value: 1, errorMessage: res.status.toString()};
const contentType = res.headers.get('content-type');
if(!contentType || !contentType.startsWith("image")) return {value: 2, errorMessage: contentType || "No content-type header"};
const stream = Readable.fromWeb(res.body)
await writeFile(path, stream);
return {value: 0, errorMessage: ""};
}
}