+6
bun.lock
+6
bun.lock
···
4
4
"": {
5
5
"name": "discord",
6
6
"dependencies": {
7
+
"@types/mime": "^4.0.0",
7
8
"discord.js": "^14.18.0",
9
+
"mime": "^4.0.6",
8
10
},
9
11
"devDependencies": {
10
12
"@types/bun": "latest",
···
35
37
36
38
"@types/bun": ["@types/bun@1.2.4", "", { "dependencies": { "bun-types": "1.2.4" } }, "sha512-QtuV5OMR8/rdKJs213iwXDpfVvnskPXY/S0ZiFbsTjQZycuqPbMW8Gf/XhLfwE5njW8sxI2WjISURXPlHypMFA=="],
37
39
40
+
"@types/mime": ["@types/mime@4.0.0", "", { "dependencies": { "mime": "*" } }, "sha512-5eEkJZ/BLvTE3vXGKkWlyTSUVZuzj23Wj8PoyOq2lt5I3CYbiLBOPb3XmCW6QcuOibIUE6emHXHt9E/F/rCa6w=="],
41
+
38
42
"@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="],
39
43
40
44
"@types/ws": ["@types/ws@8.5.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw=="],
···
54
58
"lodash.snakecase": ["lodash.snakecase@4.1.1", "", {}, "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw=="],
55
59
56
60
"magic-bytes.js": ["magic-bytes.js@1.10.0", "", {}, "sha512-/k20Lg2q8LE5xiaaSkMXk4sfvI+9EGEykFS4b0CHHGWqDYU0bGUFSwchNOMA56D7TCs9GwVTkqe9als1/ns8UQ=="],
61
+
62
+
"mime": ["mime@4.0.6", "", { "bin": { "mime": "bin/cli.js" } }, "sha512-4rGt7rvQHBbaSOF9POGkk1ocRP16Md1x36Xma8sz8h8/vfCUI2OtEIeCqe4Ofes853x4xDoPiFLIT47J5fI/7A=="],
57
63
58
64
"ts-mixer": ["ts-mixer@6.0.4", "", {}, "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA=="],
59
65
+3
-1
package.json
+3
-1
package.json
+16
-19
src/commands/dong/create.ts
+16
-19
src/commands/dong/create.ts
···
1
1
import {
2
2
Attachment,
3
+
AttachmentBuilder,
3
4
ChatInputCommandInteraction,
4
5
SlashCommandBuilder,
5
6
} from "discord.js";
6
7
import type { customClient } from "../..";
7
-
8
-
const download = async (file: Attachment): Promise<File> =>
9
-
new File(
10
-
[
11
-
await fetch(file.url).then((res) => {
12
-
return res.blob();
13
-
}),
14
-
],
15
-
file.name,
16
-
{
17
-
type: file.contentType ?? "application/octet-stream",
18
-
}
19
-
);
8
+
import { createDong } from "../../lib/dong-io";
9
+
import { download } from "../../lib/download";
20
10
21
11
export const data = new SlashCommandBuilder()
22
12
.setName("create")
···
62
52
audio: await download(audio),
63
53
};
64
54
console.log(downloaded);
65
-
await interaction.editReply(`Not implemented! Debug:
66
-
\`\`\`
67
-
filename: ${filename}
68
55
69
-
image: ${image.contentType} | ${image.url}
56
+
const dong = new File(
57
+
[await createDong(downloaded.image, downloaded.audio)],
58
+
filename,
59
+
{ type: "application/prs.vielle.dong" }
60
+
);
61
+
console.log(dong);
70
62
71
-
audio: ${audio.contentType} | ${audio.url}
72
-
\`\`\``);
63
+
await interaction.editReply({
64
+
files: [
65
+
new AttachmentBuilder(Buffer.from(await dong.arrayBuffer()), {
66
+
name: dong.name,
67
+
}),
68
+
],
69
+
});
73
70
};
+47
-6
src/commands/dong/open.ts
+47
-6
src/commands/dong/open.ts
···
1
-
import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
1
+
import {
2
+
AttachmentBuilder,
3
+
ChatInputCommandInteraction,
4
+
SlashCommandBuilder,
5
+
} from "discord.js";
2
6
import type { customClient } from "../..";
7
+
import { download } from "../../lib/download";
8
+
import { readDong } from "../../lib/dong-io";
9
+
import { Mime } from "mime";
10
+
import standardTypes from "mime/types/standard.js";
11
+
import otherTypes from "mime/types/other.js";
12
+
13
+
const mime = new Mime(standardTypes, otherTypes);
14
+
mime.define({ "audio/mpeg": ["mp3"] });
3
15
4
16
export const data = new SlashCommandBuilder()
5
17
.setName("open")
6
18
.setDescription("Open a dong file!")
7
19
.addAttachmentOption((opt) =>
8
-
opt
9
-
.setName("dong")
10
-
.setDescription("The dong file")
11
-
.setRequired(true)
20
+
opt.setName("dong").setDescription("The dong file").setRequired(true)
12
21
);
13
22
export const execute = async (
14
23
interaction: ChatInputCommandInteraction & { client: customClient }
15
24
) => {
16
-
await interaction.reply("Not Implemented!");
25
+
const dong = interaction.options.getAttachment("dong", true);
26
+
await interaction.deferReply();
27
+
28
+
const downloadedDong = await download(dong);
29
+
console.log(downloadedDong);
30
+
31
+
const output = await readDong(downloadedDong);
32
+
if (typeof output === "string") {
33
+
await interaction.editReply(output);
34
+
return;
35
+
}
36
+
const { image, audio } = output;
37
+
38
+
console.log(image, audio);
39
+
40
+
await interaction.editReply({
41
+
files: [
42
+
(() => {
43
+
const img = new AttachmentBuilder(Buffer.from(image.data.buffer), {
44
+
name: `${dong.name.match(/^.*(?=\.dong$)/gm)}.${mime.getExtension(
45
+
image.mime
46
+
)}`,
47
+
});
48
+
img.setSpoiler(true);
49
+
return img;
50
+
})(),
51
+
new AttachmentBuilder(Buffer.from(audio.data.buffer), {
52
+
name: `${dong.name.match(/^.*(?=\.dong$)/gm)}.${mime.getExtension(
53
+
audio.mime
54
+
)}`,
55
+
}),
56
+
],
57
+
});
17
58
};
+14
src/lib/download.ts
+14
src/lib/download.ts
···
1
+
import type { Attachment } from "discord.js";
2
+
3
+
export const download = async (file: Attachment): Promise<File> =>
4
+
new File(
5
+
[
6
+
await fetch(file.url).then((res) => {
7
+
return res.blob();
8
+
}),
9
+
],
10
+
file.name,
11
+
{
12
+
type: file.contentType ?? "application/octet-stream",
13
+
}
14
+
);