create-discord-https 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -0
- package/index.js +389 -0
- package/package.json +35 -0
- package/templates/cloudflare/README.md +32 -0
- package/templates/cloudflare/_gitignore +3 -0
- package/templates/cloudflare/package.json +26 -0
- package/templates/cloudflare/src/DevLayer.js +139 -0
- package/templates/cloudflare/src/commands/fun/joke.js +118 -0
- package/templates/cloudflare/src/commands/reply/ping.js +12 -0
- package/templates/cloudflare/src/commands/utility/help.js +73 -0
- package/templates/cloudflare/src/commands/utility/info.js +60 -0
- package/templates/cloudflare/src/commands/utility/profile.js +36 -0
- package/templates/cloudflare/src/spawner.js +17 -0
- package/templates/cloudflare/wrangler.jsonc +16 -0
- package/templates/cloudflare-ts/README.md +33 -0
- package/templates/cloudflare-ts/_gitignore +3 -0
- package/templates/cloudflare-ts/package.json +27 -0
- package/templates/cloudflare-ts/src/DevLayer.ts +140 -0
- package/templates/cloudflare-ts/src/commands/fun/joke.ts +125 -0
- package/templates/cloudflare-ts/src/commands/index.ts +14 -0
- package/templates/cloudflare-ts/src/commands/reply/ping.ts +12 -0
- package/templates/cloudflare-ts/src/commands/utility/help.ts +73 -0
- package/templates/cloudflare-ts/src/commands/utility/index.ts +14 -0
- package/templates/cloudflare-ts/src/commands/utility/info.ts +56 -0
- package/templates/cloudflare-ts/src/commands/utility/profile.ts +35 -0
- package/templates/cloudflare-ts/src/index.ts +60 -0
- package/templates/cloudflare-ts/src/spawner.js +17 -0
- package/templates/cloudflare-ts/tsconfig.json +18 -0
- package/templates/cloudflare-ts/wrangler.jsonc +19 -0
- package/templates/node/README.md +13 -0
- package/templates/node/_gitignore +3 -0
- package/templates/node/package.json +22 -0
- package/templates/node/src/DevLayer.js +135 -0
- package/templates/node/src/commands/fun/joke.js +118 -0
- package/templates/node/src/commands/reply/ping.js +12 -0
- package/templates/node/src/commands/utility/help.js +73 -0
- package/templates/node/src/commands/utility/info.js +60 -0
- package/templates/node/src/commands/utility/profile.js +36 -0
- package/templates/node-ts/README.md +10 -0
- package/templates/node-ts/_gitignore +3 -0
- package/templates/node-ts/package.json +24 -0
- package/templates/node-ts/src/DevLayer.ts +135 -0
- package/templates/node-ts/src/commands/fun/joke.ts +125 -0
- package/templates/node-ts/src/commands/index.ts +14 -0
- package/templates/node-ts/src/commands/reply/ping.ts +12 -0
- package/templates/node-ts/src/commands/utility/help.ts +73 -0
- package/templates/node-ts/src/commands/utility/index.ts +14 -0
- package/templates/node-ts/src/commands/utility/info.ts +56 -0
- package/templates/node-ts/src/commands/utility/profile.ts +35 -0
- package/templates/node-ts/src/index.ts +50 -0
- package/templates/vercel/.vercelignore +4 -0
- package/templates/vercel/README.md +30 -0
- package/templates/vercel/_gitignore +4 -0
- package/templates/vercel/api/interactions.js +5 -0
- package/templates/vercel/index.html +235 -0
- package/templates/vercel/package.json +23 -0
- package/templates/vercel/src/DevLayer.js +135 -0
- package/templates/vercel/src/commands/fun/joke.js +118 -0
- package/templates/vercel/src/commands/reply/ping.js +12 -0
- package/templates/vercel/src/commands/utility/help.js +73 -0
- package/templates/vercel/src/commands/utility/info.js +60 -0
- package/templates/vercel/src/commands/utility/profile.js +36 -0
- package/templates/vercel/src/spawner.js +18 -0
- package/templates/vercel-ts/.vercelignore +4 -0
- package/templates/vercel-ts/README.md +32 -0
- package/templates/vercel-ts/_gitignore +4 -0
- package/templates/vercel-ts/api/interactions.js +5 -0
- package/templates/vercel-ts/index.html +235 -0
- package/templates/vercel-ts/package.json +25 -0
- package/templates/vercel-ts/src/DevLayer.ts +135 -0
- package/templates/vercel-ts/src/commands/fun/joke.ts +125 -0
- package/templates/vercel-ts/src/commands/index.ts +14 -0
- package/templates/vercel-ts/src/commands/reply/ping.ts +12 -0
- package/templates/vercel-ts/src/commands/utility/help.ts +73 -0
- package/templates/vercel-ts/src/commands/utility/index.ts +14 -0
- package/templates/vercel-ts/src/commands/utility/info.ts +56 -0
- package/templates/vercel-ts/src/commands/utility/profile.ts +35 -0
- package/templates/vercel-ts/src/index.ts +48 -0
- package/templates/vercel-ts/src/spawner.js +18 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MessageFlags,
|
|
3
|
+
MediaGalleryBuilder,
|
|
4
|
+
MediaGalleryItemBuilder,
|
|
5
|
+
TextDisplayBuilder,
|
|
6
|
+
SeparatorBuilder,
|
|
7
|
+
SeparatorSpacingSize,
|
|
8
|
+
ButtonBuilder,
|
|
9
|
+
ButtonStyle,
|
|
10
|
+
ActionRowBuilder,
|
|
11
|
+
} from "discord.https";
|
|
12
|
+
|
|
13
|
+
// https://discordhttps.js.org/classes/interactionRouter.InteractionRouter.html
|
|
14
|
+
import { InteractionRouter } from "discord.https/router";
|
|
15
|
+
|
|
16
|
+
const router = new InteractionRouter();
|
|
17
|
+
|
|
18
|
+
// https://discord.com/developers/docs/change-log/2025-04-22-components-v2
|
|
19
|
+
const components = [
|
|
20
|
+
new MediaGalleryBuilder().addItems(
|
|
21
|
+
new MediaGalleryItemBuilder().setURL(
|
|
22
|
+
"https://raw.githubusercontent.com/discordhttps/discord.https/refs/heads/main/assets/logo.png"
|
|
23
|
+
)
|
|
24
|
+
),
|
|
25
|
+
new TextDisplayBuilder().setContent(
|
|
26
|
+
"**Discord.https** is a robust, modular library for implementing Discord HTTP interactions."
|
|
27
|
+
),
|
|
28
|
+
new SeparatorBuilder()
|
|
29
|
+
.setSpacing(SeparatorSpacingSize.Large)
|
|
30
|
+
.setDivider(true),
|
|
31
|
+
new TextDisplayBuilder().setContent(
|
|
32
|
+
"## Commands Available in This Template\n- /help\n- /index\n- /info\n- Context User Command: Profile (right-click a user and select Apps > Profile)"
|
|
33
|
+
),
|
|
34
|
+
new TextDisplayBuilder().setContent("Related Links"),
|
|
35
|
+
new ActionRowBuilder().addComponents(
|
|
36
|
+
new ButtonBuilder()
|
|
37
|
+
.setStyle(ButtonStyle.Link)
|
|
38
|
+
.setLabel("Github")
|
|
39
|
+
.setEmoji({
|
|
40
|
+
name: "⭐",
|
|
41
|
+
})
|
|
42
|
+
.setURL("https://google.com"),
|
|
43
|
+
new ButtonBuilder()
|
|
44
|
+
.setStyle(ButtonStyle.Link)
|
|
45
|
+
.setLabel("Node Package")
|
|
46
|
+
.setEmoji({
|
|
47
|
+
name: "📦",
|
|
48
|
+
})
|
|
49
|
+
.setURL("https://www.npmjs.com/package/discord.https"),
|
|
50
|
+
new ButtonBuilder()
|
|
51
|
+
.setStyle(ButtonStyle.Link)
|
|
52
|
+
.setLabel("Documentation")
|
|
53
|
+
.setEmoji({
|
|
54
|
+
name: "📘",
|
|
55
|
+
})
|
|
56
|
+
.setURL("https://discordhttps.js.org/")
|
|
57
|
+
),
|
|
58
|
+
];
|
|
59
|
+
|
|
60
|
+
// https://discordhttps.js.org/classes/interactionRouter.InteractionRouter.html#command
|
|
61
|
+
router.command(
|
|
62
|
+
(builder) =>
|
|
63
|
+
builder
|
|
64
|
+
.setName("help")
|
|
65
|
+
.setDescription("Gives you information about discord.https"),
|
|
66
|
+
async (interaction) =>
|
|
67
|
+
await interaction.reply({
|
|
68
|
+
flags: MessageFlags.IsComponentsV2,
|
|
69
|
+
components: components,
|
|
70
|
+
})
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
export default router;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MessageFlags,
|
|
3
|
+
MediaGalleryBuilder,
|
|
4
|
+
MediaGalleryItemBuilder,
|
|
5
|
+
TextDisplayBuilder,
|
|
6
|
+
SeparatorBuilder,
|
|
7
|
+
SeparatorSpacingSize,
|
|
8
|
+
ButtonBuilder,
|
|
9
|
+
ButtonStyle,
|
|
10
|
+
ActionRowBuilder,
|
|
11
|
+
} from "discord.https";
|
|
12
|
+
|
|
13
|
+
// https://discordhttps.js.org/classes/interactionRouter.InteractionRouter.html
|
|
14
|
+
import { InteractionRouter } from "discord.https/router";
|
|
15
|
+
|
|
16
|
+
const router = new InteractionRouter();
|
|
17
|
+
|
|
18
|
+
// https://discord.com/developers/docs/change-log/2025-04-22-components-v2
|
|
19
|
+
const components = [
|
|
20
|
+
new TextDisplayBuilder().setContent("Served via `src/utility/info.js`"),
|
|
21
|
+
new TextDisplayBuilder().setContent("Related Links"),
|
|
22
|
+
new ActionRowBuilder().addComponents(
|
|
23
|
+
new ButtonBuilder()
|
|
24
|
+
.setStyle(ButtonStyle.Link)
|
|
25
|
+
.setLabel("Github")
|
|
26
|
+
.setEmoji({
|
|
27
|
+
name: "⭐",
|
|
28
|
+
})
|
|
29
|
+
.setURL("https://google.com"),
|
|
30
|
+
new ButtonBuilder()
|
|
31
|
+
.setStyle(ButtonStyle.Link)
|
|
32
|
+
.setLabel("Node Package")
|
|
33
|
+
.setEmoji({
|
|
34
|
+
name: "📦",
|
|
35
|
+
})
|
|
36
|
+
.setURL("https://www.npmjs.com/package/discord.https"),
|
|
37
|
+
new ButtonBuilder()
|
|
38
|
+
.setStyle(ButtonStyle.Link)
|
|
39
|
+
.setLabel("Documentation")
|
|
40
|
+
.setEmoji({
|
|
41
|
+
name: "📘",
|
|
42
|
+
})
|
|
43
|
+
.setURL("https://discordhttps.js.org/")
|
|
44
|
+
),
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
// https://discordhttps.js.org/classes/interactionRouter.InteractionRouter.html#command
|
|
48
|
+
router.command(
|
|
49
|
+
(builder) =>
|
|
50
|
+
builder
|
|
51
|
+
.setName("info")
|
|
52
|
+
.setDescription("Gives you information about discord.https"),
|
|
53
|
+
async (interaction) =>
|
|
54
|
+
await interaction.reply({
|
|
55
|
+
flags: MessageFlags.IsComponentsV2,
|
|
56
|
+
components: components,
|
|
57
|
+
})
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
export default router;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// https://discordhttps.js.org/classes/interactionRouter.InteractionRouter.html
|
|
2
|
+
import { InteractionRouter } from "discord.https/router";
|
|
3
|
+
|
|
4
|
+
const router = new InteractionRouter();
|
|
5
|
+
|
|
6
|
+
// // https://discordhttps.js.org/classes/interactionRouter.InteractionRouter.html#usercontextmenu
|
|
7
|
+
|
|
8
|
+
// https://discord.com/developers/docs/reference#image-formatting
|
|
9
|
+
|
|
10
|
+
router.userContextMenu(
|
|
11
|
+
(builder) => builder.setName("profile"),
|
|
12
|
+
async (interaction) => {
|
|
13
|
+
const user = interaction.targetUser;
|
|
14
|
+
|
|
15
|
+
// In the case of endpoints that support GIFs, the hash will begin with a_ if it is available in GIF format.
|
|
16
|
+
const avatarFormat =
|
|
17
|
+
user.avatar && user.avatar.startsWith("a_") ? "gif" : "png";
|
|
18
|
+
|
|
19
|
+
const avatarUrl = user.avatar
|
|
20
|
+
? `/avatars/${user.id}/${user.avatar}.${avatarFormat}`
|
|
21
|
+
|
|
22
|
+
: // In the case of the Default User Avatar endpoint, the value for index depends on whether the user is migrated to the new username system.
|
|
23
|
+
// For users on the new username system, index will be (user_id >> 22) % 6.
|
|
24
|
+
// For users on the legacy username system, index will be discriminator % 5.
|
|
25
|
+
`/embed/avatars/${
|
|
26
|
+
Number(user.discriminator)
|
|
27
|
+
? Number(user.discriminator) % 5
|
|
28
|
+
: (BigInt(user.id) >> 22n) % 6n
|
|
29
|
+
}.png`;
|
|
30
|
+
|
|
31
|
+
// https://discord.com/developers/docs/reference#image-formatting
|
|
32
|
+
await interaction.reply(`https://cdn.discordapp.com/${avatarUrl}`);
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
export default router;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
## Discord.https
|
|
2
|
+
|
|
3
|
+
By default, the URL is: `<URL>/interactions`
|
|
4
|
+
|
|
5
|
+
note: You need to initialize the TypeScript build.
|
|
6
|
+
|
|
7
|
+
**A layer of local tunnel is embedded into the code for easier development**. This means requests pass through multiple layers: Discord → local tunnel → local Vercel server on your computer → your functions. The Induced latency is usually just a few milliseconds and depends on your internet connection. **This local tunneling layer only runs on your machine during development and can be removed if desired.**
|
|
8
|
+
|
|
9
|
+
For more information, view `DevLayer.ts` or, `DevLayer.js`
|
|
10
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "vercel",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Discord HTTPS interaction callback bot powered by discord.https",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
|
+
},
|
|
9
|
+
"type": "module",
|
|
10
|
+
"author": "",
|
|
11
|
+
"license": "ISC",
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@discordhttps/vercel-adapter": "^1.0.4",
|
|
14
|
+
"@vercel/functions": "^3.1.1",
|
|
15
|
+
"chalk": "^5.6.2",
|
|
16
|
+
"discord.https": "^3.0.15"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@types/localtunnel": "^2.0.4",
|
|
20
|
+
"fast-deep-equal": "^3.1.3",
|
|
21
|
+
"localtunnel": "^2.0.2",
|
|
22
|
+
"@types/node": "^24.7.0"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/*
|
|
2
|
+
|
|
3
|
+
------------It is recommended not to modify this layer of code without proper knowledge------------
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
For Info:
|
|
7
|
+
|
|
8
|
+
Summary: This code is a development layer designed to ease development, with automation features such as auto local tunnel and automatic command registration.
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
1. Automatic command registration
|
|
12
|
+
|
|
13
|
+
This layer provides support for automatic command registration by storing the last run command definitions in a file.
|
|
14
|
+
Later, these definitions are read and compared with the current command definitions.
|
|
15
|
+
If they are the same, there is no need to re-register, as nothing has changed.
|
|
16
|
+
If they are different, the command definitions have changed and require re-registration.
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
2.Local Tunnel
|
|
20
|
+
|
|
21
|
+
Local tunnels establish secure pathways between your localhost and the Internet, making it possible to expose web applications for access from anywhere.
|
|
22
|
+
|
|
23
|
+
What LocalTunnel does:
|
|
24
|
+
|
|
25
|
+
- Imagine you’re running a website on your computer at http://localhost:3000.
|
|
26
|
+
- Normally, only you can see it because it’s “local” — it is only on your computer.
|
|
27
|
+
- LocalTunnel gives it a public URL, like https://awesome-name.domain.com, so discord can send a request to your computer.
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
Why this matters for Discord:
|
|
31
|
+
|
|
32
|
+
- Normally, when you open Discord, your computer sends requests to Discord’s servers — everything works because Discord is public.
|
|
33
|
+
- But if you want Discord to **send data to your computer** (like a webhook), your computer needs a public address.
|
|
34
|
+
- LocalTunnel provides that public URL, so Discord knows where to send the requests.
|
|
35
|
+
|
|
36
|
+
Why it’s useful:
|
|
37
|
+
|
|
38
|
+
- Testing webhooks (like Discord)
|
|
39
|
+
- Debugging APIs without deploying to a server
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
export async function tunnelLayer() {
|
|
43
|
+
if (process.env.NODE_ENV !== "production") {
|
|
44
|
+
const chalk = await import("chalk");
|
|
45
|
+
const localtunnel = (await import("localtunnel")).default;
|
|
46
|
+
const tunnel = await localtunnel({
|
|
47
|
+
port: 3000,
|
|
48
|
+
subdomain: "discord-https",
|
|
49
|
+
});
|
|
50
|
+
console.log(
|
|
51
|
+
chalk.default.yellow(
|
|
52
|
+
"[DevLayer] Warning: This URL is intended only for testing and developing your bot.\n" +
|
|
53
|
+
"Never use it in production or hosting.\n" +
|
|
54
|
+
"1. It may be slower, but this is not an issue for bot development.\n" +
|
|
55
|
+
"2. This message should not appear in a production/hosting environment. If it does, your environment variables are incorrect and need to be fixed.\n" +
|
|
56
|
+
"For more information, visit https://discord.com/invite/pSgfJ4K5ej\n\n"
|
|
57
|
+
)
|
|
58
|
+
);
|
|
59
|
+
console.log(
|
|
60
|
+
chalk.default.blue(
|
|
61
|
+
`[DevLayer] Interactions Endpoint URL: ${tunnel.url}/interactions\n`
|
|
62
|
+
)
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
console.log(
|
|
66
|
+
chalk.default.yellow(
|
|
67
|
+
`[DevLayer] Modify your interaction url with the above\n`
|
|
68
|
+
)
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
process.on("SIGINT", async () => {
|
|
72
|
+
tunnel.close();
|
|
73
|
+
console.log("[DevLayer] Tunnel has been shut down");
|
|
74
|
+
process.exit();
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export async function commandRegistrarLayer(client: any, guildId?: string) {
|
|
80
|
+
if (process.env.NODE_ENV !== "production") {
|
|
81
|
+
const FILENAME = "__dev_layer_cache__";
|
|
82
|
+
const chalk = (await import("chalk")).default;
|
|
83
|
+
const isEqual = (await import("fast-deep-equal")).default;
|
|
84
|
+
const { writeFile, access, readFile, constants } = await import(
|
|
85
|
+
"node:fs/promises"
|
|
86
|
+
);
|
|
87
|
+
const { join } = await import("node:path");
|
|
88
|
+
|
|
89
|
+
let localDump = [];
|
|
90
|
+
const filePath = join(import.meta.dirname, FILENAME);
|
|
91
|
+
|
|
92
|
+
try {
|
|
93
|
+
await access(filePath, constants.F_OK);
|
|
94
|
+
const contains = await readFile(filePath, {
|
|
95
|
+
encoding: "utf-8",
|
|
96
|
+
});
|
|
97
|
+
const json = JSON.parse(contains);
|
|
98
|
+
localDump = json;
|
|
99
|
+
} catch {
|
|
100
|
+
await writeFile(filePath, "[]");
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
try {
|
|
104
|
+
// https://github.com/discordhttps/discord.https/blob/main/src/interactionRouter/internal.ts#L271
|
|
105
|
+
if (
|
|
106
|
+
!isEqual(
|
|
107
|
+
localDump,
|
|
108
|
+
// To remove undefined properties
|
|
109
|
+
JSON.parse(JSON.stringify(client.router.CommandDefinitions))
|
|
110
|
+
)
|
|
111
|
+
) {
|
|
112
|
+
console.log(
|
|
113
|
+
chalk.yellowBright(
|
|
114
|
+
`[DevLayer] Command change detected, re-registering with discord in ${
|
|
115
|
+
guildId ? `Guild - ${guildId}` : "Global"
|
|
116
|
+
}...`
|
|
117
|
+
)
|
|
118
|
+
);
|
|
119
|
+
const registar = await client.getRegistar();
|
|
120
|
+
|
|
121
|
+
if (guildId) {
|
|
122
|
+
await registar.localSlashRegistar(guildId);
|
|
123
|
+
} else {
|
|
124
|
+
await registar.globalSlashRegistar();
|
|
125
|
+
}
|
|
126
|
+
writeFile(filePath, JSON.stringify(client.router.CommandDefinitions));
|
|
127
|
+
console.log(
|
|
128
|
+
chalk.greenBright("[DevLayer] Commands synced successfully!")
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
} catch (err) {
|
|
132
|
+
console.error("[DevLayer] Failed to sync commands:", err);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
// This code includes some upper-basic level concepts. If you are an absolute beginner, you may struggle to understand it.
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
MessageFlags,
|
|
5
|
+
MediaGalleryBuilder,
|
|
6
|
+
MediaGalleryItemBuilder,
|
|
7
|
+
TextDisplayBuilder,
|
|
8
|
+
SeparatorBuilder,
|
|
9
|
+
SeparatorSpacingSize,
|
|
10
|
+
ButtonBuilder,
|
|
11
|
+
ButtonStyle,
|
|
12
|
+
ActionRowBuilder,
|
|
13
|
+
} from "discord.https";
|
|
14
|
+
|
|
15
|
+
// https://discordhttps.js.org/classes/interactionRouter.InteractionRouter.html
|
|
16
|
+
import { InteractionRouter } from "discord.https/router";
|
|
17
|
+
|
|
18
|
+
const router = new InteractionRouter();
|
|
19
|
+
|
|
20
|
+
// https://discord.com/developers/docs/change-log/2025-04-22-components-v2
|
|
21
|
+
const header = [
|
|
22
|
+
new MediaGalleryBuilder().addItems(
|
|
23
|
+
new MediaGalleryItemBuilder().setURL(
|
|
24
|
+
"https://raw.githubusercontent.com/discordhttps/discord.https/refs/heads/main/assets/logo.png"
|
|
25
|
+
)
|
|
26
|
+
),
|
|
27
|
+
new TextDisplayBuilder().setContent(
|
|
28
|
+
"**Discord.https** is a robust, modular library for implementing Discord HTTP interactions."
|
|
29
|
+
),
|
|
30
|
+
new SeparatorBuilder()
|
|
31
|
+
.setSpacing(SeparatorSpacingSize.Large)
|
|
32
|
+
.setDivider(true),
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
const footer = [
|
|
36
|
+
new SeparatorBuilder()
|
|
37
|
+
.setSpacing(SeparatorSpacingSize.Large)
|
|
38
|
+
.setDivider(true),
|
|
39
|
+
new ActionRowBuilder().addComponents(
|
|
40
|
+
new ButtonBuilder()
|
|
41
|
+
.setStyle(ButtonStyle.Link)
|
|
42
|
+
.setLabel("Github")
|
|
43
|
+
.setEmoji({
|
|
44
|
+
name: "⭐",
|
|
45
|
+
})
|
|
46
|
+
.setURL("https://google.com"),
|
|
47
|
+
new ButtonBuilder()
|
|
48
|
+
.setStyle(ButtonStyle.Link)
|
|
49
|
+
.setLabel("Node Package")
|
|
50
|
+
.setEmoji({
|
|
51
|
+
name: "📦",
|
|
52
|
+
})
|
|
53
|
+
.setURL("https://www.npmjs.com/package/discord.https"),
|
|
54
|
+
new ButtonBuilder()
|
|
55
|
+
.setStyle(ButtonStyle.Link)
|
|
56
|
+
.setLabel("Documentation")
|
|
57
|
+
.setEmoji({
|
|
58
|
+
name: "📘",
|
|
59
|
+
})
|
|
60
|
+
.setURL("https://discordhttps.js.org/")
|
|
61
|
+
),
|
|
62
|
+
];
|
|
63
|
+
// https://discordhttps.js.org/classes/interactionRouter.InteractionRouter.html#command
|
|
64
|
+
router.command(
|
|
65
|
+
(builder) =>
|
|
66
|
+
builder
|
|
67
|
+
.setName("jokes")
|
|
68
|
+
.setDescription("Gives you random joke")
|
|
69
|
+
.addStringOption((option) =>
|
|
70
|
+
option
|
|
71
|
+
.setName("type")
|
|
72
|
+
.setDescription("Type of joke")
|
|
73
|
+
.addChoices(
|
|
74
|
+
{ name: "general", value: "general" },
|
|
75
|
+
{ name: "knock-knock", value: "knock-knock" },
|
|
76
|
+
{ name: "programming", value: "programming" },
|
|
77
|
+
{ name: "dad", value: "dad" }
|
|
78
|
+
)
|
|
79
|
+
.setRequired(true)
|
|
80
|
+
),
|
|
81
|
+
async (interaction) => {
|
|
82
|
+
// Get the value of the "type" option from the slash command.
|
|
83
|
+
// The 'true' argument makes this required; if it's missing, an error is thrown.
|
|
84
|
+
const option = interaction.options.getString("type", true);
|
|
85
|
+
|
|
86
|
+
// Fetch a joke from the API based on the type (e.g., "general", "programming", etc.)
|
|
87
|
+
// This returns a Promise, so we await it to get the response.
|
|
88
|
+
// Simplest explanation for beginners, https://www.geeksforgeeks.org/node-js/rest-api-introduction
|
|
89
|
+
const response = await fetch(
|
|
90
|
+
`https://official-joke-api.appspot.com/jokes/${option}/random`
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
// Convert the response into JSON format.
|
|
94
|
+
// This allows us to access the joke's content as JavaScript objects.
|
|
95
|
+
// This process is called deserilization,
|
|
96
|
+
|
|
97
|
+
// The received data is in the format of an array: [{ setup: "", punchline: "" }]
|
|
98
|
+
// [body] uses array destructuring. A simple equivalent would be:
|
|
99
|
+
// var body = await response.json();
|
|
100
|
+
// body = body[0];
|
|
101
|
+
|
|
102
|
+
const [body] = (await response.json()) as [
|
|
103
|
+
{
|
|
104
|
+
type: string;
|
|
105
|
+
setup: string;
|
|
106
|
+
punchline: string;
|
|
107
|
+
id: number;
|
|
108
|
+
}
|
|
109
|
+
];
|
|
110
|
+
|
|
111
|
+
// Create a message component (or text display) with the joke content.
|
|
112
|
+
const middlePart = new TextDisplayBuilder().setContent(
|
|
113
|
+
`**Joke**: ${body.setup}\n**Punchline**: ${body.punchline}`
|
|
114
|
+
);
|
|
115
|
+
// send the joke to the user.
|
|
116
|
+
await interaction.reply({
|
|
117
|
+
// - flags: special options for the message (e.g., IsComponentsV2 indicate newer component handling)
|
|
118
|
+
flags: MessageFlags.IsComponentsV2,
|
|
119
|
+
// Here we spread the arrays with `...` to flatten them into a single array.
|
|
120
|
+
components: [...header, middlePart, ...footer],
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
export default router;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { InteractionRouterCollector } from "discord.https/router";
|
|
2
|
+
|
|
3
|
+
// Recommend using PascalCase and ending with the 'Route' suffix
|
|
4
|
+
// for variable naming convention
|
|
5
|
+
|
|
6
|
+
import JokeRoute from "./fun/joke.js";
|
|
7
|
+
import PingRoute from "./reply/ping.js";
|
|
8
|
+
import UtilityRoute from "./utility/index.js";
|
|
9
|
+
|
|
10
|
+
export default new InteractionRouterCollector().register(
|
|
11
|
+
JokeRoute,
|
|
12
|
+
PingRoute,
|
|
13
|
+
UtilityRoute
|
|
14
|
+
);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// https://discordhttps.js.org/classes/interactionRouter.InteractionRouter.html
|
|
2
|
+
import { InteractionRouter } from "discord.https/router";
|
|
3
|
+
|
|
4
|
+
const router = new InteractionRouter();
|
|
5
|
+
|
|
6
|
+
// https://discordhttps.js.org/classes/interactionRouter.InteractionRouter.html#command
|
|
7
|
+
router.command(
|
|
8
|
+
(builder) => builder.setName("ping").setDescription("says pong!"),
|
|
9
|
+
async (interaction) => await interaction.reply("Pong! 🏓")
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
export default router;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MessageFlags,
|
|
3
|
+
MediaGalleryBuilder,
|
|
4
|
+
MediaGalleryItemBuilder,
|
|
5
|
+
TextDisplayBuilder,
|
|
6
|
+
SeparatorBuilder,
|
|
7
|
+
SeparatorSpacingSize,
|
|
8
|
+
ButtonBuilder,
|
|
9
|
+
ButtonStyle,
|
|
10
|
+
ActionRowBuilder,
|
|
11
|
+
} from "discord.https";
|
|
12
|
+
|
|
13
|
+
// https://discordhttps.js.org/classes/interactionRouter.InteractionRouter.html
|
|
14
|
+
import { InteractionRouter } from "discord.https/router";
|
|
15
|
+
|
|
16
|
+
const router = new InteractionRouter();
|
|
17
|
+
|
|
18
|
+
// https://discord.com/developers/docs/change-log/2025-04-22-components-v2
|
|
19
|
+
const components = [
|
|
20
|
+
new MediaGalleryBuilder().addItems(
|
|
21
|
+
new MediaGalleryItemBuilder().setURL(
|
|
22
|
+
"https://raw.githubusercontent.com/discordhttps/discord.https/refs/heads/main/assets/logo.png"
|
|
23
|
+
)
|
|
24
|
+
),
|
|
25
|
+
new TextDisplayBuilder().setContent(
|
|
26
|
+
"**Discord.https** is a robust, modular library for implementing Discord HTTP interactions."
|
|
27
|
+
),
|
|
28
|
+
new SeparatorBuilder()
|
|
29
|
+
.setSpacing(SeparatorSpacingSize.Large)
|
|
30
|
+
.setDivider(true),
|
|
31
|
+
new TextDisplayBuilder().setContent(
|
|
32
|
+
"## Commands Available in This Template\n- /help\n- /index\n- /info\n- Context User Command: Profile (right-click a user and select Apps > Profile)"
|
|
33
|
+
),
|
|
34
|
+
new TextDisplayBuilder().setContent("Related Links"),
|
|
35
|
+
new ActionRowBuilder().addComponents(
|
|
36
|
+
new ButtonBuilder()
|
|
37
|
+
.setStyle(ButtonStyle.Link)
|
|
38
|
+
.setLabel("Github")
|
|
39
|
+
.setEmoji({
|
|
40
|
+
name: "⭐",
|
|
41
|
+
})
|
|
42
|
+
.setURL("https://google.com"),
|
|
43
|
+
new ButtonBuilder()
|
|
44
|
+
.setStyle(ButtonStyle.Link)
|
|
45
|
+
.setLabel("Node Package")
|
|
46
|
+
.setEmoji({
|
|
47
|
+
name: "📦",
|
|
48
|
+
})
|
|
49
|
+
.setURL("https://www.npmjs.com/package/discord.https"),
|
|
50
|
+
new ButtonBuilder()
|
|
51
|
+
.setStyle(ButtonStyle.Link)
|
|
52
|
+
.setLabel("Documentation")
|
|
53
|
+
.setEmoji({
|
|
54
|
+
name: "📘",
|
|
55
|
+
})
|
|
56
|
+
.setURL("https://discordhttps.js.org/")
|
|
57
|
+
),
|
|
58
|
+
];
|
|
59
|
+
|
|
60
|
+
// https://discordhttps.js.org/classes/interactionRouter.InteractionRouter.html#command
|
|
61
|
+
router.command(
|
|
62
|
+
(builder) =>
|
|
63
|
+
builder
|
|
64
|
+
.setName("help")
|
|
65
|
+
.setDescription("Gives you information about discord.https"),
|
|
66
|
+
async (interaction) =>
|
|
67
|
+
await interaction.reply({
|
|
68
|
+
flags: MessageFlags.IsComponentsV2,
|
|
69
|
+
components: components,
|
|
70
|
+
})
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
export default router;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { InteractionRouterCollector } from "discord.https/router";
|
|
2
|
+
|
|
3
|
+
// Recommend using PascalCase and ending with the 'Route' suffix
|
|
4
|
+
// for variable naming convention
|
|
5
|
+
|
|
6
|
+
import HelpRoute from "./help.js";
|
|
7
|
+
import InfoRoute from "./info.js";
|
|
8
|
+
import ProfileRoute from "./profile.js";
|
|
9
|
+
|
|
10
|
+
export default new InteractionRouterCollector().register(
|
|
11
|
+
HelpRoute,
|
|
12
|
+
InfoRoute,
|
|
13
|
+
ProfileRoute
|
|
14
|
+
);
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MessageFlags,
|
|
3
|
+
TextDisplayBuilder,
|
|
4
|
+
ButtonBuilder,
|
|
5
|
+
ButtonStyle,
|
|
6
|
+
ActionRowBuilder,
|
|
7
|
+
} from "discord.https";
|
|
8
|
+
|
|
9
|
+
// https://discordhttps.js.org/classes/interactionRouter.InteractionRouter.html
|
|
10
|
+
import { InteractionRouter } from "discord.https/router";
|
|
11
|
+
|
|
12
|
+
const router = new InteractionRouter();
|
|
13
|
+
|
|
14
|
+
// https://discord.com/developers/docs/change-log/2025-04-22-components-v2
|
|
15
|
+
const components = [
|
|
16
|
+
new TextDisplayBuilder().setContent("Served via `src/utility/info.js`"),
|
|
17
|
+
new TextDisplayBuilder().setContent("Related Links"),
|
|
18
|
+
new ActionRowBuilder().addComponents(
|
|
19
|
+
new ButtonBuilder()
|
|
20
|
+
.setStyle(ButtonStyle.Link)
|
|
21
|
+
.setLabel("Github")
|
|
22
|
+
.setEmoji({
|
|
23
|
+
name: "⭐",
|
|
24
|
+
})
|
|
25
|
+
.setURL("https://google.com"),
|
|
26
|
+
new ButtonBuilder()
|
|
27
|
+
.setStyle(ButtonStyle.Link)
|
|
28
|
+
.setLabel("Node Package")
|
|
29
|
+
.setEmoji({
|
|
30
|
+
name: "📦",
|
|
31
|
+
})
|
|
32
|
+
.setURL("https://www.npmjs.com/package/discord.https"),
|
|
33
|
+
new ButtonBuilder()
|
|
34
|
+
.setStyle(ButtonStyle.Link)
|
|
35
|
+
.setLabel("Documentation")
|
|
36
|
+
.setEmoji({
|
|
37
|
+
name: "📘",
|
|
38
|
+
})
|
|
39
|
+
.setURL("https://discordhttps.js.org/")
|
|
40
|
+
),
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
// https://discordhttps.js.org/classes/interactionRouter.InteractionRouter.html#command
|
|
44
|
+
router.command(
|
|
45
|
+
(builder) =>
|
|
46
|
+
builder
|
|
47
|
+
.setName("info")
|
|
48
|
+
.setDescription("Gives you information about discord.https"),
|
|
49
|
+
async (interaction) =>
|
|
50
|
+
await interaction.reply({
|
|
51
|
+
flags: MessageFlags.IsComponentsV2,
|
|
52
|
+
components: components,
|
|
53
|
+
})
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
export default router;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// https://discordhttps.js.org/classes/interactionRouter.InteractionRouter.html
|
|
2
|
+
import { InteractionRouter } from "discord.https/router";
|
|
3
|
+
|
|
4
|
+
const router = new InteractionRouter();
|
|
5
|
+
|
|
6
|
+
// https://discordhttps.js.org/classes/interactionRouter.InteractionRouter.html#usercontextmenu
|
|
7
|
+
|
|
8
|
+
// https://discord.com/developers/docs/reference#image-formatting
|
|
9
|
+
|
|
10
|
+
router.userContextMenu(
|
|
11
|
+
(builder) => builder.setName("profile"),
|
|
12
|
+
async (interaction) => {
|
|
13
|
+
const user = interaction.targetUser;
|
|
14
|
+
|
|
15
|
+
// In the case of endpoints that support GIFs, the hash will begin with a_ if it is available in GIF format.
|
|
16
|
+
const avatarFormat =
|
|
17
|
+
user.avatar && user.avatar!.startsWith("a_") ? "gif" : "png";
|
|
18
|
+
|
|
19
|
+
const avatarUrl = user.avatar
|
|
20
|
+
? `/avatars/${user.id}/${user.avatar}.${avatarFormat}`
|
|
21
|
+
: // In the case of the Default User Avatar endpoint, the value for index depends on whether the user is migrated to the new username system.
|
|
22
|
+
// For users on the new username system, index will be (user_id >> 22) % 6.
|
|
23
|
+
// For users on the legacy username system, index will be discriminator % 5.
|
|
24
|
+
`/embed/avatars/${
|
|
25
|
+
Number(user.discriminator)
|
|
26
|
+
? Number(user.discriminator) % 5
|
|
27
|
+
: (BigInt(user.id) >> 22n) % 6n
|
|
28
|
+
}.png`;
|
|
29
|
+
|
|
30
|
+
// https://discord.com/developers/docs/reference#image-formatting
|
|
31
|
+
await interaction.reply(`https://cdn.discordapp.com/${avatarUrl}`);
|
|
32
|
+
}
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
export default router;
|