-
-
Notifications
You must be signed in to change notification settings - Fork 25
/
Copy pathupload_emote.ts
129 lines (100 loc) · 2.82 KB
/
upload_emote.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import { basename, extname } from '$std/path/mod.ts';
async function copyToClipboard(text: string): Promise<void> {
const command = new Deno.Command(
Deno.build.os === 'windows' ? 'clip' : 'xclip',
{
stdin: 'piped',
args: Deno.build.os === 'windows' ? [] : ['-selection', 'clipboard'],
},
);
const child = command.spawn();
const writer = child.stdin.getWriter();
writer.write(new TextEncoder().encode(text));
await writer.close();
// await child.stdin.close();
await child.status;
console.log('Copied to clipboard!');
}
async function uploadEmote(
{ BOT_TOKEN, GUILD_ID, emotePath }: {
BOT_TOKEN: string;
GUILD_ID: string;
emotePath: string;
},
): Promise<{ id: string; name: string }> {
const url = `https://discord.com/api/v10/guilds/${GUILD_ID}/emojis`;
const imageData = await Deno.readFile(emotePath);
const imageBase64 = btoa(String.fromCharCode(...imageData));
const imageDataUrl = `data:image/png;base64,${imageBase64}`;
const emoteName = basename(emotePath, extname(emotePath));
const body = { image: imageDataUrl, name: emoteName };
const response = await fetch(url, {
method: 'POST',
body: JSON.stringify(body),
headers: {
'Authorization': `Bot ${BOT_TOKEN}`,
'Content-Type': 'application/json',
},
});
const emoteData = await response.json();
if (!response.ok) {
throw new Error(
`Failed to upload emote: ${
JSON.stringify(emoteData, null, 2) ?? response.statusText
}`,
);
}
return emoteData;
}
async function deleteEmote(
{ BOT_TOKEN, GUILD_ID, emoteId }: {
BOT_TOKEN: string;
GUILD_ID: string;
emoteId: string;
},
): Promise<void> {
const url =
`https://discord.com/api/v10/guilds/${GUILD_ID}/emojis/${emoteId}`;
const response = await fetch(url, {
method: 'DELETE',
headers: {
'Authorization': `Bot ${BOT_TOKEN}`,
'Content-Type': 'application/json',
},
});
if (response.status !== 204) {
throw new Error(
`Failed to upload emote: ${response.statusText}`,
);
}
}
if (import.meta.main) {
const GUILD_ID = '1046932492952805446';
const BOT_TOKEN = Deno.env.get('BOT_TOKEN');
const [emotePath, emoteId] = Deno.args;
if (!BOT_TOKEN) {
throw new Error('BOT_TOKEN is not defined');
}
if (!emotePath) {
throw new Error('Emote image path is not defined');
}
if (emotePath === 'delete') {
if (!emoteId) {
throw new Error('Emote id is not defined');
}
await deleteEmote({
BOT_TOKEN,
GUILD_ID,
emoteId,
});
console.log(`Emote ${emoteId} deleted`);
} else {
const { id, name } = await uploadEmote({
BOT_TOKEN,
GUILD_ID,
emotePath,
});
const output = `${name.toLowerCase()}: '<:${name}:${id}>'`;
copyToClipboard((console.log(output), output));
}
}