mirror of
https://github.com/discordeno/discordeno.git
synced 2026-06-03 17:30:07 +00:00
fix: more helpers
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import type { AtLeastOne, BigString, Camelize, DiscordGetGatewayBot } from '@discordeno/types'
|
||||
import { GatewayOpcodes } from '@discordeno/types'
|
||||
import type { AtLeastOne, BigString, Camelize, DiscordGetGatewayBot, DiscordMember, RequestGuildMembers } from '@discordeno/types'
|
||||
import { GatewayIntents, GatewayOpcodes } from '@discordeno/types'
|
||||
import type { LeakyBucket } from '@discordeno/utils'
|
||||
import { createLeakyBucket, delay } from '@discordeno/utils'
|
||||
import { Collection, createLeakyBucket, delay } from '@discordeno/utils'
|
||||
import Shard from './Shard.js'
|
||||
import type { ShardEvents, UpdateVoiceState } from './types.js'
|
||||
import type { ShardEvents, StatusUpdate, UpdateVoiceState } from './types.js'
|
||||
|
||||
export function createGatewayManager(options: CreateGatewayManagerOptions): GatewayManager {
|
||||
if (!options.connection) {
|
||||
@@ -40,6 +40,12 @@ export function createGatewayManager(options: CreateGatewayManagerOptions): Gate
|
||||
spawnShardDelay: options.spawnShardDelay ?? 5300,
|
||||
shards: new Map(),
|
||||
buckets: new Map(),
|
||||
cache: {
|
||||
requestMembers: {
|
||||
enabled: options.cache?.requestMembers?.enabled ?? false,
|
||||
pending: new Collection(),
|
||||
}
|
||||
},
|
||||
|
||||
calculateTotalShards() {
|
||||
// Bots under 100k servers do not have access to total shards.
|
||||
@@ -196,6 +202,85 @@ export function createGatewayManager(options: CreateGatewayManagerOptions): Gate
|
||||
},
|
||||
})
|
||||
},
|
||||
|
||||
async editBotStatus(data) {
|
||||
await Promise.all(
|
||||
[...gateway.shards.values()].map(async (shard) => {
|
||||
gateway.editShardStatus(shard.id, data)
|
||||
}),
|
||||
)
|
||||
},
|
||||
|
||||
async editShardStatus(shardId, data) {
|
||||
const shard = gateway.shards.get(shardId)
|
||||
if (!shard) {
|
||||
throw new Error(`Shard (id: ${shardId}) not found.`)
|
||||
}
|
||||
|
||||
return await shard.send({
|
||||
op: GatewayOpcodes.PresenceUpdate,
|
||||
d: {
|
||||
since: null,
|
||||
afk: false,
|
||||
activities: data.activities,
|
||||
status: data.status,
|
||||
},
|
||||
})
|
||||
},
|
||||
|
||||
async requestMembers(guildId, options) {
|
||||
// You can request 1 member without the intent
|
||||
// Check if intents is not 0 as proxy ws won't set intents in other instances
|
||||
if (gateway.intents && (!options?.limit || options.limit > 1) && !(gateway.intents & GatewayIntents.GuildMembers)) {
|
||||
throw new Error('MISSING_INTENT_GUILD_MEMBERS')
|
||||
}
|
||||
|
||||
if (options?.userIds?.length) {
|
||||
options.limit = options.userIds.length
|
||||
}
|
||||
|
||||
const shardId = gateway.calculateShardId(guildId)
|
||||
const shard = gateway.shards.get(shardId)
|
||||
if (!shard) {
|
||||
throw new Error(`Shard (id: ${shardId}) not found.`)
|
||||
}
|
||||
|
||||
const nonce = `${guildId}-${Date.now()}`
|
||||
|
||||
// Gateway does not require caching these requests so directly send and return
|
||||
if (!gateway.cache.requestMembers?.enabled) {
|
||||
await shard.send({
|
||||
op: GatewayOpcodes.RequestGuildMembers,
|
||||
d: {
|
||||
guild_id: guildId.toString(),
|
||||
// If a query is provided use it, OR if a limit is NOT provided use ""
|
||||
query: options?.query ?? (options?.limit ? undefined : ''),
|
||||
limit: options?.limit ?? 0,
|
||||
presences: options?.presences ?? false,
|
||||
user_ids: options?.userIds?.map((id) => id.toString()),
|
||||
nonce,
|
||||
},
|
||||
})
|
||||
return [];
|
||||
}
|
||||
|
||||
return await new Promise((resolve) => {
|
||||
gateway.cache.requestMembers?.pending.set(nonce, { nonce, resolve, members: [] })
|
||||
|
||||
shard.send({
|
||||
op: GatewayOpcodes.RequestGuildMembers,
|
||||
d: {
|
||||
guild_id: guildId.toString(),
|
||||
// If a query is provided use it, OR if a limit is NOT provided use ""
|
||||
query: options?.query ?? (options?.limit ? undefined : ''),
|
||||
limit: options?.limit ?? 0,
|
||||
presences: options?.presences ?? false,
|
||||
user_ids: options?.userIds?.map((id) => id.toString()),
|
||||
nonce,
|
||||
},
|
||||
})
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
return gateway
|
||||
@@ -276,6 +361,18 @@ export interface CreateGatewayManagerOptions {
|
||||
version?: number
|
||||
/** The events handlers */
|
||||
events: ShardEvents
|
||||
/** This managers cache related settings. */
|
||||
cache?: {
|
||||
requestMembers?: {
|
||||
/**
|
||||
* Whether or not request member requests should be cached.
|
||||
* @default false
|
||||
*/
|
||||
enabled?: boolean
|
||||
/** The pending requests. */
|
||||
pending: Collection<string, RequestMemberRequest>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export interface GatewayManager extends Required<CreateGatewayManagerOptions> {
|
||||
@@ -329,4 +426,52 @@ export interface GatewayManager extends Required<CreateGatewayManagerOptions> {
|
||||
channelId: BigString,
|
||||
options?: AtLeastOne<Omit<UpdateVoiceState, 'guildId' | 'channelId'>>,
|
||||
) => Promise<void>
|
||||
/**
|
||||
* Edits the bot status in all shards that this gateway manages.
|
||||
*
|
||||
* @param data The status data to set the bots status to.
|
||||
* @returns Promise<void>
|
||||
*/
|
||||
editBotStatus: (data: StatusUpdate) => Promise<void>
|
||||
/**
|
||||
* Edits the bot's status on one shard.
|
||||
*
|
||||
* @param shardId The shard id to edit the status for.
|
||||
* @param data The status data to set the bots status to.
|
||||
* @returns Promise<void>
|
||||
*/
|
||||
editShardStatus: (shardId: number, data: StatusUpdate) => Promise<void>
|
||||
/**
|
||||
* Fetches the list of members for a guild over the gateway.
|
||||
*
|
||||
* @param guildId - The ID of the guild to get the list of members for.
|
||||
* @param options - The parameters for the fetching of the members.
|
||||
*
|
||||
* @remarks
|
||||
* If requesting the entire member list:
|
||||
* - Requires the `GUILD_MEMBERS` intent.
|
||||
*
|
||||
* If requesting presences ({@link RequestGuildMembers.presences | presences} set to `true`):
|
||||
* - Requires the `GUILD_PRESENCES` intent.
|
||||
*
|
||||
* If requesting a prefix ({@link RequestGuildMembers.query | query} non-`undefined`):
|
||||
* - Returns a maximum of 100 members.
|
||||
*
|
||||
* If requesting a users by ID ({@link RequestGuildMembers.userIds | userIds} non-`undefined`):
|
||||
* - Returns a maximum of 100 members.
|
||||
*
|
||||
* Fires a _Guild Members Chunk_ gateway event for every 1000 members fetched.
|
||||
*
|
||||
* @see {@link https://discord.com/developers/docs/topics/gateway#request-guild-members}
|
||||
*/
|
||||
requestMembers: (guildId: BigString, options?: Omit<RequestGuildMembers, 'guildId'>) => Promise<Camelize<DiscordMember[]>>
|
||||
}
|
||||
|
||||
export interface RequestMemberRequest {
|
||||
/** The unique nonce for this request. */
|
||||
nonce: string
|
||||
/** The resolver handler to run when all members arrive. */
|
||||
resolve: (value: Camelize<DiscordMember[]> | PromiseLike<Camelize<DiscordMember[]>>) => void
|
||||
/** The members that have already arrived for this request. */
|
||||
members: Camelize<DiscordMember[]>
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ActivityTypes, Camelize, DiscordGatewayPayload, GatewayOpcodes, PresenceStatus } from '@discordeno/types'
|
||||
import type { ActivityTypes, Camelize, DiscordActivity, DiscordGatewayPayload, GatewayOpcodes, PresenceStatus } from '@discordeno/types'
|
||||
import type Shard from './Shard.js'
|
||||
|
||||
export enum ShardState {
|
||||
@@ -167,3 +167,15 @@ export interface UpdateVoiceState {
|
||||
/** Is the client deafened */
|
||||
selfDeaf: boolean
|
||||
}
|
||||
|
||||
/** https://discord.com/developers/docs/topics/gateway-events#update-presence */
|
||||
export interface StatusUpdate {
|
||||
// /** Unix time (in milliseconds) of when the client went idle, or null if the client is not idle */
|
||||
// since: number | null;
|
||||
/** The user's activities */
|
||||
activities: Camelize<DiscordActivity[]>
|
||||
/** The user's new status */
|
||||
status: keyof typeof PresenceStatus
|
||||
// /** Whether or not the client is afk */
|
||||
// afk: boolean;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* eslint-disable @typescript-eslint/restrict-template-expressions */
|
||||
/* eslint-disable no-const-assign */
|
||||
import { InteractionResponseTypes } from '@discordeno/types'
|
||||
import { DiscordGuildWidget, InteractionResponseTypes } from '@discordeno/types'
|
||||
import {
|
||||
calculateBits,
|
||||
camelize,
|
||||
@@ -53,6 +53,8 @@ import type {
|
||||
DiscordFollowedChannel,
|
||||
DiscordGetGatewayBot,
|
||||
DiscordGuild,
|
||||
DiscordGuildPreview,
|
||||
DiscordGuildWidgetSettings,
|
||||
DiscordIntegration,
|
||||
DiscordInvite,
|
||||
DiscordInviteMetadata,
|
||||
@@ -61,6 +63,8 @@ import type {
|
||||
DiscordMember,
|
||||
DiscordMemberWithUser,
|
||||
DiscordMessage,
|
||||
DiscordModifyGuildWelcomeScreen,
|
||||
DiscordPrunedCount,
|
||||
DiscordRole,
|
||||
DiscordScheduledEvent,
|
||||
DiscordStageInstance,
|
||||
@@ -72,6 +76,7 @@ import type {
|
||||
DiscordVanityUrl,
|
||||
DiscordVoiceRegion,
|
||||
DiscordWebhook,
|
||||
DiscordWelcomeScreen,
|
||||
EditAutoModerationRuleOptions,
|
||||
EditChannelPermissionOverridesOptions,
|
||||
EditGuildRole,
|
||||
@@ -175,6 +180,9 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage
|
||||
dm: () => {
|
||||
return '/users/@me/channels'
|
||||
},
|
||||
pins: (channelId) => {
|
||||
return `/channels/${channelId}/pins`
|
||||
},
|
||||
reactions: {
|
||||
bot: (channelId, messageId, emoji) => {
|
||||
return `/channels/${channelId}/messages/${messageId}/reactions/${encodeURIComponent(emoji)}/@me`
|
||||
@@ -195,6 +203,18 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage
|
||||
if (options.limit) url += `&limit=${options.limit}`
|
||||
}
|
||||
|
||||
return url
|
||||
},
|
||||
message: (channelId, messageId, emoji, options) => {
|
||||
let url = `/channels/${channelId}/messages/${messageId}/reactions/${encodeURIComponent(emoji)}?`
|
||||
|
||||
if (options) {
|
||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||
if (options.after) url += `after=${options.after}`
|
||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||
if (options.limit) url += `&limit=${options.limit}`
|
||||
}
|
||||
|
||||
return url
|
||||
},
|
||||
},
|
||||
@@ -505,6 +525,26 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage
|
||||
},
|
||||
},
|
||||
mfa: (guildId) => `/guilds/${guildId}/mfa`,
|
||||
preview: (guildId) => {
|
||||
return `/guilds/${guildId}/preview`
|
||||
},
|
||||
prune: (guildId, options) => {
|
||||
let url = `/guilds/${guildId}/prune?`
|
||||
|
||||
if (options) {
|
||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||
if (options.days) url += `days=${options.days}`
|
||||
if (Array.isArray(options.includeRoles)) {
|
||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||
url += `&include_roles=${options.includeRoles.join(',')}`
|
||||
} else if (options.includeRoles) {
|
||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||
url += `&include_roles=${options.includeRoles}`
|
||||
}
|
||||
}
|
||||
|
||||
return url
|
||||
},
|
||||
roles: {
|
||||
one: (guildId, roleId) => {
|
||||
return `/guilds/${guildId}/roles/${roleId}`
|
||||
@@ -545,12 +585,25 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage
|
||||
webhooks: (guildId) => {
|
||||
return `/guilds/${guildId}/webhooks`
|
||||
},
|
||||
welcome: (guildId) => {
|
||||
return `/guilds/${guildId}/welcome-screen`
|
||||
},
|
||||
widget: (guildId) => {
|
||||
return `/guilds/${guildId}/widget`
|
||||
},
|
||||
widgetJson: (guildId) => {
|
||||
return `/guilds/${guildId}/widget.json`
|
||||
},
|
||||
},
|
||||
|
||||
sticker: (stickerId: BigString) => {
|
||||
return `/stickers/${stickerId}`
|
||||
},
|
||||
|
||||
regions: () => {
|
||||
return '/voice/regions'
|
||||
},
|
||||
|
||||
// Interaction Endpoints
|
||||
interactions: {
|
||||
commands: {
|
||||
@@ -1235,7 +1288,6 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage
|
||||
)
|
||||
},
|
||||
|
||||
/** Modify a guild's MFA level. Requires guild ownership. */
|
||||
async editGuildMfaLevel(guildId: BigString, mfaLevel: MfaLevels, reason?: string): Promise<void> {
|
||||
return await rest.post(rest.routes.guilds.mfa(guildId), { level: mfaLevel, reason })
|
||||
},
|
||||
@@ -1309,6 +1361,14 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage
|
||||
return await rest.patch<DiscordWebhook>(rest.routes.webhooks.webhook(webhookId, token), options)
|
||||
},
|
||||
|
||||
async editWelcomeScreen(guildId, options) {
|
||||
return await rest.patch<DiscordWelcomeScreen>(rest.routes.guilds.welcome(guildId), options)
|
||||
},
|
||||
|
||||
async editWidgetSettings(guildId, options) {
|
||||
return await rest.patch<DiscordGuildWidgetSettings>(rest.routes.guilds.widget(guildId), options)
|
||||
},
|
||||
|
||||
async executeWebhook(webhookId, token, options) {
|
||||
return await rest.post<DiscordMessage>(rest.routes.webhooks.webhook(webhookId, token, options), options)
|
||||
},
|
||||
@@ -1349,6 +1409,10 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage
|
||||
return await rest.get<DiscordAutoModerationRule[]>(rest.routes.guilds.automod.rules(guildId))
|
||||
},
|
||||
|
||||
async getAvailableVoiceRegions() {
|
||||
return await rest.get<DiscordVoiceRegion[]>(rest.routes.regions())
|
||||
},
|
||||
|
||||
async getBan(guildId, userId) {
|
||||
return await rest.get<DiscordBan>(rest.routes.guilds.members.ban(guildId, userId))
|
||||
},
|
||||
@@ -1415,6 +1479,10 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage
|
||||
return await rest.get<DiscordApplicationCommand[]>(rest.routes.interactions.commands.guilds.all(rest.applicationId, guildId))
|
||||
},
|
||||
|
||||
async getGuildPreview(guildId) {
|
||||
return await rest.get<DiscordGuildPreview>(rest.routes.guilds.preview(guildId))
|
||||
},
|
||||
|
||||
async getGuildTemplate(templateCode) {
|
||||
return await rest.get<DiscordTemplate>(rest.routes.guilds.templates.code(templateCode))
|
||||
},
|
||||
@@ -1439,6 +1507,14 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage
|
||||
return await rest.get<DiscordInviteMetadata[]>(rest.routes.guilds.invites(guildId))
|
||||
},
|
||||
|
||||
async getMessage(channelId, messageId) {
|
||||
return await rest.get<DiscordMessage>(rest.routes.channels.message(channelId, messageId))
|
||||
},
|
||||
|
||||
async getMessages(channelId, options) {
|
||||
return await rest.get<DiscordMessage[]>(rest.routes.channels.messages(channelId, options))
|
||||
},
|
||||
|
||||
async getNitroStickerPacks() {
|
||||
return await rest.get<DiscordStickerPack[]>(rest.routes.nitroStickerPacks())
|
||||
},
|
||||
@@ -1447,6 +1523,10 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage
|
||||
return await rest.get<DiscordMessage>(rest.routes.interactions.responses.original(rest.applicationId, token))
|
||||
},
|
||||
|
||||
async getPinnedMessages(channelId) {
|
||||
return await rest.get<DiscordMessage[]>(rest.routes.channels.pins(channelId))
|
||||
},
|
||||
|
||||
async getPrivateArchivedThreads(channelId, options) {
|
||||
return await rest.get<DiscordListArchivedThreads>(rest.routes.channels.threads.private(channelId, options))
|
||||
},
|
||||
@@ -1455,6 +1535,10 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage
|
||||
return await rest.get<DiscordListArchivedThreads>(rest.routes.channels.threads.joined(channelId, options))
|
||||
},
|
||||
|
||||
async getPruneCount(guildId, options) {
|
||||
return await rest.get<DiscordPrunedCount>(rest.routes.guilds.prune(guildId, options))
|
||||
},
|
||||
|
||||
async getPublicArchivedThreads(channelId, options) {
|
||||
return await rest.get<DiscordListArchivedThreads>(rest.routes.channels.threads.public(channelId, options))
|
||||
},
|
||||
@@ -1503,6 +1587,10 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage
|
||||
return await rest.get<DiscordThreadMember[]>(rest.routes.channels.threads.members(channelId))
|
||||
},
|
||||
|
||||
async getReactions(channelId, messageId, reaction, options) {
|
||||
return await rest.get<DiscordUser[]>(rest.routes.channels.reactions.message(channelId, messageId, reaction, options))
|
||||
},
|
||||
|
||||
async getUser(id) {
|
||||
return await rest.get<DiscordUser>(rest.routes.user(id))
|
||||
},
|
||||
@@ -1527,6 +1615,18 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage
|
||||
return await rest.get<DiscordWebhook>(rest.routes.webhooks.webhook(webhookId, token))
|
||||
},
|
||||
|
||||
async getWelcomeScreen(guildId) {
|
||||
return await rest.get<DiscordWelcomeScreen>(rest.routes.guilds.welcome(guildId))
|
||||
},
|
||||
|
||||
async getWidget(guildId) {
|
||||
return await rest.get<DiscordGuildWidget>(rest.routes.guilds.widgetJson(guildId))
|
||||
},
|
||||
|
||||
async getWidgetSettings(guildId) {
|
||||
return await rest.get<DiscordGuildWidgetSettings>(rest.routes.guilds.widget(guildId))
|
||||
},
|
||||
|
||||
async joinThread(channelId) {
|
||||
return await rest.put(rest.routes.channels.threads.me(channelId))
|
||||
},
|
||||
@@ -1730,6 +1830,8 @@ export interface RestManager {
|
||||
bulk: (channelId: BigString) => string
|
||||
/** Route for non-specific dm channel. */
|
||||
dm: () => string
|
||||
/** Route for handling a channels pins. */
|
||||
pins: (channelId: BigString) => string
|
||||
/** Route for non-specific webhook in a channel. */
|
||||
webhooks: (channelId: BigString) => string
|
||||
/** Route for a specific channel. */
|
||||
@@ -1787,6 +1889,8 @@ export interface RestManager {
|
||||
all: (channelId: BigString, messageId: BigString) => string
|
||||
/** Route for handling all reactions for a single emoji on a message. */
|
||||
emoji: (channelId: BigString, messageId: BigString, emoji: string, options?: GetReactions) => string
|
||||
/** Route for handling a specific reaction on a message. */
|
||||
message: (channelId: BigString, messageId: BigString, emoji: string, options?: GetReactions) => string
|
||||
}
|
||||
}
|
||||
/** Routes for guild related endpoints. */
|
||||
@@ -1827,8 +1931,18 @@ export interface RestManager {
|
||||
invite: (inviteCode: string, options?: GetInvite) => string
|
||||
/** Route for handling non-specific invites in a guild. */
|
||||
invites: (guildId: BigString) => string
|
||||
/** Route for handling a guild's preview. */
|
||||
preview: (guildId: BigString) => string
|
||||
/** Route for handling pruning of a guild. */
|
||||
prune: (guildId: BigString, options?: GetGuildPruneCountQuery) => string
|
||||
/** Route for handling non-specific webhooks in a guild */
|
||||
webhooks: (guildId: BigString) => string
|
||||
/** Route for handling a guild's welcome screen. */
|
||||
welcome: (guildId: BigString) => string
|
||||
/** Route for handling a guild's widget. */
|
||||
widget: (guildId: BigString) => string
|
||||
/** Route for handling a guild's widget in the form of json. */
|
||||
widgetJson: (guildId: BigString) => string
|
||||
/** Route for handling a guilds mfa level. */
|
||||
mfa: (guildId: BigString) => string
|
||||
/** Routes for handling a guild's members. */
|
||||
@@ -1909,6 +2023,8 @@ export interface RestManager {
|
||||
}
|
||||
/** Route for handling a sticker. */
|
||||
sticker: (stickerId: BigString) => string
|
||||
/** Route for handling all voice regions. */
|
||||
regions: () => string
|
||||
}
|
||||
/** Check the rate limits for a url or a bucket. */
|
||||
checkRateLimits: (url: string) => number | false
|
||||
@@ -2873,7 +2989,6 @@ export interface RestManager {
|
||||
/**
|
||||
* Edits the voice state of the bot user.
|
||||
*
|
||||
* @param rest - The rest manager to use to make the request.
|
||||
* @param guildId - The ID of the guild in which to edit the voice state of the bot user.
|
||||
* @param options - The parameters for the edit of the voice state.
|
||||
*
|
||||
@@ -3016,6 +3131,35 @@ export interface RestManager {
|
||||
* @see {@link https://discord.com/developers/docs/resources/webhook#modify-webhook-with-token}
|
||||
*/
|
||||
editWebhookWithToken: (webhookId: BigString, token: string, options: Omit<ModifyWebhook, 'channelId'>) => Promise<Camelize<DiscordWebhook>>
|
||||
/**
|
||||
* Edits a guild's welcome screen.
|
||||
*
|
||||
* @param guildId - The ID of the guild to edit the welcome screen of.
|
||||
* @param options - The parameters for the edit of the welcome screen.
|
||||
* @returns An instance of the edited {@link WelcomeScreen}.
|
||||
*
|
||||
* @remarks
|
||||
* Requires the `MANAGE_GUILD` permission.
|
||||
*
|
||||
* Fires a _Guild Update_ gateway event.
|
||||
*
|
||||
* @see {@link https://discord.com/developers/docs/resources/guild#modify-guild-welcome-screen}
|
||||
*/
|
||||
editWelcomeScreen: (guildId: BigString, options: Camelize<DiscordModifyGuildWelcomeScreen>) => Promise<Camelize<DiscordWelcomeScreen>>
|
||||
/**
|
||||
* Edits the settings of a guild's widget.
|
||||
*
|
||||
* @param guildId - The ID of the guild to edit the settings of the widget of.
|
||||
* @returns An instance of the edited {@link GuildWidgetSettings}.
|
||||
*
|
||||
* @remarks
|
||||
* Requires the `MANAGE_GUILD` permission.
|
||||
*
|
||||
* Fires a _Guild Update_ gateway event.
|
||||
*
|
||||
* @see {@link https://discord.com/developers/docs/resources/guild#modify-guild-widget}
|
||||
*/
|
||||
editWidgetSettings: (guildId: BigString, options: Camelize<DiscordGuildWidgetSettings>) => Promise<Camelize<DiscordGuildWidgetSettings>>
|
||||
/**
|
||||
* Executes a webhook, causing a message to be posted in the channel configured for the webhook.
|
||||
*
|
||||
@@ -3118,6 +3262,12 @@ export interface RestManager {
|
||||
* @see {@link https://discord.com/developers/docs/resources/auto-moderation#list-auto-moderation-rules-for-guild}
|
||||
*/
|
||||
getAutomodRules: (guildId: BigString) => Promise<Camelize<DiscordAutoModerationRule[]>>
|
||||
/**
|
||||
* Gets the list of available voice regions.
|
||||
*
|
||||
* @returns A collection of {@link VoiceRegions | VoiceRegion} objects assorted by voice region ID.
|
||||
*/
|
||||
getAvailableVoiceRegions: () => Promise<Camelize<DiscordVoiceRegion[]>>
|
||||
/**
|
||||
* Gets a ban by user ID.
|
||||
*
|
||||
@@ -3289,6 +3439,18 @@ export interface RestManager {
|
||||
* @see {@link https://discord.com/developers/docs/interactions/application-commands#get-global-application-commandss}
|
||||
*/
|
||||
getGuildApplicationCommands: (guildId: BigString) => Promise<Camelize<DiscordApplicationCommand[]>>
|
||||
/**
|
||||
* Gets the preview of a guild by a guild's ID.
|
||||
*
|
||||
* @param guildId - The ID of the guild to get the preview of.
|
||||
* @returns An instance of {@link GuildPreview}.
|
||||
*
|
||||
* @remarks
|
||||
* If the bot user is not in the guild, the guild must be lurkable.
|
||||
*
|
||||
* @see {@link https://discord.com/developers/docs/resources/guild#get-guild-preview}
|
||||
*/
|
||||
getGuildPreview: (guildId: BigString) => Promise<Camelize<DiscordGuildPreview>>
|
||||
/**
|
||||
* Returns a sticker object for the given guild and sticker IDs.
|
||||
*
|
||||
@@ -3382,6 +3544,38 @@ export interface RestManager {
|
||||
* @see {@link https://discord.com/developers/docs/resources/invite#get-invites}
|
||||
*/
|
||||
getInvites: (guildId: BigString) => Promise<Camelize<DiscordInviteMetadata[]>>
|
||||
/**
|
||||
* Gets a message from a channel by the ID of the message.
|
||||
*
|
||||
* @param channelId - The ID of the channel from which to get the message.
|
||||
* @param messageId - The ID of the message to get.
|
||||
* @returns An instance of {@link Message}.
|
||||
*
|
||||
* @remarks
|
||||
* Requires that the bot user be able to see the contents of the channel in which the message was posted.
|
||||
*
|
||||
* If getting a message from a guild channel:
|
||||
* - Requires the `READ_MESSAGE_HISTORY` permission.
|
||||
*
|
||||
* @see {@link https://discord.com/developers/docs/resources/channel#get-channel-message}
|
||||
*/
|
||||
getMessage: (channelId: BigString, messageId: BigString) => Promise<Camelize<DiscordMessage>>
|
||||
/**
|
||||
* Gets multiple messages from a channel.
|
||||
*
|
||||
* @param channelId - The ID of the channel from which to get the messages.
|
||||
* @param options - The parameters for the fetching of the messages.
|
||||
* @returns A collection of {@link Message} objects assorted by message ID.
|
||||
*
|
||||
* @remarks
|
||||
* Requires that the bot user be able to see the contents of the channel in which the messages were posted.
|
||||
*
|
||||
* If getting a messages from a guild channel:
|
||||
* - Requires the `READ_MESSAGE_HISTORY` permission.
|
||||
*
|
||||
* @see {@link https://discord.com/developers/docs/resources/channel#get-channel-messages}
|
||||
*/
|
||||
getMessages: (channelId: BigString, options?: GetMessagesOptions) => Promise<Camelize<DiscordMessage[]>>
|
||||
/**
|
||||
* Returns the list of sticker packs available to Nitro subscribers.
|
||||
*
|
||||
@@ -3407,6 +3601,21 @@ export interface RestManager {
|
||||
* @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#get-original-interaction-response}
|
||||
*/
|
||||
getOriginalInteractionResponse: (token: string) => Promise<Camelize<DiscordMessage>>
|
||||
/**
|
||||
* Gets the pinned messages for a channel.
|
||||
*
|
||||
* @param channelId - The ID of the channel to get the pinned messages for.
|
||||
* @returns A collection of {@link Message} objects assorted by message ID.
|
||||
*
|
||||
* @remarks
|
||||
* Requires that the bot user be able to see the contents of the channel in which the messages were posted.
|
||||
*
|
||||
* If getting a message from a guild channel:
|
||||
* - Requires the `READ_MESSAGE_HISTORY` permission.
|
||||
*
|
||||
* @see {@link https://discord.com/developers/docs/resources/channel#get-pinned-messages}
|
||||
*/
|
||||
getPinnedMessages: (channelId: BigString) => Promise<Camelize<DiscordMessage[]>>
|
||||
/**
|
||||
* Gets the list of private archived threads for a channel.
|
||||
*
|
||||
@@ -3442,6 +3651,19 @@ export interface RestManager {
|
||||
* @see {@link https://discord.com/developers/docs/resources/channel#list-joined-private-archived-threads}
|
||||
*/
|
||||
getPrivateJoinedArchivedThreads: (channelId: BigString, options?: ListArchivedThreads) => Promise<Camelize<DiscordArchivedThreads>>
|
||||
/**
|
||||
* Gets the number of members that would be kicked from a guild during pruning.
|
||||
*
|
||||
* @param guildId - The ID of the guild to get the prune count of.
|
||||
* @param options - The parameters for the fetching of the prune count.
|
||||
* @returns A number indicating the number of members that would be kicked.
|
||||
*
|
||||
* @remarks
|
||||
* Requires the `KICK_MEMBERS` permission.
|
||||
*
|
||||
* @see {@link https://discord.com/developers/docs/resources/guild#get-guild-prune-count}
|
||||
*/
|
||||
getPruneCount: (guildId: BigString, options?: GetGuildPruneCountQuery) => Promise<Camelize<DiscordPrunedCount>>
|
||||
/**
|
||||
* Gets the list of public archived threads for a channel.
|
||||
*
|
||||
@@ -3555,6 +3777,18 @@ export interface RestManager {
|
||||
* @see {@link https://discord.com/developers/docs/resources/channel#list-thread-members}
|
||||
*/
|
||||
getThreadMembers: (channelId: BigString) => Promise<Camelize<DiscordThreadMember[]>>
|
||||
/**
|
||||
* Gets the list of users that reacted with an emoji to a message.
|
||||
*
|
||||
* @param channelId - The ID of the channel the message to get the users for is in.
|
||||
* @param messageId - The ID of the message to get the users for.
|
||||
* @param reaction - The reaction for which to get the users.
|
||||
* @param options - The parameters for the fetching of the users.
|
||||
* @returns A collection of {@link User} objects assorted by user ID.
|
||||
*
|
||||
* @see {@link https://discord.com/developers/docs/resources/channel#get-reactions}
|
||||
*/
|
||||
getReactions: (channelId: BigString, messageId: BigString, reaction: string, options?: GetReactions) => Promise<Camelize<DiscordUser[]>>
|
||||
/**
|
||||
* Get a user's data from the api
|
||||
*
|
||||
@@ -3624,6 +3858,40 @@ export interface RestManager {
|
||||
* @see {@link https://discord.com/developers/docs/resources/webhook#get-webhook-with-token}
|
||||
*/
|
||||
getWebhookWithToken: (webhookId: BigString, token: string) => Promise<Camelize<DiscordWebhook>>
|
||||
/**
|
||||
* Gets the welcome screen for a guild.
|
||||
*
|
||||
* @param guildId - The ID of the guild to get the welcome screen for.
|
||||
* @returns An instance of {@link WelcomeScreen}.
|
||||
*
|
||||
* @remarks
|
||||
* If the welcome screen is not enabled:
|
||||
* - Requires the `MANAGE_GUILD` permission.
|
||||
*
|
||||
* @see {@link https://discord.com/developers/docs/resources/guild#get-guild-welcome-screen}
|
||||
*/
|
||||
getWelcomeScreen: (guildId: BigString) => Promise<Camelize<DiscordWelcomeScreen>>
|
||||
/**
|
||||
* Gets the guild widget by guild ID.
|
||||
*
|
||||
* @param guildId - The ID of the guild to get the widget of.
|
||||
* @returns An instance of {@link GuildWidget}.
|
||||
*
|
||||
* @see {@link https://discord.com/developers/docs/resources/guild#get-guild-widget}
|
||||
*/
|
||||
getWidget: (guildId: BigString) => Promise<Camelize<DiscordGuildWidget>>
|
||||
/**
|
||||
* Gets the settings of a guild's widget.
|
||||
*
|
||||
* @param guildId - The ID of the guild to get the widget of.
|
||||
* @returns An instance of {@link GuildWidgetSettings}.
|
||||
*
|
||||
* @remarks
|
||||
* Requires the `MANAGE_GUILD` permission.
|
||||
*
|
||||
* @see {@link https://discord.com/developers/docs/resources/guild#get-guild-widget-settings}
|
||||
*/
|
||||
getWidgetSettings: (guildId: BigString) => Promise<Camelize<DiscordGuildWidgetSettings>>
|
||||
/**
|
||||
* Adds the bot user to a thread.
|
||||
*
|
||||
|
||||
@@ -1964,26 +1964,26 @@ export interface DiscordApplicationCommandPermissions {
|
||||
permission: boolean
|
||||
}
|
||||
|
||||
// /** https://discord.com/developers/docs/resources/guild#get-guild-widget-example-get-guild-widget */
|
||||
// export interface DiscordGuildWidget {
|
||||
// id: string
|
||||
// name: string
|
||||
// instant_invite: string
|
||||
// channels: Array<{
|
||||
// id: string
|
||||
// name: string
|
||||
// position: number
|
||||
// }>
|
||||
// members: Array<{
|
||||
// id: string
|
||||
// username: string
|
||||
// discriminator: string
|
||||
// avatar?: string | null
|
||||
// status: string
|
||||
// avatar_url: string
|
||||
// }>
|
||||
// presence_count: number
|
||||
// }
|
||||
/** https://discord.com/developers/docs/resources/guild#get-guild-widget-example-get-guild-widget */
|
||||
export interface DiscordGuildWidget {
|
||||
id: string
|
||||
name: string
|
||||
instant_invite: string
|
||||
channels: Array<{
|
||||
id: string
|
||||
name: string
|
||||
position: number
|
||||
}>
|
||||
members: Array<{
|
||||
id: string
|
||||
username: string
|
||||
discriminator: string
|
||||
avatar?: string | null
|
||||
status: string
|
||||
avatar_url: string
|
||||
}>
|
||||
presence_count: number
|
||||
}
|
||||
|
||||
/** https://discord.com/developers/docs/resources/guild#guild-preview-object */
|
||||
export interface DiscordGuildPreview {
|
||||
@@ -2467,12 +2467,12 @@ export interface DiscordVoiceRegion {
|
||||
custom: boolean
|
||||
}
|
||||
|
||||
// export interface DiscordGuildWidgetSettings {
|
||||
// /** whether the widget is enabled */
|
||||
// enabled: boolean
|
||||
// /** the widget channel id */
|
||||
// channel_id: string | null
|
||||
// }
|
||||
export interface DiscordGuildWidgetSettings {
|
||||
/** whether the widget is enabled */
|
||||
enabled: boolean
|
||||
/** the widget channel id */
|
||||
channel_id: string | null
|
||||
}
|
||||
|
||||
export interface DiscordInstallParams {
|
||||
/** the scopes to add the application to the server with */
|
||||
@@ -2886,15 +2886,15 @@ export interface DiscordCreateMessage {
|
||||
// level: MfaLevels
|
||||
// }
|
||||
|
||||
// /** https://discord.com/developers/docs/resources/guild#modify-guild-welcome-screen */
|
||||
// export interface DiscordModifyGuildWelcomeScreen {
|
||||
// /** Whether the welcome screen is enabled */
|
||||
// enabled?: boolean | null
|
||||
// /** Channels linked in the welcome screen and their display options */
|
||||
// welcome_screen?: DiscordWelcomeScreenChannel[] | null
|
||||
// /** The server description to show in the welcome screen */
|
||||
// description?: string | null
|
||||
// }
|
||||
/** https://discord.com/developers/docs/resources/guild#modify-guild-welcome-screen */
|
||||
export interface DiscordModifyGuildWelcomeScreen {
|
||||
/** Whether the welcome screen is enabled */
|
||||
enabled?: boolean | null
|
||||
/** Channels linked in the welcome screen and their display options */
|
||||
welcome_screen?: DiscordWelcomeScreenChannel[] | null
|
||||
/** The server description to show in the welcome screen */
|
||||
description?: string | null
|
||||
}
|
||||
|
||||
// export interface DiscordStartThreadWithMessage {
|
||||
// /** 1-100 character thread name */
|
||||
@@ -3147,4 +3147,8 @@ export interface DiscordActiveThreads {
|
||||
export interface DiscordVanityUrl {
|
||||
code: string | null
|
||||
uses: number
|
||||
}
|
||||
|
||||
export interface DiscordPrunedCount {
|
||||
pruned: number
|
||||
}
|
||||
@@ -1087,3 +1087,17 @@ export interface EditUserVoiceState {
|
||||
/** The user id to target */
|
||||
userId: BigString
|
||||
}
|
||||
|
||||
/** https://discord.com/developers/docs/resources/guild#get-guild-widget-image-query-string-params */
|
||||
export interface GetGuildWidgetImageQuery {
|
||||
/**
|
||||
* Style of the widget returned, default: shield
|
||||
*
|
||||
* Shield: Widget with Discord icon and guild members online count.
|
||||
* Banner1: Large image with guild icon, name and online count. "POWERED BY DISCORD" as the footer of the widget
|
||||
* Banner2: Smaller widget style with guild icon, name and online count. Split on the right with Discord logo
|
||||
* Banner3: Large image with guild icon, name and online count. In the footer, Discord logo on the left and "Chat Now" on the right
|
||||
* Banner4: Large Discord logo at the top of the widget. Guild icon, name and online count in the middle portion of the widget and a "JOIN MY SERVER" button at the bottom
|
||||
*/
|
||||
style?: 'shield' | 'banner1' | 'banner2' | 'banner3' | 'banner4'
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* eslint-disable @typescript-eslint/restrict-template-expressions */
|
||||
import type { BigString, ImageFormat, ImageSize } from '@discordeno/types'
|
||||
import type { BigString, GetGuildWidgetImageQuery, ImageFormat, ImageSize } from '@discordeno/types'
|
||||
import { iconBigintToHash } from './hash.js'
|
||||
|
||||
/** Help format an image url. */
|
||||
@@ -120,3 +120,23 @@ export function guildSplashUrl(
|
||||
)
|
||||
: undefined
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a URL to the guild widget image stored in the Discord CDN.
|
||||
*
|
||||
* @param guildId - The ID of the guild to get the link to the widget image for.
|
||||
* @param options - The parameters for the building of the URL.
|
||||
* @returns The link to the resource.
|
||||
*/
|
||||
export function getWidgetImageUrl (
|
||||
guildId: BigString,
|
||||
options?: GetGuildWidgetImageQuery
|
||||
): string {
|
||||
let url = `https://cdn.discordapp.com/guilds/${guildId}/widget.png`
|
||||
|
||||
if (options?.style) {
|
||||
url += `?style=${options.style}`
|
||||
}
|
||||
|
||||
return url
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user