Discord bot to open dong files

finish it

Changed files
+86 -26
src
commands
lib
+6
bun.lock
···
"": {
"name": "discord",
"dependencies": {
"discord.js": "^14.18.0",
},
"devDependencies": {
"@types/bun": "latest",
···
"@types/bun": ["@types/bun@1.2.4", "", { "dependencies": { "bun-types": "1.2.4" } }, "sha512-QtuV5OMR8/rdKJs213iwXDpfVvnskPXY/S0ZiFbsTjQZycuqPbMW8Gf/XhLfwE5njW8sxI2WjISURXPlHypMFA=="],
"@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="],
"@types/ws": ["@types/ws@8.5.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw=="],
···
"lodash.snakecase": ["lodash.snakecase@4.1.1", "", {}, "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw=="],
"magic-bytes.js": ["magic-bytes.js@1.10.0", "", {}, "sha512-/k20Lg2q8LE5xiaaSkMXk4sfvI+9EGEykFS4b0CHHGWqDYU0bGUFSwchNOMA56D7TCs9GwVTkqe9als1/ns8UQ=="],
"ts-mixer": ["ts-mixer@6.0.4", "", {}, "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA=="],
···
"": {
"name": "discord",
"dependencies": {
+
"@types/mime": "^4.0.0",
"discord.js": "^14.18.0",
+
"mime": "^4.0.6",
},
"devDependencies": {
"@types/bun": "latest",
···
"@types/bun": ["@types/bun@1.2.4", "", { "dependencies": { "bun-types": "1.2.4" } }, "sha512-QtuV5OMR8/rdKJs213iwXDpfVvnskPXY/S0ZiFbsTjQZycuqPbMW8Gf/XhLfwE5njW8sxI2WjISURXPlHypMFA=="],
+
"@types/mime": ["@types/mime@4.0.0", "", { "dependencies": { "mime": "*" } }, "sha512-5eEkJZ/BLvTE3vXGKkWlyTSUVZuzj23Wj8PoyOq2lt5I3CYbiLBOPb3XmCW6QcuOibIUE6emHXHt9E/F/rCa6w=="],
+
"@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="],
"@types/ws": ["@types/ws@8.5.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw=="],
···
"lodash.snakecase": ["lodash.snakecase@4.1.1", "", {}, "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw=="],
"magic-bytes.js": ["magic-bytes.js@1.10.0", "", {}, "sha512-/k20Lg2q8LE5xiaaSkMXk4sfvI+9EGEykFS4b0CHHGWqDYU0bGUFSwchNOMA56D7TCs9GwVTkqe9als1/ns8UQ=="],
+
+
"mime": ["mime@4.0.6", "", { "bin": { "mime": "bin/cli.js" } }, "sha512-4rGt7rvQHBbaSOF9POGkk1ocRP16Md1x36Xma8sz8h8/vfCUI2OtEIeCqe4Ofes853x4xDoPiFLIT47J5fI/7A=="],
"ts-mixer": ["ts-mixer@6.0.4", "", {}, "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA=="],
+3 -1
package.json
···
"typescript": "^5"
},
"dependencies": {
-
"discord.js": "^14.18.0"
}
}
···
"typescript": "^5"
},
"dependencies": {
+
"@types/mime": "^4.0.0",
+
"discord.js": "^14.18.0",
+
"mime": "^4.0.6"
}
}
+16 -19
src/commands/dong/create.ts
···
import {
Attachment,
ChatInputCommandInteraction,
SlashCommandBuilder,
} from "discord.js";
import type { customClient } from "../..";
-
-
const download = async (file: Attachment): Promise<File> =>
-
new File(
-
[
-
await fetch(file.url).then((res) => {
-
return res.blob();
-
}),
-
],
-
file.name,
-
{
-
type: file.contentType ?? "application/octet-stream",
-
}
-
);
export const data = new SlashCommandBuilder()
.setName("create")
···
audio: await download(audio),
};
console.log(downloaded);
-
await interaction.editReply(`Not implemented! Debug:
-
\`\`\`
-
filename: ${filename}
-
image: ${image.contentType} | ${image.url}
-
audio: ${audio.contentType} | ${audio.url}
-
\`\`\``);
};
···
import {
Attachment,
+
AttachmentBuilder,
ChatInputCommandInteraction,
SlashCommandBuilder,
} from "discord.js";
import type { customClient } from "../..";
+
import { createDong } from "../../lib/dong-io";
+
import { download } from "../../lib/download";
export const data = new SlashCommandBuilder()
.setName("create")
···
audio: await download(audio),
};
console.log(downloaded);
+
const dong = new File(
+
[await createDong(downloaded.image, downloaded.audio)],
+
filename,
+
{ type: "application/prs.vielle.dong" }
+
);
+
console.log(dong);
+
await interaction.editReply({
+
files: [
+
new AttachmentBuilder(Buffer.from(await dong.arrayBuffer()), {
+
name: dong.name,
+
}),
+
],
+
});
};
+47 -6
src/commands/dong/open.ts
···
-
import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
import type { customClient } from "../..";
export const data = new SlashCommandBuilder()
.setName("open")
.setDescription("Open a dong file!")
.addAttachmentOption((opt) =>
-
opt
-
.setName("dong")
-
.setDescription("The dong file")
-
.setRequired(true)
);
export const execute = async (
interaction: ChatInputCommandInteraction & { client: customClient }
) => {
-
await interaction.reply("Not Implemented!");
};
···
+
import {
+
AttachmentBuilder,
+
ChatInputCommandInteraction,
+
SlashCommandBuilder,
+
} from "discord.js";
import type { customClient } from "../..";
+
import { download } from "../../lib/download";
+
import { readDong } from "../../lib/dong-io";
+
import { Mime } from "mime";
+
import standardTypes from "mime/types/standard.js";
+
import otherTypes from "mime/types/other.js";
+
+
const mime = new Mime(standardTypes, otherTypes);
+
mime.define({ "audio/mpeg": ["mp3"] });
export const data = new SlashCommandBuilder()
.setName("open")
.setDescription("Open a dong file!")
.addAttachmentOption((opt) =>
+
opt.setName("dong").setDescription("The dong file").setRequired(true)
);
export const execute = async (
interaction: ChatInputCommandInteraction & { client: customClient }
) => {
+
const dong = interaction.options.getAttachment("dong", true);
+
await interaction.deferReply();
+
+
const downloadedDong = await download(dong);
+
console.log(downloadedDong);
+
+
const output = await readDong(downloadedDong);
+
if (typeof output === "string") {
+
await interaction.editReply(output);
+
return;
+
}
+
const { image, audio } = output;
+
+
console.log(image, audio);
+
+
await interaction.editReply({
+
files: [
+
(() => {
+
const img = new AttachmentBuilder(Buffer.from(image.data.buffer), {
+
name: `${dong.name.match(/^.*(?=\.dong$)/gm)}.${mime.getExtension(
+
image.mime
+
)}`,
+
});
+
img.setSpoiler(true);
+
return img;
+
})(),
+
new AttachmentBuilder(Buffer.from(audio.data.buffer), {
+
name: `${dong.name.match(/^.*(?=\.dong$)/gm)}.${mime.getExtension(
+
audio.mime
+
)}`,
+
}),
+
],
+
});
};
+14
src/lib/download.ts
···
···
+
import type { Attachment } from "discord.js";
+
+
export const download = async (file: Attachment): Promise<File> =>
+
new File(
+
[
+
await fetch(file.url).then((res) => {
+
return res.blob();
+
}),
+
],
+
file.name,
+
{
+
type: file.contentType ?? "application/octet-stream",
+
}
+
);