@theholocron/discord-client 1.57.1-alpha.2 → 1.58.0-alpha.10
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 -8
- package/dist/index.d.mts +377 -2
- package/dist/index.mjs +148 -11
- package/package.json +15 -15
package/README.md
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
<!-- alex disable host-hostess -->
|
|
2
|
+
|
|
1
3
|
# @theholocron/discord-client
|
|
2
4
|
|
|
3
5
|
A TypeScript client for Discord — posts messages through webhooks, and (with a bot token) provisions a server's channels, roles and webhooks.
|
|
@@ -99,19 +101,20 @@ the resource, look it up by name before creating it again. A webhook created
|
|
|
99
101
|
that way cannot have its URL read back, since Discord returns the token only on
|
|
100
102
|
the create response.
|
|
101
103
|
|
|
102
|
-
| Resource | Methods
|
|
103
|
-
| -------------------- |
|
|
104
|
-
| `client.users` | `me()` — `GET /users/@me`, a cheap token check; `get(id)` — a user's name; `guilds({ limit, after })` — `GET /users/@me/guilds`, the servers the bot is in and whether it owns each (look here before retrying `guilds.create`)
|
|
105
|
-
| `client.application` | `get`, `modify` (the bot's own application: description, tags, install settings, URLs, and `flags` for the privileged-intent toggles; `redirect_uris` can be read but not written, so add them in the developer portal)
|
|
106
|
-
| `client.guilds` | `get`, `modify`, `channels`, `createChannel`, `roles`, `createRole`, `modifyRole`, `create`, `delete`, `emojis`, `member`, `members`, `membersWithRole`, `addMemberRole`, `removeMemberRole`, `welcomeScreen`, `modifyWelcomeScreen`, `onboarding`, `modifyOnboarding`
|
|
107
|
-
| `client.channels` | `modify`, `webhooks`, `createWebhook`, `createMessage`, `createInvite`, `messages`, `pin`, `deleteMessage`
|
|
108
|
-
| `client.
|
|
104
|
+
| Resource | Methods |
|
|
105
|
+
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
106
|
+
| `client.users` | `me()` — `GET /users/@me`, a cheap token check; `get(id)` — a user's name; `guilds({ limit, after })` — `GET /users/@me/guilds`, the servers the bot is in and whether it owns each (look here before retrying `guilds.create`) |
|
|
107
|
+
| `client.application` | `get`, `modify` (the bot's own application: description, tags, install settings, URLs, and `flags` for the privileged-intent toggles; `redirect_uris` can be read but not written, so add them in the developer portal) |
|
|
108
|
+
| `client.guilds` | `get`, `modify`, `channels`, `createChannel`, `roles`, `createRole`, `modifyRole`, `create`, `delete`, `emojis`, `member`, `members`, `membersWithRole`, `addMemberRole`, `removeMemberRole`, `welcomeScreen`, `modifyWelcomeScreen`, `onboarding`, `modifyOnboarding` |
|
|
109
|
+
| `client.channels` | `modify`, `webhooks`, `createWebhook`, `createMessage`, `message`, `editMessage`, `createInvite`, `messages`, `pin`, `deleteMessage` |
|
|
110
|
+
| `client.threads` | `createForumPost` — a post in a forum channel with its tags and first message; `modify` — a thread's title, tags, archived and locked state; `active` — the server's active threads; `archived` — one page of a channel's archived threads; `inChannel` — every post of a forum, active and archived |
|
|
111
|
+
| `client.webhooks` | `modify` (name, avatar), `delete` |
|
|
109
112
|
|
|
110
113
|
`permissions([...names])` builds the decimal-string bitfield Discord expects, and
|
|
111
114
|
`permissionNames(bitfield)` reads one back; `Permission` holds the bits themselves.
|
|
112
115
|
Welcome screen and onboarding only work once the server has the community
|
|
113
116
|
features on, and `modifyOnboarding` is a `PUT` that replaces the whole config.
|
|
114
|
-
`channels.createMessage`
|
|
117
|
+
`channels.createMessage`, `channels.editMessage` and the first message of `threads.createForumPost` turn every mention off unless `allowed_mentions` says
|
|
115
118
|
otherwise.
|
|
116
119
|
|
|
117
120
|
The bot needs Manage Channels, Manage Roles, Manage Webhooks and (for server settings, welcome screen and onboarding) Manage Server in the server, plus View Channel and Send Messages in any channel it posts to with `channels.createMessage`.
|
|
@@ -135,6 +138,10 @@ hands it over, `channels.createInvite` makes the link to join it, and `guilds.de
|
|
|
135
138
|
`executeAndWait` posts and returns the message id and `deleteMessage` removes it, so a check can post a line, read it back
|
|
136
139
|
with `channels.messages`, and clean up. `channels.pin` pins a message.
|
|
137
140
|
|
|
141
|
+
### Forum posts
|
|
142
|
+
|
|
143
|
+
`guilds.createChannel` with `type: ChannelType.Forum` and `available_tags` makes a forum; `channels.modify` replaces its tags (send the whole list, with each kept tag's `id`). `threads.createForumPost(channelId, { name, applied_tags, message })` makes a post, and `message.flags: MessageFlag.SuppressNotifications` posts it without notifying anyone, as a backfill should. `threads.modify` retitles or retags a post, and writing to an archived post unarchives it. Discord hides a post that has been quiet for a while, so `threads.inChannel(guildId, forumId)` reads the archived pages too before you decide a post does not exist. Creating a post is not idempotent: look it up first. Only the bot, which owns its posts, and members with Manage Threads can change a post's tags.
|
|
144
|
+
|
|
138
145
|
Discord only returns a webhook's `token`/`url` for webhooks the same
|
|
139
146
|
application created, so a pre-existing webhook can be found by name but its URL
|
|
140
147
|
cannot be read back.
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
/** What fetching a webhook by id and token returns. */
|
|
1
2
|
interface DiscordWebhookInfo {
|
|
3
|
+
/** The webhook id. */
|
|
2
4
|
id: string;
|
|
5
|
+
/** The webhook name. */
|
|
3
6
|
name: string;
|
|
7
|
+
/** Id of the server the webhook belongs to, when Discord includes it. */
|
|
4
8
|
guild_id?: string;
|
|
5
9
|
}
|
|
6
10
|
/** Parse a Discord webhook URL into its id and token parts. */
|
|
@@ -8,41 +12,64 @@ export declare function parseWebhookUrl(url: string): {
|
|
|
8
12
|
id: string;
|
|
9
13
|
token: string;
|
|
10
14
|
};
|
|
15
|
+
/** Options for `createDiscordClient`. */
|
|
11
16
|
interface DiscordClientOptions {
|
|
12
17
|
/** Override base URL for testing. Defaults to https://discord.com/api/v10. */
|
|
13
18
|
baseUrl?: string;
|
|
14
19
|
/** Override fetch for testing. Defaults to globalThis.fetch. */
|
|
15
20
|
fetch?: typeof fetch;
|
|
16
21
|
}
|
|
22
|
+
/** Options for `createDiscordBotClient`. */
|
|
17
23
|
export interface DiscordBotClientOptions {
|
|
18
24
|
/** Bot token from the Discord developer portal (Bot → Reset Token). */
|
|
19
25
|
botToken: string;
|
|
20
|
-
/**
|
|
26
|
+
/**
|
|
27
|
+
* Override base URL for testing. Defaults to https://discord.com/api/v10.
|
|
28
|
+
* The bot token is sent to whatever host this names, so never derive it from untrusted input.
|
|
29
|
+
*/
|
|
21
30
|
baseUrl?: string;
|
|
22
31
|
/** Override fetch for testing. Defaults to globalThis.fetch. */
|
|
23
32
|
fetch?: typeof fetch;
|
|
24
33
|
/** Per-request deadline in milliseconds. Defaults to 15000. */
|
|
25
34
|
timeoutMs?: number;
|
|
26
|
-
/**
|
|
35
|
+
/**
|
|
36
|
+
* Retries after a 429 (rate limit) before giving up. Defaults to 3.
|
|
37
|
+
* Each retry waits for the `Retry-After` Discord sends; a wait longer than 10 seconds fails immediately.
|
|
38
|
+
*/
|
|
27
39
|
maxRetries?: number;
|
|
28
40
|
/** Wait between rate-limit retries; a test seam. Defaults to `setTimeout`. */
|
|
29
41
|
sleep?: (ms: number) => Promise<void>;
|
|
30
42
|
}
|
|
31
43
|
/** Discord channel `type` values this client creates or reads. */
|
|
32
44
|
export declare const ChannelType: {
|
|
45
|
+
/** A text channel. */
|
|
33
46
|
readonly Text: 0;
|
|
47
|
+
/** A category that groups channels. */
|
|
34
48
|
readonly Category: 4;
|
|
49
|
+
/** An announcement channel. */
|
|
35
50
|
readonly Announcement: 5;
|
|
51
|
+
/** A forum channel. */
|
|
36
52
|
readonly Forum: 15;
|
|
37
53
|
};
|
|
54
|
+
/** Bits of a message's `flags` that a bot may set when it posts. */
|
|
55
|
+
export declare const MessageFlag: {
|
|
56
|
+
/** Posts without notifying anyone, as a backfill of many messages should. */
|
|
57
|
+
readonly SuppressNotifications: number;
|
|
58
|
+
};
|
|
59
|
+
/** A Discord account, as the API returns it. */
|
|
38
60
|
export interface DiscordUser {
|
|
61
|
+
/** The user id. */
|
|
39
62
|
id: string;
|
|
63
|
+
/** The account's username. */
|
|
40
64
|
username: string;
|
|
65
|
+
/** Whether the account is a bot. */
|
|
41
66
|
bot?: boolean;
|
|
42
67
|
}
|
|
43
68
|
/** A server as `GET /users/@me/guilds` lists it: a summary, not the full guild. */
|
|
44
69
|
export interface DiscordUserGuild {
|
|
70
|
+
/** The server id. */
|
|
45
71
|
id: string;
|
|
72
|
+
/** The server name. */
|
|
46
73
|
name: string;
|
|
47
74
|
/** Whether the caller (here, the bot) owns the server. */
|
|
48
75
|
owner: boolean;
|
|
@@ -51,13 +78,16 @@ export interface DiscordUserGuild {
|
|
|
51
78
|
}
|
|
52
79
|
/** Page options for `users.guilds`; Discord allows a `limit` of 1–200; values outside that are clamped. */
|
|
53
80
|
export interface ListUserGuildsInput {
|
|
81
|
+
/** How many servers to return, 1 to 200. */
|
|
54
82
|
limit?: number;
|
|
55
83
|
/** Return servers after this server id. */
|
|
56
84
|
after?: string;
|
|
57
85
|
}
|
|
58
86
|
/** Guild fields `guilds.modify` can change; the numeric enums are Discord's own. */
|
|
59
87
|
export interface DiscordGuild {
|
|
88
|
+
/** The server id. */
|
|
60
89
|
id: string;
|
|
90
|
+
/** The server name. */
|
|
61
91
|
name: string;
|
|
62
92
|
/** 0 none, 1 low, 2 medium, 3 high, 4 very high. */
|
|
63
93
|
verification_level?: number;
|
|
@@ -65,84 +95,136 @@ export interface DiscordGuild {
|
|
|
65
95
|
default_message_notifications?: number;
|
|
66
96
|
/** 0 disabled, 1 members without roles, 2 all members. */
|
|
67
97
|
explicit_content_filter?: number;
|
|
98
|
+
/** Id of the channel for system messages, or `null` for none. */
|
|
68
99
|
system_channel_id?: string | null;
|
|
69
100
|
/** Bitfield of system-channel messages to suppress. */
|
|
70
101
|
system_channel_flags?: number;
|
|
102
|
+
/** Id of the rules channel, or `null` for none. */
|
|
71
103
|
rules_channel_id?: string | null;
|
|
104
|
+
/** Id of the channel for Discord's community updates, or `null` for none. */
|
|
72
105
|
public_updates_channel_id?: string | null;
|
|
106
|
+
/** The server's preferred locale, such as `en-US`. */
|
|
73
107
|
preferred_locale?: string;
|
|
108
|
+
/** The server description, or `null` when unset. */
|
|
74
109
|
description?: string | null;
|
|
75
110
|
/** `COMMUNITY` here means the community features (welcome screen, onboarding) are available. */
|
|
76
111
|
features?: string[];
|
|
77
112
|
}
|
|
113
|
+
/** What `PATCH /guilds/{id}` takes; a field left out is left alone. */
|
|
78
114
|
export interface ModifyGuildInput {
|
|
115
|
+
/** A new server name. */
|
|
79
116
|
name?: string;
|
|
80
117
|
/** Hands the server to another user; only the current owner (never a bot that does not own it) may. */
|
|
81
118
|
owner_id?: string;
|
|
119
|
+
/** Verification level: 0 none, 1 low, 2 medium, 3 high, 4 very high. */
|
|
82
120
|
verification_level?: number;
|
|
121
|
+
/** Notification default: 0 all messages, 1 only @mentions. */
|
|
83
122
|
default_message_notifications?: number;
|
|
123
|
+
/** Content filter: 0 disabled, 1 members without roles, 2 all members. */
|
|
84
124
|
explicit_content_filter?: number;
|
|
125
|
+
/** Id of the channel for system messages, or `null` for none. */
|
|
85
126
|
system_channel_id?: string | null;
|
|
127
|
+
/** Bitfield of system-channel messages to suppress. */
|
|
86
128
|
system_channel_flags?: number;
|
|
129
|
+
/** Id of the rules channel, or `null` for none. */
|
|
87
130
|
rules_channel_id?: string | null;
|
|
131
|
+
/** Id of the channel for Discord's community updates, or `null` for none. */
|
|
88
132
|
public_updates_channel_id?: string | null;
|
|
133
|
+
/** The server's preferred locale, such as `en-US`. */
|
|
89
134
|
preferred_locale?: string;
|
|
135
|
+
/** The server description, or `null` to clear it. */
|
|
90
136
|
description?: string | null;
|
|
91
137
|
/** The full list of mutable guild features (for example `COMMUNITY`); Discord ignores the ones it manages itself. */
|
|
92
138
|
features?: string[];
|
|
93
139
|
}
|
|
140
|
+
/** A channel featured on a server's welcome screen. */
|
|
94
141
|
export interface DiscordWelcomeChannel {
|
|
142
|
+
/** Id of the featured channel. */
|
|
95
143
|
channel_id: string;
|
|
144
|
+
/** The blurb shown beside the channel. */
|
|
96
145
|
description: string;
|
|
146
|
+
/** Id of a custom emoji shown beside it, or `null`. */
|
|
97
147
|
emoji_id?: string | null;
|
|
148
|
+
/** Name of a Unicode emoji shown beside it, or `null`. */
|
|
98
149
|
emoji_name?: string | null;
|
|
99
150
|
}
|
|
100
151
|
/** Whether the screen is on is the `WELCOME_SCREEN_ENABLED` entry in the guild's `features`; the object has no flag. */
|
|
101
152
|
export interface DiscordWelcomeScreen {
|
|
153
|
+
/** The server description shown on the screen, or `null`. */
|
|
102
154
|
description: string | null;
|
|
155
|
+
/** The channels featured on the screen. */
|
|
103
156
|
welcome_channels: DiscordWelcomeChannel[];
|
|
104
157
|
}
|
|
158
|
+
/** What `PATCH /guilds/{id}/welcome-screen` takes. */
|
|
105
159
|
export interface ModifyWelcomeScreenInput {
|
|
160
|
+
/** Whether to turn the welcome screen on or off. */
|
|
106
161
|
enabled?: boolean;
|
|
162
|
+
/** New welcome-screen description, or `null` to clear it. */
|
|
107
163
|
description?: string | null;
|
|
164
|
+
/** The channels to feature on the welcome screen. */
|
|
108
165
|
welcome_channels?: DiscordWelcomeChannel[];
|
|
109
166
|
}
|
|
167
|
+
/** A server emoji; `id` is `null` for a standard Unicode emoji. */
|
|
110
168
|
export interface DiscordEmoji {
|
|
169
|
+
/** The emoji id, or `null` for a Unicode emoji. */
|
|
111
170
|
id: string | null;
|
|
171
|
+
/** The emoji name (the Unicode character for a standard emoji), or `null`. */
|
|
112
172
|
name: string | null;
|
|
173
|
+
/** Whether the emoji is animated. */
|
|
113
174
|
animated?: boolean;
|
|
114
175
|
}
|
|
176
|
+
/** One answer a member can pick in an onboarding prompt. */
|
|
115
177
|
export interface DiscordOnboardingOption {
|
|
178
|
+
/** The option id; absent when creating a new option. */
|
|
116
179
|
id?: string;
|
|
180
|
+
/** The text of the option. */
|
|
117
181
|
title: string;
|
|
182
|
+
/** A short explanation shown under the title. */
|
|
118
183
|
description?: string | null;
|
|
184
|
+
/** Ids of the channels a member who picks this option is shown. */
|
|
119
185
|
channel_ids?: string[];
|
|
186
|
+
/** Ids of the roles a member who picks this option is given. */
|
|
120
187
|
role_ids?: string[];
|
|
121
188
|
/** Discord returns the emoji as an object... */
|
|
122
189
|
emoji?: DiscordEmoji;
|
|
123
190
|
/** ...and takes it as these three fields (a custom emoji has `emoji_id`, a Unicode one only `emoji_name`). */
|
|
124
191
|
emoji_id?: string | null;
|
|
192
|
+
/** Name of a Unicode emoji, or of a custom emoji together with `emoji_id`. */
|
|
125
193
|
emoji_name?: string | null;
|
|
194
|
+
/** Whether the custom emoji is animated. */
|
|
126
195
|
emoji_animated?: boolean;
|
|
127
196
|
}
|
|
197
|
+
/** A question in the server's onboarding flow, with the options a member picks from. */
|
|
128
198
|
export interface DiscordOnboardingPrompt {
|
|
199
|
+
/** The prompt id; absent when creating a new prompt. */
|
|
129
200
|
id?: string;
|
|
130
201
|
/** 0 multiple choice, 1 dropdown. */
|
|
131
202
|
type: number;
|
|
203
|
+
/** The question text. */
|
|
132
204
|
title: string;
|
|
205
|
+
/** Whether a member may pick only one option. */
|
|
133
206
|
single_select: boolean;
|
|
207
|
+
/** Whether a member must answer. */
|
|
134
208
|
required: boolean;
|
|
209
|
+
/** Whether the prompt appears during onboarding (otherwise only in Channels & Roles). */
|
|
135
210
|
in_onboarding: boolean;
|
|
211
|
+
/** The answers a member can choose from. */
|
|
136
212
|
options: DiscordOnboardingOption[];
|
|
137
213
|
}
|
|
214
|
+
/** A server's onboarding configuration, as `GET /guilds/{id}/onboarding` returns and `PUT` takes it. */
|
|
138
215
|
export interface DiscordOnboarding {
|
|
216
|
+
/** The server id. */
|
|
139
217
|
guild_id?: string;
|
|
218
|
+
/** The questions asked during onboarding. */
|
|
140
219
|
prompts: DiscordOnboardingPrompt[];
|
|
220
|
+
/** Ids of the channels every new member is shown by default. */
|
|
141
221
|
default_channel_ids: string[];
|
|
222
|
+
/** Whether onboarding is turned on. */
|
|
142
223
|
enabled: boolean;
|
|
143
224
|
/** 0 default, 1 advanced. */
|
|
144
225
|
mode?: number;
|
|
145
226
|
}
|
|
227
|
+
/** A per-role or per-member override of a channel's permissions. */
|
|
146
228
|
export interface DiscordPermissionOverwrite {
|
|
147
229
|
/** Role or user id. */
|
|
148
230
|
id: string;
|
|
@@ -153,92 +235,255 @@ export interface DiscordPermissionOverwrite {
|
|
|
153
235
|
/** Bitfield of permissions to deny, as a string. */
|
|
154
236
|
deny: string;
|
|
155
237
|
}
|
|
238
|
+
/** A channel or category in a server, as Discord returns it. */
|
|
156
239
|
export interface DiscordChannel {
|
|
240
|
+
/** The channel id. */
|
|
157
241
|
id: string;
|
|
242
|
+
/** The channel name. */
|
|
158
243
|
name: string;
|
|
244
|
+
/** The channel type; see `ChannelType`. */
|
|
159
245
|
type: number;
|
|
246
|
+
/** Id of the category the channel sits in, or `null` for none. */
|
|
160
247
|
parent_id?: string | null;
|
|
248
|
+
/** The channel topic, or `null` when unset. */
|
|
161
249
|
topic?: string | null;
|
|
250
|
+
/** The channel's sort position within its category or the server. */
|
|
162
251
|
position?: number;
|
|
252
|
+
/** Permission overrides set on this channel. */
|
|
163
253
|
permission_overwrites?: DiscordPermissionOverwrite[];
|
|
254
|
+
/** The tags a post in this forum channel can carry; present on forum channels only. */
|
|
255
|
+
available_tags?: DiscordForumTag[];
|
|
256
|
+
}
|
|
257
|
+
/** A tag a forum post can carry, with the emoji shown beside its name. */
|
|
258
|
+
export interface DiscordForumTag {
|
|
259
|
+
/** The tag id. */
|
|
260
|
+
id: string;
|
|
261
|
+
/** The tag name, up to 20 characters. */
|
|
262
|
+
name: string;
|
|
263
|
+
/** Whether only members with Manage Threads can apply the tag. */
|
|
264
|
+
moderated: boolean;
|
|
265
|
+
/** Id of the tag's custom emoji, or `null` when it has none. */
|
|
266
|
+
emoji_id: string | null;
|
|
267
|
+
/** Name of the tag's Unicode emoji, or `null` when it has none. */
|
|
268
|
+
emoji_name: string | null;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* A tag as sent when a forum is created or its tags are replaced. Send the whole list every time: Discord replaces
|
|
272
|
+
* the tags with it, and a tag keeps its id only when `id` is given.
|
|
273
|
+
*/
|
|
274
|
+
export interface ForumTagInput {
|
|
275
|
+
/** The id of a tag that already exists; leave it out to make a new one. */
|
|
276
|
+
id?: string;
|
|
277
|
+
/** The tag name, up to 20 characters. */
|
|
278
|
+
name: string;
|
|
279
|
+
/** Whether only members with Manage Threads can apply the tag. */
|
|
280
|
+
moderated?: boolean;
|
|
281
|
+
/** Id of a custom emoji for the tag. */
|
|
282
|
+
emoji_id?: string | null;
|
|
283
|
+
/** Name of a Unicode emoji for the tag, such as `💬`. */
|
|
284
|
+
emoji_name?: string | null;
|
|
285
|
+
}
|
|
286
|
+
/** What Discord says about a thread's state. */
|
|
287
|
+
export interface DiscordThreadMetadata {
|
|
288
|
+
/** Whether the thread is archived (hidden from the active list until it is used again). */
|
|
289
|
+
archived: boolean;
|
|
290
|
+
/** Minutes of silence after which the thread archives: 60, 1440, 4320 or 10080. */
|
|
291
|
+
auto_archive_duration: number;
|
|
292
|
+
/** When the archived state last changed, as an ISO 8601 timestamp. */
|
|
293
|
+
archive_timestamp: string;
|
|
294
|
+
/** Whether only members with Manage Threads can unarchive and post in the thread. */
|
|
295
|
+
locked: boolean;
|
|
296
|
+
}
|
|
297
|
+
/** A thread, which in a forum channel is a post. */
|
|
298
|
+
export interface DiscordThread extends DiscordChannel {
|
|
299
|
+
/** Id of the forum or text channel the thread belongs to. */
|
|
300
|
+
parent_id: string;
|
|
301
|
+
/** Id of the user who made the thread. */
|
|
302
|
+
owner_id?: string;
|
|
303
|
+
/** Ids of the forum tags applied to the post. */
|
|
304
|
+
applied_tags?: string[];
|
|
305
|
+
/** The thread's archive state. */
|
|
306
|
+
thread_metadata: DiscordThreadMetadata;
|
|
307
|
+
}
|
|
308
|
+
/** What `POST /channels/{id}/threads` takes to make a post in a forum channel. */
|
|
309
|
+
export interface CreateForumPostInput {
|
|
310
|
+
/** The post's title, up to 100 characters. */
|
|
311
|
+
name: string;
|
|
312
|
+
/** Minutes of silence after which the post archives: 60, 1440, 4320 or 10080. */
|
|
313
|
+
auto_archive_duration?: number;
|
|
314
|
+
/** Ids of the forum tags to apply. */
|
|
315
|
+
applied_tags?: string[];
|
|
316
|
+
/** The post's first message. */
|
|
317
|
+
message: CreateMessageInput;
|
|
318
|
+
}
|
|
319
|
+
/** What making a forum post returns: the new thread, with the first message that opens it. */
|
|
320
|
+
export interface DiscordForumPost extends DiscordThread {
|
|
321
|
+
/** The post's first message; its id is the thread's id. */
|
|
322
|
+
message?: DiscordMessage;
|
|
323
|
+
}
|
|
324
|
+
/** What `PATCH /channels/{id}` takes to change a thread. A field left out is left alone. */
|
|
325
|
+
export interface ModifyThreadInput {
|
|
326
|
+
/** A new title, up to 100 characters. */
|
|
327
|
+
name?: string;
|
|
328
|
+
/** Ids of the forum tags to apply, replacing the current ones. */
|
|
329
|
+
applied_tags?: string[];
|
|
330
|
+
/** Whether the thread is archived. Writing to an archived thread unarchives it. */
|
|
331
|
+
archived?: boolean;
|
|
332
|
+
/** Whether only members with Manage Threads can unarchive and post in the thread. */
|
|
333
|
+
locked?: boolean;
|
|
334
|
+
/** Minutes of silence after which the thread archives: 60, 1440, 4320 or 10080. */
|
|
335
|
+
auto_archive_duration?: number;
|
|
336
|
+
}
|
|
337
|
+
/** One page of the archived threads of a channel. */
|
|
338
|
+
export interface DiscordArchivedThreads {
|
|
339
|
+
/** The threads on this page, newest archived first. */
|
|
340
|
+
threads: DiscordThread[];
|
|
341
|
+
/** Whether more archived threads remain after this page. */
|
|
342
|
+
has_more: boolean;
|
|
343
|
+
}
|
|
344
|
+
/** What `GET /channels/{id}/threads/archived/public` takes. */
|
|
345
|
+
export interface ListArchivedThreadsInput {
|
|
346
|
+
/** Only threads archived before this ISO 8601 timestamp. */
|
|
347
|
+
before?: string;
|
|
348
|
+
/** The page size, 1 to 100. Defaults to 100. */
|
|
349
|
+
limit?: number;
|
|
164
350
|
}
|
|
351
|
+
/** What `PATCH /channels/{id}/messages/{id}` takes. A field left out is left alone. */
|
|
352
|
+
export interface EditMessageInput {
|
|
353
|
+
/** The new message text. */
|
|
354
|
+
content: string;
|
|
355
|
+
/** Defaults to no mentions, so editing in a pasted `@everyone` cannot ping anyone. */
|
|
356
|
+
allowed_mentions?: CreateMessageInput["allowed_mentions"];
|
|
357
|
+
}
|
|
358
|
+
/** What `POST /guilds/{id}/channels` takes. */
|
|
165
359
|
export interface CreateChannelInput {
|
|
360
|
+
/** The channel name. */
|
|
166
361
|
name: string;
|
|
362
|
+
/** The channel type; see `ChannelType`. Discord creates a text channel when omitted. */
|
|
167
363
|
type?: number;
|
|
364
|
+
/** The channel topic. */
|
|
168
365
|
topic?: string;
|
|
366
|
+
/** Id of the category to create the channel in. */
|
|
169
367
|
parent_id?: string;
|
|
368
|
+
/** Permission overrides to set on the new channel. */
|
|
170
369
|
permission_overwrites?: DiscordPermissionOverwrite[];
|
|
370
|
+
/** The tags of a forum channel (`ChannelType.Forum`). */
|
|
371
|
+
available_tags?: ForumTagInput[];
|
|
171
372
|
}
|
|
172
373
|
/** `null` clears `topic` or detaches the channel from its category. */
|
|
173
374
|
export interface ModifyChannelInput {
|
|
375
|
+
/** A new channel name. */
|
|
174
376
|
name?: string;
|
|
377
|
+
/** A new topic. */
|
|
175
378
|
topic?: string | null;
|
|
379
|
+
/** Id of the category to move the channel into. */
|
|
176
380
|
parent_id?: string | null;
|
|
381
|
+
/** The full list of permission overrides, replacing the existing ones. */
|
|
177
382
|
permission_overwrites?: DiscordPermissionOverwrite[];
|
|
383
|
+
/** The full list of a forum channel's tags, replacing the existing ones; give a tag's `id` to keep it. */
|
|
384
|
+
available_tags?: ForumTagInput[];
|
|
178
385
|
}
|
|
179
386
|
/** A member of a server. Only what provisioning needs: who they are and which roles they hold. */
|
|
180
387
|
export interface DiscordGuildMember {
|
|
388
|
+
/** The member's account; Discord leaves it out in some message contexts. */
|
|
181
389
|
user?: {
|
|
390
|
+
/** The user id. */
|
|
182
391
|
id: string;
|
|
392
|
+
/** The account's username. */
|
|
183
393
|
username?: string;
|
|
184
394
|
};
|
|
185
395
|
/** Ids of the roles the member holds. */
|
|
186
396
|
roles: string[];
|
|
397
|
+
/** The member's nickname in the server, or `null` when none is set. */
|
|
187
398
|
nick?: string | null;
|
|
188
399
|
}
|
|
400
|
+
/** A role in a server, as Discord returns it. */
|
|
189
401
|
export interface DiscordRole {
|
|
402
|
+
/** The role id. */
|
|
190
403
|
id: string;
|
|
404
|
+
/** The role name. */
|
|
191
405
|
name: string;
|
|
406
|
+
/** The role colour as an integer RGB value; `0` means no colour. */
|
|
192
407
|
color: number;
|
|
408
|
+
/** Whether anyone can @mention the role. */
|
|
193
409
|
mentionable: boolean;
|
|
410
|
+
/** Whether members with the role are listed separately in the member list. */
|
|
194
411
|
hoist?: boolean;
|
|
195
412
|
/** Bitfield of permissions, as a string. */
|
|
196
413
|
permissions?: string;
|
|
414
|
+
/** Whether an integration (such as a bot) manages the role. */
|
|
197
415
|
managed?: boolean;
|
|
416
|
+
/** The role's position in the role hierarchy. */
|
|
198
417
|
position?: number;
|
|
199
418
|
}
|
|
419
|
+
/** Role fields `PATCH /guilds/{id}/roles/{id}` can change; a field left out is left alone. */
|
|
200
420
|
export interface ModifyRoleInput {
|
|
421
|
+
/** A new role name. */
|
|
201
422
|
name?: string;
|
|
423
|
+
/** A new colour as an integer RGB value. */
|
|
202
424
|
color?: number;
|
|
425
|
+
/** Whether to list the role's members separately. */
|
|
203
426
|
hoist?: boolean;
|
|
427
|
+
/** Whether anyone can @mention the role. */
|
|
204
428
|
mentionable?: boolean;
|
|
205
429
|
/** Bitfield of permissions, as a string. */
|
|
206
430
|
permissions?: string;
|
|
207
431
|
}
|
|
432
|
+
/** What `POST /guilds/{id}/roles` takes. */
|
|
208
433
|
export interface CreateRoleInput {
|
|
434
|
+
/** The role name. */
|
|
209
435
|
name: string;
|
|
436
|
+
/** The colour as an integer RGB value. */
|
|
210
437
|
color?: number;
|
|
438
|
+
/** Whether anyone can @mention the role. */
|
|
211
439
|
mentionable?: boolean;
|
|
440
|
+
/** Whether to list the role's members separately. */
|
|
212
441
|
hoist?: boolean;
|
|
213
442
|
/** Bitfield of permissions, as a string. */
|
|
214
443
|
permissions?: string;
|
|
215
444
|
}
|
|
445
|
+
/** A webhook attached to a channel, as the bot API returns it. */
|
|
216
446
|
export interface DiscordChannelWebhook {
|
|
447
|
+
/** The webhook id. */
|
|
217
448
|
id: string;
|
|
449
|
+
/** The webhook name, or `null` when unset. */
|
|
218
450
|
name: string | null;
|
|
219
451
|
/** The avatar hash, or `null` for the default one. */
|
|
220
452
|
avatar?: string | null;
|
|
453
|
+
/** Id of the channel the webhook posts to. */
|
|
221
454
|
channel_id: string;
|
|
222
455
|
/** Present only on webhooks this application created; Discord omits it otherwise. */
|
|
223
456
|
token?: string;
|
|
224
457
|
/** Present only on webhooks this application created. */
|
|
225
458
|
url?: string;
|
|
226
459
|
}
|
|
460
|
+
/** What `POST /channels/{id}/messages` takes. */
|
|
227
461
|
export interface CreateMessageInput {
|
|
462
|
+
/** The message text. */
|
|
228
463
|
content: string;
|
|
229
464
|
/** With `enforce_nonce`, Discord drops a repeat of the same nonce, so a retry after a lost response cannot post twice. */
|
|
230
465
|
nonce?: string | number;
|
|
466
|
+
/** Turns on the nonce de-duplication for `nonce`. */
|
|
231
467
|
enforce_nonce?: boolean;
|
|
468
|
+
/** Message flags; see `MessageFlag`. */
|
|
469
|
+
flags?: number;
|
|
232
470
|
/** Defaults to no mentions, so a pasted `@everyone` cannot ping anyone. */
|
|
233
471
|
allowed_mentions?: {
|
|
472
|
+
/** Which mention types Discord may resolve into pings. */
|
|
234
473
|
parse?: Array<"roles" | "users" | "everyone">;
|
|
474
|
+
/** Ids of the roles that may be pinged. */
|
|
235
475
|
roles?: string[];
|
|
476
|
+
/** Ids of the users that may be pinged. */
|
|
236
477
|
users?: string[];
|
|
237
478
|
};
|
|
238
479
|
}
|
|
480
|
+
/** A message that was posted, as Discord returns it. */
|
|
239
481
|
export interface DiscordMessage {
|
|
482
|
+
/** The message id. */
|
|
240
483
|
id: string;
|
|
484
|
+
/** Id of the channel the message is in. */
|
|
241
485
|
channel_id: string;
|
|
486
|
+
/** The message text. */
|
|
242
487
|
content: string;
|
|
243
488
|
}
|
|
244
489
|
/** How the bot is added to a server or an account. */
|
|
@@ -253,17 +498,26 @@ export interface DiscordInstallParams {
|
|
|
253
498
|
* that Discord has not verified; once verified, the plain ones take over and the toggle is Discord's to change.
|
|
254
499
|
*/
|
|
255
500
|
export declare const ApplicationFlag: {
|
|
501
|
+
/** Application may receive presence updates (verified apps). */
|
|
256
502
|
readonly GatewayPresence: number;
|
|
503
|
+
/** The privileged presence intent toggle for an unverified app. */
|
|
257
504
|
readonly GatewayPresenceLimited: number;
|
|
505
|
+
/** Application may receive server-member events and the member list (verified apps). */
|
|
258
506
|
readonly GatewayGuildMembers: number;
|
|
507
|
+
/** The privileged server-members intent toggle for an unverified app. */
|
|
259
508
|
readonly GatewayGuildMembersLimited: number;
|
|
509
|
+
/** Application may read message content (verified apps). */
|
|
260
510
|
readonly GatewayMessageContent: number;
|
|
511
|
+
/** The privileged message-content intent toggle for an unverified app. */
|
|
261
512
|
readonly GatewayMessageContentLimited: number;
|
|
262
513
|
};
|
|
263
514
|
/** The bot's own application, as `GET /applications/@me` returns it. Fields Discord leaves out are absent or null. */
|
|
264
515
|
export interface DiscordApplication {
|
|
516
|
+
/** The application id. */
|
|
265
517
|
id: string;
|
|
518
|
+
/** The application name. */
|
|
266
519
|
name: string;
|
|
520
|
+
/** The description shown on the application's page. */
|
|
267
521
|
description?: string | null;
|
|
268
522
|
/** Up to five short labels shown on the application's page. */
|
|
269
523
|
tags?: string[];
|
|
@@ -271,13 +525,19 @@ export interface DiscordApplication {
|
|
|
271
525
|
install_params?: DiscordInstallParams;
|
|
272
526
|
/** Used instead of the default install link when set. */
|
|
273
527
|
custom_install_url?: string | null;
|
|
528
|
+
/** URL Discord uses for linked-role verification. */
|
|
274
529
|
role_connections_verification_url?: string | null;
|
|
530
|
+
/** URL of the application's terms of service. */
|
|
275
531
|
terms_of_service_url?: string | null;
|
|
532
|
+
/** URL of the application's privacy policy. */
|
|
276
533
|
privacy_policy_url?: string | null;
|
|
534
|
+
/** URL Discord sends interaction events to. */
|
|
277
535
|
interactions_endpoint_url?: string | null;
|
|
278
536
|
/** Whether anyone can add the bot (`true`) or only its owner. */
|
|
279
537
|
bot_public?: boolean;
|
|
538
|
+
/** Whether the bot is only added after the full OAuth2 code grant. */
|
|
280
539
|
bot_require_code_grant?: boolean;
|
|
540
|
+
/** The application flags bitfield; see `ApplicationFlag`. */
|
|
281
541
|
flags?: number;
|
|
282
542
|
/**
|
|
283
543
|
* The OAuth2 redirect URIs registered on the application. Read-only here: Discord accepts a write to this
|
|
@@ -287,13 +547,21 @@ export interface DiscordApplication {
|
|
|
287
547
|
}
|
|
288
548
|
/** What `PATCH /applications/@me` takes; a field left out is left alone, and `null` clears the ones that can be cleared. */
|
|
289
549
|
export interface ModifyApplicationInput {
|
|
550
|
+
/** A new description. */
|
|
290
551
|
description?: string;
|
|
552
|
+
/** The new tags (at most five). */
|
|
291
553
|
tags?: string[];
|
|
554
|
+
/** The new default install link scopes and permissions. */
|
|
292
555
|
install_params?: DiscordInstallParams;
|
|
556
|
+
/** A custom install URL, or `null` to use the default link. */
|
|
293
557
|
custom_install_url?: string | null;
|
|
558
|
+
/** The linked-role verification URL, or `null` to clear it. */
|
|
294
559
|
role_connections_verification_url?: string | null;
|
|
560
|
+
/** The terms of service URL, or `null` to clear it. */
|
|
295
561
|
terms_of_service_url?: string | null;
|
|
562
|
+
/** The privacy policy URL, or `null` to clear it. */
|
|
296
563
|
privacy_policy_url?: string | null;
|
|
564
|
+
/** The interactions endpoint URL, or `null` to clear it. */
|
|
297
565
|
interactions_endpoint_url?: string | null;
|
|
298
566
|
/**
|
|
299
567
|
* The whole flags value. Discord keeps only the bits an app may change (the `*Limited` privileged-intent
|
|
@@ -301,22 +569,29 @@ export interface ModifyApplicationInput {
|
|
|
301
569
|
*/
|
|
302
570
|
flags?: number;
|
|
303
571
|
}
|
|
572
|
+
/** What `PATCH /webhooks/{id}` takes; a field left out is left alone. */
|
|
304
573
|
export interface ModifyWebhookInput {
|
|
574
|
+
/** A new webhook name. */
|
|
305
575
|
name?: string;
|
|
306
576
|
/** A data URI (`data:image/png;base64,...`); `null` clears it. */
|
|
307
577
|
avatar?: string | null;
|
|
308
578
|
}
|
|
309
579
|
/** What `POST /guilds` takes. Only a bot in fewer than ten servers may create one, and it becomes the owner. */
|
|
310
580
|
export interface CreateGuildInput {
|
|
581
|
+
/** The server name. */
|
|
311
582
|
name: string;
|
|
312
583
|
/** A data URI (`data:image/png;base64,...`). */
|
|
313
584
|
icon?: string;
|
|
585
|
+
/** Verification level, using the same values as `DiscordGuild.verification_level`. */
|
|
314
586
|
verification_level?: number;
|
|
587
|
+
/** Default notification setting, using the same values as `DiscordGuild.default_message_notifications`. */
|
|
315
588
|
default_message_notifications?: number;
|
|
589
|
+
/** Content filter level, using the same values as `DiscordGuild.explicit_content_filter`. */
|
|
316
590
|
explicit_content_filter?: number;
|
|
317
591
|
}
|
|
318
592
|
/** Page options for `guilds.members`; Discord caps `limit` at 1000. */
|
|
319
593
|
export interface ListMembersInput {
|
|
594
|
+
/** How many members to return; Discord caps it at 1000. */
|
|
320
595
|
limit?: number;
|
|
321
596
|
/** Return members after this user id. */
|
|
322
597
|
after?: string;
|
|
@@ -325,29 +600,43 @@ export interface DiscordEmoji {
|
|
|
325
600
|
id: string | null;
|
|
326
601
|
name: string | null;
|
|
327
602
|
animated?: boolean;
|
|
603
|
+
/** Whether the emoji can be used (it may be unavailable when the server lost a boost level). */
|
|
328
604
|
available?: boolean;
|
|
329
605
|
}
|
|
606
|
+
/** What `POST /channels/{id}/invites` takes. */
|
|
330
607
|
export interface CreateInviteInput {
|
|
331
608
|
/** Seconds until it expires; `0` never. Discord's default is 86400. */
|
|
332
609
|
max_age?: number;
|
|
333
610
|
/** Uses before it is revoked; `0` unlimited. */
|
|
334
611
|
max_uses?: number;
|
|
612
|
+
/** Whether the invite grants temporary membership. */
|
|
335
613
|
temporary?: boolean;
|
|
614
|
+
/** Whether to always create a new invite instead of reusing a similar one. */
|
|
336
615
|
unique?: boolean;
|
|
337
616
|
}
|
|
617
|
+
/** A server invite, as Discord returns it. */
|
|
338
618
|
export interface DiscordInvite {
|
|
619
|
+
/** The invite code, the part after `discord.gg/`. */
|
|
339
620
|
code: string;
|
|
621
|
+
/** Id of the channel the invite leads to. */
|
|
340
622
|
channel_id?: string;
|
|
623
|
+
/** How many times the invite has been used. */
|
|
341
624
|
uses?: number;
|
|
342
625
|
}
|
|
343
626
|
/** A message listed back from a channel, with who wrote it. */
|
|
344
627
|
export interface DiscordChannelMessage extends DiscordMessage {
|
|
628
|
+
/** Who wrote the message; absent when Discord omits it. */
|
|
345
629
|
author?: {
|
|
630
|
+
/** The author's user id. */
|
|
346
631
|
id: string;
|
|
632
|
+
/** The author's username. */
|
|
347
633
|
username?: string;
|
|
634
|
+
/** Whether the author is a bot. */
|
|
348
635
|
bot?: boolean;
|
|
349
636
|
};
|
|
637
|
+
/** Id of the webhook that posted the message, when one did. */
|
|
350
638
|
webhook_id?: string;
|
|
639
|
+
/** Whether the message is pinned in its channel. */
|
|
351
640
|
pinned?: boolean;
|
|
352
641
|
}
|
|
353
642
|
/**
|
|
@@ -416,6 +705,10 @@ export declare function createDiscordBotClient(opts: DiscordBotClientOptions): {
|
|
|
416
705
|
webhooks: (channelId: string) => Promise<DiscordChannelWebhook[]>;
|
|
417
706
|
/** `POST /channels/:id/messages` as the bot. Mentions are off unless `allowed_mentions` asks for them. */
|
|
418
707
|
createMessage: (channelId: string, body: CreateMessageInput) => Promise<DiscordMessage>;
|
|
708
|
+
/** `GET /channels/:id/messages/:id` — one message, e.g. the first message of a forum post (its id is the post's). */
|
|
709
|
+
message: (channelId: string, messageId: string) => Promise<DiscordChannelMessage>;
|
|
710
|
+
/** `PATCH /channels/:id/messages/:id` — a message this bot posted. Mentions are off unless `allowed_mentions` asks for them. */
|
|
711
|
+
editMessage: (channelId: string, messageId: string, body: EditMessageInput) => Promise<DiscordMessage>;
|
|
419
712
|
/** `POST /channels/:id/invites` — a join link for the server, e.g. to hand over a newly created one. */
|
|
420
713
|
createInvite: (channelId: string, body?: CreateInviteInput) => Promise<DiscordInvite>;
|
|
421
714
|
/** `GET /channels/:id/messages` — the newest messages first, to read a post back. */
|
|
@@ -427,6 +720,24 @@ export declare function createDiscordBotClient(opts: DiscordBotClientOptions): {
|
|
|
427
720
|
name: string;
|
|
428
721
|
}) => Promise<DiscordChannelWebhook>;
|
|
429
722
|
};
|
|
723
|
+
threads: {
|
|
724
|
+
/**
|
|
725
|
+
* `POST /channels/:id/threads` in a forum channel — a new post with its first message. Not idempotent: look
|
|
726
|
+
* the post up (`inChannel`) before retrying. Mentions in the first message are off unless asked for.
|
|
727
|
+
*/
|
|
728
|
+
createForumPost: (channelId: string, body: CreateForumPostInput) => Promise<DiscordForumPost>;
|
|
729
|
+
/** `PATCH /channels/:id` on a thread — its title, tags, archived or locked state. Writing to an archived post unarchives it. */
|
|
730
|
+
modify: (threadId: string, body: ModifyThreadInput) => Promise<DiscordThread>;
|
|
731
|
+
/** `GET /guilds/:id/threads/active` — every active thread in the server, across channels. */
|
|
732
|
+
active: (guildId: string) => Promise<DiscordThread[]>;
|
|
733
|
+
/** `GET /channels/:id/threads/archived/public` — one page of a channel's archived threads, newest archived first. */
|
|
734
|
+
archived: (channelId: string, opts?: ListArchivedThreadsInput) => Promise<DiscordArchivedThreads>;
|
|
735
|
+
/**
|
|
736
|
+
* Every post in a forum channel, active and archived: Discord hides a post that has been quiet for a while, so
|
|
737
|
+
* a lookup that read only the active ones would miss it and make it again.
|
|
738
|
+
*/
|
|
739
|
+
inChannel: (guildId: string, channelId: string) => Promise<DiscordThread[]>;
|
|
740
|
+
};
|
|
430
741
|
application: {
|
|
431
742
|
/** `GET /applications/@me` — the bot's own application: description, tags, install settings, URLs. */
|
|
432
743
|
get: () => Promise<DiscordApplication>;
|
|
@@ -441,6 +752,7 @@ export declare function createDiscordBotClient(opts: DiscordBotClientOptions): {
|
|
|
441
752
|
delete: (webhookId: string) => Promise<void>;
|
|
442
753
|
};
|
|
443
754
|
};
|
|
755
|
+
/** The bot-token client returned by `createDiscordBotClient`, with its resource groups (guilds, channels, roles, webhooks, messages and so on). */
|
|
444
756
|
export type DiscordBotClient = ReturnType<typeof createDiscordBotClient>;
|
|
445
757
|
/**
|
|
446
758
|
* Discord permission bits, by the names the Discord docs use. Permissions travel as
|
|
@@ -449,62 +761,114 @@ export type DiscordBotClient = ReturnType<typeof createDiscordBotClient>;
|
|
|
449
761
|
* `permissions` cannot set them by name.
|
|
450
762
|
*/
|
|
451
763
|
export declare const Permission: {
|
|
764
|
+
/** Create invites to the server. */
|
|
452
765
|
readonly CreateInstantInvite: bigint;
|
|
766
|
+
/** Kick members. */
|
|
453
767
|
readonly KickMembers: bigint;
|
|
768
|
+
/** Ban members. */
|
|
454
769
|
readonly BanMembers: bigint;
|
|
770
|
+
/** Administrator: all permissions, and bypasses channel overrides. */
|
|
455
771
|
readonly Administrator: bigint;
|
|
772
|
+
/** Create, edit and delete channels. */
|
|
456
773
|
readonly ManageChannels: bigint;
|
|
774
|
+
/** Change server settings. */
|
|
457
775
|
readonly ManageGuild: bigint;
|
|
776
|
+
/** Add new reactions to messages. */
|
|
458
777
|
readonly AddReactions: bigint;
|
|
778
|
+
/** View the audit log. */
|
|
459
779
|
readonly ViewAuditLog: bigint;
|
|
780
|
+
/** Use priority speaker in voice channels. */
|
|
460
781
|
readonly PrioritySpeaker: bigint;
|
|
782
|
+
/** Go live (stream) in voice channels. */
|
|
461
783
|
readonly Stream: bigint;
|
|
784
|
+
/** View channels (and read their messages). */
|
|
462
785
|
readonly ViewChannel: bigint;
|
|
786
|
+
/** Send messages in text channels. */
|
|
463
787
|
readonly SendMessages: bigint;
|
|
788
|
+
/** Send text-to-speech messages. */
|
|
464
789
|
readonly SendTtsMessages: bigint;
|
|
790
|
+
/** Delete other members' messages and pin messages. */
|
|
465
791
|
readonly ManageMessages: bigint;
|
|
792
|
+
/** Have links in messages embed. */
|
|
466
793
|
readonly EmbedLinks: bigint;
|
|
794
|
+
/** Upload files and media. */
|
|
467
795
|
readonly AttachFiles: bigint;
|
|
796
|
+
/** Read message history. */
|
|
468
797
|
readonly ReadMessageHistory: bigint;
|
|
798
|
+
/** Mention @everyone, @here and all roles. */
|
|
469
799
|
readonly MentionEveryone: bigint;
|
|
800
|
+
/** Use emojis from other servers. */
|
|
470
801
|
readonly UseExternalEmojis: bigint;
|
|
802
|
+
/** View server insights. */
|
|
471
803
|
readonly ViewGuildInsights: bigint;
|
|
804
|
+
/** Join voice channels. */
|
|
472
805
|
readonly Connect: bigint;
|
|
806
|
+
/** Speak in voice channels. */
|
|
473
807
|
readonly Speak: bigint;
|
|
808
|
+
/** Mute other members in voice channels. */
|
|
474
809
|
readonly MuteMembers: bigint;
|
|
810
|
+
/** Deafen other members in voice channels. */
|
|
475
811
|
readonly DeafenMembers: bigint;
|
|
812
|
+
/** Move members between voice channels. */
|
|
476
813
|
readonly MoveMembers: bigint;
|
|
814
|
+
/** Use voice activity detection instead of push-to-talk. */
|
|
477
815
|
readonly UseVoiceActivity: bigint;
|
|
816
|
+
/** Change one's own nickname. */
|
|
478
817
|
readonly ChangeNickname: bigint;
|
|
818
|
+
/** Change other members' nicknames. */
|
|
479
819
|
readonly ManageNicknames: bigint;
|
|
820
|
+
/** Create, edit and delete roles lower than the member's own. */
|
|
480
821
|
readonly ManageRoles: bigint;
|
|
822
|
+
/** Create, edit and delete webhooks. */
|
|
481
823
|
readonly ManageWebhooks: bigint;
|
|
824
|
+
/** Edit and delete emojis, stickers and soundboard sounds. */
|
|
482
825
|
readonly ManageGuildExpressions: bigint;
|
|
826
|
+
/** Use application commands (slash commands). */
|
|
483
827
|
readonly UseApplicationCommands: bigint;
|
|
828
|
+
/** Request to speak in stage channels. */
|
|
484
829
|
readonly RequestToSpeak: bigint;
|
|
830
|
+
/** Edit and delete scheduled events. */
|
|
485
831
|
readonly ManageEvents: bigint;
|
|
832
|
+
/** Manage and delete threads. */
|
|
486
833
|
readonly ManageThreads: bigint;
|
|
834
|
+
/** Create public threads. */
|
|
487
835
|
readonly CreatePublicThreads: bigint;
|
|
836
|
+
/** Create private threads. */
|
|
488
837
|
readonly CreatePrivateThreads: bigint;
|
|
838
|
+
/** Use stickers from other servers. */
|
|
489
839
|
readonly UseExternalStickers: bigint;
|
|
840
|
+
/** Send messages in threads. */
|
|
490
841
|
readonly SendMessagesInThreads: bigint;
|
|
842
|
+
/** Start activities in voice channels. */
|
|
491
843
|
readonly UseEmbeddedActivities: bigint;
|
|
844
|
+
/** Time out members. */
|
|
492
845
|
readonly ModerateMembers: bigint;
|
|
846
|
+
/** View creator monetization analytics. */
|
|
493
847
|
readonly ViewCreatorMonetizationAnalytics: bigint;
|
|
848
|
+
/** Use soundboard sounds. */
|
|
494
849
|
readonly UseSoundboard: bigint;
|
|
850
|
+
/** Create emojis, stickers and soundboard sounds. */
|
|
495
851
|
readonly CreateGuildExpressions: bigint;
|
|
852
|
+
/** Create scheduled events. */
|
|
496
853
|
readonly CreateEvents: bigint;
|
|
854
|
+
/** Use soundboard sounds from other servers. */
|
|
497
855
|
readonly UseExternalSounds: bigint;
|
|
856
|
+
/** Send voice messages. */
|
|
498
857
|
readonly SendVoiceMessages: bigint;
|
|
858
|
+
/** Send polls. */
|
|
499
859
|
readonly SendPolls: bigint;
|
|
860
|
+
/** Use apps that are not installed in the server. */
|
|
500
861
|
readonly UseExternalApps: bigint;
|
|
862
|
+
/** Pin and unpin messages. */
|
|
501
863
|
readonly PinMessages: bigint;
|
|
502
864
|
};
|
|
865
|
+
/** The name of one entry in `Permission`. */
|
|
503
866
|
export type PermissionName = keyof typeof Permission;
|
|
504
867
|
/** The decimal-string bitfield Discord wants for the named permissions (`"0"` for none). */
|
|
505
868
|
export declare function permissions(names: readonly PermissionName[]): string;
|
|
506
869
|
/** The permission names set in a bitfield, in declaration order (unknown bits are ignored). */
|
|
507
870
|
export declare function permissionNames(bitfield: string): PermissionName[];
|
|
871
|
+
/** Options for `createDiscordOAuthClient`. */
|
|
508
872
|
export interface DiscordOAuthClientOptions {
|
|
509
873
|
/** The application's client id (the same as its application id). Not a secret. */
|
|
510
874
|
clientId: string;
|
|
@@ -523,11 +887,15 @@ export interface DiscordOAuthClientOptions {
|
|
|
523
887
|
}
|
|
524
888
|
/** What a member's token may do: `identify` reads who they are, `connections` reads their linked accounts. */
|
|
525
889
|
export type DiscordOAuthScope = "identify" | "connections";
|
|
890
|
+
/** The token Discord returns from the OAuth2 token endpoint. */
|
|
526
891
|
export interface DiscordOAuthToken {
|
|
892
|
+
/** The access token to send as a bearer. */
|
|
527
893
|
access_token: string;
|
|
894
|
+
/** The token type, `Bearer`. */
|
|
528
895
|
token_type: string;
|
|
529
896
|
/** Seconds until `access_token` stops working. */
|
|
530
897
|
expires_in: number;
|
|
898
|
+
/** The token that can be exchanged for a new access token. */
|
|
531
899
|
refresh_token?: string;
|
|
532
900
|
/** The scopes granted, space separated. */
|
|
533
901
|
scope: string;
|
|
@@ -542,12 +910,16 @@ export interface DiscordConnection {
|
|
|
542
910
|
type: string;
|
|
543
911
|
/** Whether Discord confirmed the member owns the account. */
|
|
544
912
|
verified: boolean;
|
|
913
|
+
/** Discord's visibility code: 0 only the member, 1 everyone. */
|
|
545
914
|
visibility?: number;
|
|
546
915
|
}
|
|
547
916
|
/** The member who signed in, as `GET /users/@me` returns it with their token. */
|
|
548
917
|
export interface DiscordOAuthUser {
|
|
918
|
+
/** The Discord user id. */
|
|
549
919
|
id: string;
|
|
920
|
+
/** The account's username. */
|
|
550
921
|
username: string;
|
|
922
|
+
/** The display name, or `null` when the member has none. */
|
|
551
923
|
global_name?: string | null;
|
|
552
924
|
}
|
|
553
925
|
/**
|
|
@@ -580,6 +952,7 @@ export declare function createDiscordOAuthClient(opts: DiscordOAuthClientOptions
|
|
|
580
952
|
/** `GET /users/@me/connections` as the member (needs `connections`). */
|
|
581
953
|
connections: (accessToken: string) => Promise<DiscordConnection[]>;
|
|
582
954
|
};
|
|
955
|
+
/** The member-OAuth client returned by `createDiscordOAuthClient`. */
|
|
583
956
|
export type DiscordOAuthClient = ReturnType<typeof createDiscordOAuthClient>;
|
|
584
957
|
/**
|
|
585
958
|
* The verified connection of one service, or `undefined`. Unverified ones are ignored: anyone can type a
|
|
@@ -603,6 +976,7 @@ export declare function signOAuthState(secret: string, opts?: {
|
|
|
603
976
|
export declare function verifyOAuthState(secret: string, state: string, opts?: {
|
|
604
977
|
now?: number;
|
|
605
978
|
}): boolean;
|
|
979
|
+
/** Builds the webhook client: a `webhooks` group that reads, posts to and deletes messages from a webhook by its id and token. */
|
|
606
980
|
export declare function createDiscordClient(opts?: DiscordClientOptions): {
|
|
607
981
|
webhooks: {
|
|
608
982
|
get: (id: string, token: string) => Promise<DiscordWebhookInfo>;
|
|
@@ -613,5 +987,6 @@ export declare function createDiscordClient(opts?: DiscordClientOptions): {
|
|
|
613
987
|
deleteMessage: (id: string, token: string, messageId: string) => Promise<void>;
|
|
614
988
|
};
|
|
615
989
|
};
|
|
990
|
+
/** The client `createDiscordClient` returns. */
|
|
616
991
|
export type DiscordClient = ReturnType<typeof createDiscordClient>;
|
|
617
992
|
export type { DiscordClientOptions, DiscordWebhookInfo };
|
package/dist/index.mjs
CHANGED
|
@@ -81,6 +81,8 @@ const DEFAULT_MAX_RETRIES = 3;
|
|
|
81
81
|
const MAX_RETRY_WAIT_MS = 1e4;
|
|
82
82
|
/** A guard on `membersWithRole`, so a runaway cursor cannot loop forever. */
|
|
83
83
|
const MAX_MEMBER_PAGES = 50;
|
|
84
|
+
/** A guard on `threads.inChannel`, so a runaway `before` cursor cannot loop forever. */
|
|
85
|
+
const MAX_THREAD_PAGES = 50;
|
|
84
86
|
/** Discord ids are snowflakes; anything else would be spliced into a URL path. */
|
|
85
87
|
function id(value) {
|
|
86
88
|
if (!/^\d{1,20}$/.test(value)) throw new Error(`invalid Discord id: ${JSON.stringify(value)}`);
|
|
@@ -93,6 +95,22 @@ function bodyIds(...values) {
|
|
|
93
95
|
for (const one of typeof value === "string" ? [value] : value) id(one);
|
|
94
96
|
}
|
|
95
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* A message body with its mention ids checked and mentions switched off unless asked for. The default is applied
|
|
100
|
+
* after the spread, so an explicit `allowed_mentions: undefined` still means "no mentions".
|
|
101
|
+
*/
|
|
102
|
+
function withMentionsOff(body) {
|
|
103
|
+
bodyIds(body.allowed_mentions?.roles, body.allowed_mentions?.users);
|
|
104
|
+
return {
|
|
105
|
+
...body,
|
|
106
|
+
allowed_mentions: body.allowed_mentions ?? { parse: [] }
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/** An ISO 8601 timestamp that travels in a query, so a malformed one fails here and not at Discord. */
|
|
110
|
+
function timestamp(value) {
|
|
111
|
+
if (Number.isNaN(Date.parse(value))) throw new Error(`invalid timestamp: ${JSON.stringify(value)}`);
|
|
112
|
+
return value;
|
|
113
|
+
}
|
|
96
114
|
/** How long Discord asks us to wait after a 429, in ms (header first, then the JSON body). */
|
|
97
115
|
async function retryDelayMs(res) {
|
|
98
116
|
const header = Number(res.headers.get("retry-after"));
|
|
@@ -279,16 +297,17 @@ function createDiscordBotClient(opts) {
|
|
|
279
297
|
}),
|
|
280
298
|
webhooks: async (channelId) => (await rest.request(`/channels/${id(channelId)}/webhooks`)).map(withUrl),
|
|
281
299
|
/** `POST /channels/:id/messages` as the bot. Mentions are off unless `allowed_mentions` asks for them. */
|
|
282
|
-
createMessage: (channelId, body) => {
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
300
|
+
createMessage: (channelId, body) => rest.request(`/channels/${id(channelId)}/messages`, {
|
|
301
|
+
method: "POST",
|
|
302
|
+
body: withMentionsOff(body)
|
|
303
|
+
}),
|
|
304
|
+
/** `GET /channels/:id/messages/:id` — one message, e.g. the first message of a forum post (its id is the post's). */
|
|
305
|
+
message: (channelId, messageId) => rest.request(`/channels/${id(channelId)}/messages/${id(messageId)}`),
|
|
306
|
+
/** `PATCH /channels/:id/messages/:id` — a message this bot posted. Mentions are off unless `allowed_mentions` asks for them. */
|
|
307
|
+
editMessage: (channelId, messageId, body) => rest.request(`/channels/${id(channelId)}/messages/${id(messageId)}`, {
|
|
308
|
+
method: "PATCH",
|
|
309
|
+
body: withMentionsOff(body)
|
|
310
|
+
}),
|
|
292
311
|
/** `POST /channels/:id/invites` — a join link for the server, e.g. to hand over a newly created one. */
|
|
293
312
|
createInvite: (channelId, body = {}) => rest.request(`/channels/${id(channelId)}/invites`, {
|
|
294
313
|
method: "POST",
|
|
@@ -310,6 +329,59 @@ function createDiscordBotClient(opts) {
|
|
|
310
329
|
body
|
|
311
330
|
}))
|
|
312
331
|
},
|
|
332
|
+
threads: {
|
|
333
|
+
/**
|
|
334
|
+
* `POST /channels/:id/threads` in a forum channel — a new post with its first message. Not idempotent: look
|
|
335
|
+
* the post up (`inChannel`) before retrying. Mentions in the first message are off unless asked for.
|
|
336
|
+
*/
|
|
337
|
+
createForumPost: (channelId, body) => {
|
|
338
|
+
bodyIds(body.applied_tags);
|
|
339
|
+
return rest.request(`/channels/${id(channelId)}/threads`, {
|
|
340
|
+
method: "POST",
|
|
341
|
+
body: {
|
|
342
|
+
...body,
|
|
343
|
+
message: withMentionsOff(body.message)
|
|
344
|
+
}
|
|
345
|
+
});
|
|
346
|
+
},
|
|
347
|
+
/** `PATCH /channels/:id` on a thread — its title, tags, archived or locked state. Writing to an archived post unarchives it. */
|
|
348
|
+
modify: (threadId, body) => {
|
|
349
|
+
bodyIds(body.applied_tags);
|
|
350
|
+
return rest.request(`/channels/${id(threadId)}`, {
|
|
351
|
+
method: "PATCH",
|
|
352
|
+
body
|
|
353
|
+
});
|
|
354
|
+
},
|
|
355
|
+
/** `GET /guilds/:id/threads/active` — every active thread in the server, across channels. */
|
|
356
|
+
active: async (guildId) => (await rest.request(`/guilds/${id(guildId)}/threads/active`)).threads,
|
|
357
|
+
/** `GET /channels/:id/threads/archived/public` — one page of a channel's archived threads, newest archived first. */
|
|
358
|
+
archived: (channelId, opts = {}) => {
|
|
359
|
+
const query = { limit: String(Math.min(Math.max(opts.limit ?? 100, 1), 100)) };
|
|
360
|
+
if (opts.before !== void 0) query.before = timestamp(opts.before);
|
|
361
|
+
return rest.request(`/channels/${id(channelId)}/threads/archived/public`, { query });
|
|
362
|
+
},
|
|
363
|
+
/**
|
|
364
|
+
* Every post in a forum channel, active and archived: Discord hides a post that has been quiet for a while, so
|
|
365
|
+
* a lookup that read only the active ones would miss it and make it again.
|
|
366
|
+
*/
|
|
367
|
+
inChannel: async (guildId, channelId) => {
|
|
368
|
+
const parent = id(channelId);
|
|
369
|
+
const { threads } = await rest.request(`/guilds/${id(guildId)}/threads/active`);
|
|
370
|
+
const found = threads.filter((t) => t.parent_id === parent);
|
|
371
|
+
let before;
|
|
372
|
+
for (let page = 0; page < MAX_THREAD_PAGES; page++) {
|
|
373
|
+
const batch = await rest.request(`/channels/${parent}/threads/archived/public`, { query: {
|
|
374
|
+
limit: "100",
|
|
375
|
+
...before === void 0 ? {} : { before: timestamp(before) }
|
|
376
|
+
} });
|
|
377
|
+
found.push(...batch.threads);
|
|
378
|
+
const last = batch.threads[batch.threads.length - 1];
|
|
379
|
+
if (!batch.has_more || last === void 0) return found;
|
|
380
|
+
before = last.thread_metadata.archive_timestamp;
|
|
381
|
+
}
|
|
382
|
+
throw new Error(`more than 5000 archived threads; refusing to read them all`);
|
|
383
|
+
}
|
|
384
|
+
},
|
|
313
385
|
application: {
|
|
314
386
|
/** `GET /applications/@me` — the bot's own application: description, tags, install settings, URLs. */
|
|
315
387
|
get: () => rest.request("/applications/@me"),
|
|
@@ -344,21 +416,35 @@ function createDiscordBotClient(opts) {
|
|
|
344
416
|
// src/bot/bot.type.ts
|
|
345
417
|
/** Discord channel `type` values this client creates or reads. */
|
|
346
418
|
const ChannelType = {
|
|
419
|
+
/** A text channel. */
|
|
347
420
|
Text: 0,
|
|
421
|
+
/** A category that groups channels. */
|
|
348
422
|
Category: 4,
|
|
423
|
+
/** An announcement channel. */
|
|
349
424
|
Announcement: 5,
|
|
425
|
+
/** A forum channel. */
|
|
350
426
|
Forum: 15
|
|
351
427
|
};
|
|
428
|
+
/** Bits of a message's `flags` that a bot may set when it posts. */
|
|
429
|
+
const MessageFlag = {
|
|
430
|
+
/** Posts without notifying anyone, as a backfill of many messages should. */
|
|
431
|
+
SuppressNotifications: 4096 };
|
|
352
432
|
/**
|
|
353
433
|
* Bits of the application's `flags`. The `*Limited` ones are the portal's privileged-intent toggles for an app
|
|
354
434
|
* that Discord has not verified; once verified, the plain ones take over and the toggle is Discord's to change.
|
|
355
435
|
*/
|
|
356
436
|
const ApplicationFlag = {
|
|
437
|
+
/** Application may receive presence updates (verified apps). */
|
|
357
438
|
GatewayPresence: 4096,
|
|
439
|
+
/** The privileged presence intent toggle for an unverified app. */
|
|
358
440
|
GatewayPresenceLimited: 8192,
|
|
441
|
+
/** Application may receive server-member events and the member list (verified apps). */
|
|
359
442
|
GatewayGuildMembers: 16384,
|
|
443
|
+
/** The privileged server-members intent toggle for an unverified app. */
|
|
360
444
|
GatewayGuildMembersLimited: 32768,
|
|
445
|
+
/** Application may read message content (verified apps). */
|
|
361
446
|
GatewayMessageContent: 1 << 18,
|
|
447
|
+
/** The privileged message-content intent toggle for an unverified app. */
|
|
362
448
|
GatewayMessageContentLimited: 1 << 19
|
|
363
449
|
};
|
|
364
450
|
// src/bot/permissions.ts
|
|
@@ -369,55 +455,105 @@ const ApplicationFlag = {
|
|
|
369
455
|
* `permissions` cannot set them by name.
|
|
370
456
|
*/
|
|
371
457
|
const Permission = {
|
|
458
|
+
/** Create invites to the server. */
|
|
372
459
|
CreateInstantInvite: 1n << 0n,
|
|
460
|
+
/** Kick members. */
|
|
373
461
|
KickMembers: 1n << 1n,
|
|
462
|
+
/** Ban members. */
|
|
374
463
|
BanMembers: 1n << 2n,
|
|
464
|
+
/** Administrator: all permissions, and bypasses channel overrides. */
|
|
375
465
|
Administrator: 1n << 3n,
|
|
466
|
+
/** Create, edit and delete channels. */
|
|
376
467
|
ManageChannels: 1n << 4n,
|
|
468
|
+
/** Change server settings. */
|
|
377
469
|
ManageGuild: 1n << 5n,
|
|
470
|
+
/** Add new reactions to messages. */
|
|
378
471
|
AddReactions: 1n << 6n,
|
|
472
|
+
/** View the audit log. */
|
|
379
473
|
ViewAuditLog: 1n << 7n,
|
|
474
|
+
/** Use priority speaker in voice channels. */
|
|
380
475
|
PrioritySpeaker: 1n << 8n,
|
|
476
|
+
/** Go live (stream) in voice channels. */
|
|
381
477
|
Stream: 1n << 9n,
|
|
478
|
+
/** View channels (and read their messages). */
|
|
382
479
|
ViewChannel: 1n << 10n,
|
|
480
|
+
/** Send messages in text channels. */
|
|
383
481
|
SendMessages: 1n << 11n,
|
|
482
|
+
/** Send text-to-speech messages. */
|
|
384
483
|
SendTtsMessages: 1n << 12n,
|
|
484
|
+
/** Delete other members' messages and pin messages. */
|
|
385
485
|
ManageMessages: 1n << 13n,
|
|
486
|
+
/** Have links in messages embed. */
|
|
386
487
|
EmbedLinks: 1n << 14n,
|
|
488
|
+
/** Upload files and media. */
|
|
387
489
|
AttachFiles: 1n << 15n,
|
|
490
|
+
/** Read message history. */
|
|
388
491
|
ReadMessageHistory: 1n << 16n,
|
|
492
|
+
/** Mention @everyone, @here and all roles. */
|
|
389
493
|
MentionEveryone: 1n << 17n,
|
|
494
|
+
/** Use emojis from other servers. */
|
|
390
495
|
UseExternalEmojis: 1n << 18n,
|
|
496
|
+
/** View server insights. */
|
|
391
497
|
ViewGuildInsights: 1n << 19n,
|
|
498
|
+
/** Join voice channels. */
|
|
392
499
|
Connect: 1n << 20n,
|
|
500
|
+
/** Speak in voice channels. */
|
|
393
501
|
Speak: 1n << 21n,
|
|
502
|
+
/** Mute other members in voice channels. */
|
|
394
503
|
MuteMembers: 1n << 22n,
|
|
504
|
+
/** Deafen other members in voice channels. */
|
|
395
505
|
DeafenMembers: 1n << 23n,
|
|
506
|
+
/** Move members between voice channels. */
|
|
396
507
|
MoveMembers: 1n << 24n,
|
|
508
|
+
/** Use voice activity detection instead of push-to-talk. */
|
|
397
509
|
UseVoiceActivity: 1n << 25n,
|
|
510
|
+
/** Change one's own nickname. */
|
|
398
511
|
ChangeNickname: 1n << 26n,
|
|
512
|
+
/** Change other members' nicknames. */
|
|
399
513
|
ManageNicknames: 1n << 27n,
|
|
514
|
+
/** Create, edit and delete roles lower than the member's own. */
|
|
400
515
|
ManageRoles: 1n << 28n,
|
|
516
|
+
/** Create, edit and delete webhooks. */
|
|
401
517
|
ManageWebhooks: 1n << 29n,
|
|
518
|
+
/** Edit and delete emojis, stickers and soundboard sounds. */
|
|
402
519
|
ManageGuildExpressions: 1n << 30n,
|
|
520
|
+
/** Use application commands (slash commands). */
|
|
403
521
|
UseApplicationCommands: 1n << 31n,
|
|
522
|
+
/** Request to speak in stage channels. */
|
|
404
523
|
RequestToSpeak: 1n << 32n,
|
|
524
|
+
/** Edit and delete scheduled events. */
|
|
405
525
|
ManageEvents: 1n << 33n,
|
|
526
|
+
/** Manage and delete threads. */
|
|
406
527
|
ManageThreads: 1n << 34n,
|
|
528
|
+
/** Create public threads. */
|
|
407
529
|
CreatePublicThreads: 1n << 35n,
|
|
530
|
+
/** Create private threads. */
|
|
408
531
|
CreatePrivateThreads: 1n << 36n,
|
|
532
|
+
/** Use stickers from other servers. */
|
|
409
533
|
UseExternalStickers: 1n << 37n,
|
|
534
|
+
/** Send messages in threads. */
|
|
410
535
|
SendMessagesInThreads: 1n << 38n,
|
|
536
|
+
/** Start activities in voice channels. */
|
|
411
537
|
UseEmbeddedActivities: 1n << 39n,
|
|
538
|
+
/** Time out members. */
|
|
412
539
|
ModerateMembers: 1n << 40n,
|
|
540
|
+
/** View creator monetization analytics. */
|
|
413
541
|
ViewCreatorMonetizationAnalytics: 1n << 41n,
|
|
542
|
+
/** Use soundboard sounds. */
|
|
414
543
|
UseSoundboard: 1n << 42n,
|
|
544
|
+
/** Create emojis, stickers and soundboard sounds. */
|
|
415
545
|
CreateGuildExpressions: 1n << 43n,
|
|
546
|
+
/** Create scheduled events. */
|
|
416
547
|
CreateEvents: 1n << 44n,
|
|
548
|
+
/** Use soundboard sounds from other servers. */
|
|
417
549
|
UseExternalSounds: 1n << 45n,
|
|
550
|
+
/** Send voice messages. */
|
|
418
551
|
SendVoiceMessages: 1n << 46n,
|
|
552
|
+
/** Send polls. */
|
|
419
553
|
SendPolls: 1n << 49n,
|
|
554
|
+
/** Use apps that are not installed in the server. */
|
|
420
555
|
UseExternalApps: 1n << 50n,
|
|
556
|
+
/** Pin and unpin messages. */
|
|
421
557
|
PinMessages: 1n << 51n
|
|
422
558
|
};
|
|
423
559
|
/** The decimal-string bitfield Discord wants for the named permissions (`"0"` for none). */
|
|
@@ -561,7 +697,8 @@ function verifyOAuthState(secret, state, opts = {}) {
|
|
|
561
697
|
return Number(expires) >= Math.floor((opts.now ?? Date.now()) / 1e3);
|
|
562
698
|
}
|
|
563
699
|
// src/index.ts
|
|
700
|
+
/** Builds the webhook client: a `webhooks` group that reads, posts to and deletes messages from a webhook by its id and token. */
|
|
564
701
|
function createDiscordClient(opts = {}) {
|
|
565
702
|
return { webhooks: webhooks(opts.baseUrl ?? "https://discord.com/api/v10", opts.fetch ?? globalThis.fetch) };
|
|
566
703
|
}
|
|
567
|
-
export { ApplicationFlag, ChannelType, DEFAULT_STATE_TTL_SECONDS, Permission, createDiscordBotClient, createDiscordClient, createDiscordOAuthClient, findVerifiedConnection, parseWebhookUrl, permissionNames, permissions, signOAuthState, verifyOAuthState };
|
|
704
|
+
export { ApplicationFlag, ChannelType, DEFAULT_STATE_TTL_SECONDS, MessageFlag, Permission, createDiscordBotClient, createDiscordClient, createDiscordOAuthClient, findVerifiedConnection, parseWebhookUrl, permissionNames, permissions, signOAuthState, verifyOAuthState };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theholocron/discord-client",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.58.0-alpha.10",
|
|
4
4
|
"description": "A TypeScript client for the Discord webhooks API",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"discord",
|
|
@@ -32,22 +32,22 @@
|
|
|
32
32
|
"dist"
|
|
33
33
|
],
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@theholocron/http-client": "^1.
|
|
35
|
+
"@theholocron/http-client": "^1.58.0-alpha.10"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@types/node": "^26",
|
|
39
39
|
"@vitest/coverage-v8": "^5.0.5",
|
|
40
|
-
"@vitest/eslint-plugin": "^1.6.
|
|
41
|
-
"eslint": "^10.
|
|
42
|
-
"eslint-plugin-n": "^18.
|
|
43
|
-
"globals": "^17.
|
|
44
|
-
"tsdown": "^0.23.
|
|
40
|
+
"@vitest/eslint-plugin": "^1.6.28",
|
|
41
|
+
"eslint": "^10.14.0",
|
|
42
|
+
"eslint-plugin-n": "^18.5.0",
|
|
43
|
+
"globals": "^17.14.0",
|
|
44
|
+
"tsdown": "^0.23.4",
|
|
45
45
|
"typescript": "^5.9.3",
|
|
46
46
|
"vitest": "^5.0.5",
|
|
47
|
-
"@theholocron/
|
|
48
|
-
"@theholocron/
|
|
49
|
-
"@theholocron/tsdown-config": "^8.9.0-alpha.
|
|
50
|
-
"@theholocron/vitest-config": "^8.9.0-alpha.
|
|
47
|
+
"@theholocron/tsconfig": "^8.9.0-alpha.8",
|
|
48
|
+
"@theholocron/eslint-config": "^8.9.0-alpha.8",
|
|
49
|
+
"@theholocron/tsdown-config": "^8.9.0-alpha.8",
|
|
50
|
+
"@theholocron/vitest-config": "^8.9.0-alpha.8"
|
|
51
51
|
},
|
|
52
52
|
"engines": {
|
|
53
53
|
"node": ">=22.0.0"
|
|
@@ -56,10 +56,10 @@
|
|
|
56
56
|
"access": "public"
|
|
57
57
|
},
|
|
58
58
|
"scripts": {
|
|
59
|
-
"
|
|
60
|
-
"
|
|
59
|
+
"build": "tsdown && node ../scripts/check-bundle-size.mjs",
|
|
60
|
+
"lint:code": "eslint .",
|
|
61
|
+
"test:unit": "vitest run --coverage",
|
|
61
62
|
"test:watch": "vitest",
|
|
62
|
-
"
|
|
63
|
-
"verification.unitTests": "vitest run"
|
|
63
|
+
"typecheck": "tsc --noEmit"
|
|
64
64
|
}
|
|
65
65
|
}
|