feat(types, rest, bot): Add lobby support (#4158)

* Add lobby support

* Fix CI
Apparently for extends a bot was a LobbyMember since both had
a required id property and even if LobbyMember had other properties
as well that did not matter

* update LobbyMember flags to use ToggleBitfield
This commit is contained in:
Fleny
2025-04-25 21:15:42 +02:00
committed by GitHub
parent f730ffe06c
commit 22012fc288
13 changed files with 405 additions and 16 deletions

View File

@@ -22,6 +22,8 @@ import type {
InteractionResource,
Invite,
InviteStageInstance,
Lobby,
LobbyMember,
Member,
Message,
MessageCall,
@@ -96,6 +98,8 @@ export interface TransformersObjects {
webhook: Webhook
subscription: Subscription
soundboardSound: SoundboardSound
lobby: Lobby
lobbyMember: LobbyMember
}
// NOTE: the top-level objects need both the dependencies and alwaysPresents even if empty when the key is specified, this is due the extends & nullability on DesiredPropertiesMetadata
@@ -730,6 +734,20 @@ export function createDesiredPropertiesObject<T extends RecursivePartial<Transfo
volume: defaultValue,
...desiredProperties.soundboardSound,
},
lobby: {
id: defaultValue,
applicationId: defaultValue,
metadata: defaultValue,
members: defaultValue,
linkedChannel: defaultValue,
...desiredProperties.lobby,
},
lobbyMember: {
id: defaultValue,
metadata: defaultValue,
flags: defaultValue,
...desiredProperties.lobbyMember,
},
} satisfies TransformersDesiredProperties as CompleteDesiredProperties<T, TDefault>
}
@@ -828,28 +846,31 @@ type GetErrorWhenUndesired<
type IsObject<T> = T extends object ? (T extends Function ? false : true) : false
// If the object is a transformed object, a collection of transformed object or an array of transformed objects we need to apply the desired props to them as well
export type TransformProperty<
T,
TProps extends TransformersDesiredProperties,
TBehavior extends DesiredPropertiesBehavior,
> = T extends TransformersObjects[keyof TransformersObjects] // is T a transformed object?
// NOTE: changing the order of these ternaries can cause bugs, for this reason we check in this order:
// - Is it an array?
// - Is it a collection?
// - Is it a bot?
// - Is it a transformed object?
// - Is it an object?
// - It's not an object
export type TransformProperty<T, TProps extends TransformersDesiredProperties, TBehavior extends DesiredPropertiesBehavior> = T extends Array<infer U> // is it an array?
? // Yes, apply the desired props
SetupDesiredProps<T, TProps, TBehavior>
TransformProperty<U, TProps, TBehavior>[]
: // No, is it a collection?
T extends Collection<infer U, infer UObj>
? // Yes, check for nested proprieties
Collection<U, TransformProperty<UObj, TProps, TBehavior>>
: // No, is it an array?
T extends Array<infer U>
? // Yes, apply the desired props
TransformProperty<U, TProps, TBehavior>[]
: // No, is it a Bot?
T extends Bot
? // Yes, return a bot with the correct set of props & behavior
Bot<TProps, TBehavior>
: // No, is this a generic object? If so we need to ensure nested inside there aren't transformed objects
: // No, is it a Bot?
T extends Bot
? // Yes, return a bot with the correct set of props & behavior
Bot<TProps, TBehavior>
: // No, is it a transformed object?
T extends TransformersObjects[keyof TransformersObjects]
? // Yes, apply the desired props
SetupDesiredProps<T, TProps, TBehavior>
: // Is it an object?
IsObject<T> extends true
? // Yes, check of nested proprieties
? // Yes, we need to ensure nested inside there aren't transformed objects
{ [K in keyof T]: TransformProperty<T[K], TProps, TBehavior> }
: // No, this is a normal value such as string / bigint / number
T

View File

@@ -1,6 +1,7 @@
import type {
AddDmRecipientOptions,
AddGuildMemberOptions,
AddLobbyMember,
AtLeastOne,
BeginGuildPrune,
BigString,
@@ -22,6 +23,7 @@ import type {
CreateGuildRole,
CreateGuildSoundboardSound,
CreateGuildStickerOptions,
CreateLobby,
CreateMessageOptions,
CreateScheduledEvent,
CreateStageInstance,
@@ -80,6 +82,7 @@ import type {
InteractionCallbackData,
InteractionCallbackOptions,
InteractionResponse,
LinkChannelToLobby,
ListArchivedThreads,
ListGuildMembers,
ListSkuSubscriptionsOptions,
@@ -93,6 +96,7 @@ import type {
ModifyGuildMember,
ModifyGuildSoundboardSound,
ModifyGuildTemplate,
ModifyLobby,
ModifyRolePositions,
ModifyWebhook,
SearchMembers,
@@ -120,6 +124,8 @@ import type {
Integration,
InteractionCallbackResponse,
Invite,
Lobby,
LobbyMember,
Member,
Message,
Role,
@@ -609,6 +615,24 @@ export function createBotHelpers<TProps extends TransformersDesiredProperties, T
updateApplicationRoleConnectionsMetadataRecords: async (applicationId, options) => {
return await bot.rest.updateApplicationRoleConnectionsMetadataRecords(applicationId, options)
},
createLobby: async (options) => {
return bot.transformers.lobby(bot, snakelize(await bot.rest.createLobby(options)))
},
getLobby: async (lobbyId) => {
return bot.transformers.lobby(bot, snakelize(await bot.rest.getLobby(lobbyId)))
},
modifyLobby: async (lobbyId, options) => {
return bot.transformers.lobby(bot, snakelize(await bot.rest.modifyLobby(lobbyId, options)))
},
addMemberToLobby: async (lobbyId, userId, options) => {
return bot.transformers.lobbyMember(bot, snakelize(await bot.rest.addMemberToLobby(lobbyId, userId, options)))
},
linkChannelToLobby: async (lobbyId, bearerToken, options) => {
return bot.transformers.lobby(bot, snakelize(await bot.rest.linkChannelToLobby(lobbyId, bearerToken, options)))
},
unlinkChannelToLobby: async (lobbyId, bearerToken) => {
return bot.transformers.lobby(bot, snakelize(await bot.rest.unlinkChannelToLobby(lobbyId, bearerToken)))
},
// All useless void return functions here
addReaction: async (channelId, messageId, reaction) => {
return await bot.rest.addReaction(channelId, messageId, reaction)
@@ -823,6 +847,15 @@ export function createBotHelpers<TProps extends TransformersDesiredProperties, T
deleteGuildSoundboardSound: async (guildId, soundId, reason) => {
await bot.rest.deleteGuildSoundboardSound(guildId, soundId, reason)
},
deleteLobby: async (lobbyId) => {
await bot.rest.deleteLobby(lobbyId)
},
removeMemberFromLobby: async (lobbyId, userId) => {
await bot.rest.removeMemberFromLobby(lobbyId, userId)
},
leaveLobby: async (lobbyId, bearerToken) => {
await bot.rest.leaveLobby(lobbyId, bearerToken)
},
}
}
@@ -1079,6 +1112,12 @@ export type BotHelpers<TProps extends TransformersDesiredProperties, TBehavior e
applicationId: BigString,
options: Camelize<DiscordApplicationRoleConnectionMetadata>[],
) => Promise<Camelize<DiscordApplicationRoleConnectionMetadata>[]>
createLobby: (options: CreateLobby) => Promise<SetupDesiredProps<Lobby, TProps, TBehavior>>
getLobby: (lobbyId: BigString) => Promise<SetupDesiredProps<Lobby, TProps, TBehavior>>
modifyLobby: (lobbyId: BigString, options: ModifyLobby) => Promise<SetupDesiredProps<Lobby, TProps, TBehavior>>
addMemberToLobby: (lobbyId: BigString, userId: BigString, options: AddLobbyMember) => Promise<SetupDesiredProps<LobbyMember, TProps, TBehavior>>
linkChannelToLobby: (lobbyId: BigString, bearerToken: string, options: LinkChannelToLobby) => Promise<SetupDesiredProps<Lobby, TProps, TBehavior>>
unlinkChannelToLobby: (lobbyId: BigString, bearerToken: string) => Promise<SetupDesiredProps<Lobby, TProps, TBehavior>>
// functions return Void so dont need any special handling
addReaction: (channelId: BigString, messageId: BigString, reaction: string) => Promise<void>
addReactions: (channelId: BigString, messageId: BigString, reactions: string[], ordered?: boolean) => Promise<void>
@@ -1164,4 +1203,7 @@ export type BotHelpers<TProps extends TransformersDesiredProperties, TBehavior e
reason?: string,
) => Promise<SetupDesiredProps<SoundboardSound, TProps, TBehavior>>
deleteGuildSoundboardSound: (guildId: BigString, soundId: BigString, reason?: string) => Promise<void>
deleteLobby: (lobbyId: BigString) => Promise<void>
removeMemberFromLobby: (lobbyId: BigString, userId: BigString) => Promise<void>
leaveLobby: (lobbyId: BigString, bearerToken: string) => Promise<void>
}

View File

@@ -41,6 +41,8 @@ import type {
DiscordInviteCreate,
DiscordInviteMetadata,
DiscordInviteStageInstance,
DiscordLobby,
DiscordLobbyMember,
DiscordMember,
DiscordMessage,
DiscordMessageCall,
@@ -116,6 +118,8 @@ import {
type InteractionResource,
type Invite,
type InviteStageInstance,
type Lobby,
type LobbyMember,
type Member,
type Message,
type MessageCall,
@@ -184,6 +188,8 @@ import {
transformInteractionResource,
transformInvite,
transformInviteStageInstance,
transformLobby,
transformLobbyMember,
transformMember,
transformMemberToDiscordMember,
transformMessage,
@@ -331,6 +337,8 @@ export type Transformers<TProps extends TransformersDesiredProperties, TBehavior
payload: DiscordInviteStageInstance,
inviteStageInstance: SetupDesiredProps<InviteStageInstance, TProps, TBehavior>,
) => any
lobby: (bot: Bot<TProps, TBehavior>, payload: DiscordLobby, lobby: SetupDesiredProps<Lobby, TProps, TBehavior>) => any
lobbyMember: (bot: Bot<TProps, TBehavior>, payload: DiscordLobbyMember, lobbyMember: SetupDesiredProps<LobbyMember, TProps, TBehavior>) => any
member: (bot: Bot<TProps, TBehavior>, payload: DiscordMember, member: SetupDesiredProps<Member, TProps, TBehavior>) => any
message: (bot: Bot<TProps, TBehavior>, payload: DiscordMessage, message: SetupDesiredProps<Message, TProps, TBehavior>) => any
messageCall: (bot: Bot<TProps, TBehavior>, payload: DiscordMessageCall, call: SetupDesiredProps<MessageCall, TProps, TBehavior>) => any
@@ -470,6 +478,8 @@ export type Transformers<TProps extends TransformersDesiredProperties, TBehavior
bot: Bot<TProps, TBehavior>,
payload: DiscordInviteStageInstance & { guildId: BigString },
) => SetupDesiredProps<InviteStageInstance, TProps, TBehavior>
lobby: (bot: Bot<TProps, TBehavior>, payload: DiscordLobby) => SetupDesiredProps<Lobby, TProps, TBehavior>
lobbyMember: (bot: Bot<TProps, TBehavior>, payload: DiscordLobbyMember) => SetupDesiredProps<LobbyMember, TProps, TBehavior>
member: (
bot: Bot<TProps, TBehavior>,
payload: DiscordMember,
@@ -560,6 +570,8 @@ export function createTransformers<TProps extends TransformersDesiredProperties,
interactionResource: options?.customizers?.interactionResource ?? defaultCustomizer,
invite: options.customizers?.invite ?? defaultCustomizer,
inviteStageInstance: options.customizers?.inviteStageInstance ?? defaultCustomizer,
lobby: options.customizers?.lobby ?? defaultCustomizer,
lobbyMember: options.customizers?.lobbyMember ?? defaultCustomizer,
member: options.customizers?.member ?? defaultCustomizer,
message: options.customizers?.message ?? defaultCustomizer,
messageCall: options.customizers?.messageCall ?? defaultCustomizer,
@@ -642,6 +654,8 @@ export function createTransformers<TProps extends TransformersDesiredProperties,
interactionResource: options.interactionResource ?? transformInteractionResource,
invite: options.invite ?? transformInvite,
inviteStageInstance: options.inviteStageInstance ?? transformInviteStageInstance,
lobby: options.lobby ?? transformLobby,
lobbyMember: options.lobbyMember ?? transformLobbyMember,
member: options.member ?? transformMember,
message: options.message ?? transformMessage,
messageCall: options.messageCall ?? transformMessageCall,

View File

@@ -20,6 +20,7 @@ export * from './incidentsData.js'
export * from './integration.js'
export * from './interaction.js'
export * from './invite.js'
export * from './lobby.js'
export * from './member.js'
export * from './message.js'
export * from './onboarding.js'

View File

@@ -0,0 +1,26 @@
import type { DiscordLobby, DiscordLobbyMember } from '@discordeno/types'
import { type InternalBot, type Lobby, type LobbyMember, ToggleBitfield } from '../index.js'
export function transformLobby(bot: InternalBot, payload: DiscordLobby): Lobby {
const props = bot.transformers.desiredProperties.lobby
const lobby = {} as Lobby
if (props.id && payload.id) lobby.id = bot.transformers.snowflake(payload.id)
if (props.applicationId && payload.application_id) lobby.applicationId = bot.transformers.snowflake(payload.application_id)
if (props.metadata && payload.metadata) lobby.metadata = payload.metadata
if (props.members && payload.members) lobby.members = payload.members.map((member) => bot.transformers.lobbyMember(bot, member))
if (props.linkedChannel && payload.linked_channel) lobby.linkedChannel = bot.transformers.channel(bot, { channel: payload.linked_channel })
return bot.transformers.customizers.lobby(bot, payload, lobby)
}
export function transformLobbyMember(bot: InternalBot, payload: DiscordLobbyMember): LobbyMember {
const props = bot.transformers.desiredProperties.lobbyMember
const lobbyMember = {} as LobbyMember
if (props.id && payload.id) lobbyMember.id = bot.transformers.snowflake(payload.id)
if (props.metadata && payload.metadata) lobbyMember.metadata = payload.metadata
if (props.flags && payload.flags) lobbyMember.flags = new ToggleBitfield(payload.flags)
return bot.transformers.customizers.lobbyMember(bot, payload, lobbyMember)
}

View File

@@ -1826,3 +1826,27 @@ export interface SoundboardSound {
/** The user who created this sound */
user?: User
}
/** https://discord.com/developers/docs/resources/lobby#lobby-object-lobby-structure */
export interface Lobby {
/** The id of this channel */
id: bigint
/** application that created the lobby */
applicationId: bigint
/** dictionary of string key/value pairs. The max total length is 1000. */
metadata?: Record<string, string>
/** members of the lobby */
members: LobbyMember[]
/** the guild channel linked to the lobby */
linkedChannel?: Channel
}
/** https://discord.com/developers/docs/resources/lobby#lobby-member-object-lobby-member-structure */
export interface LobbyMember {
/** The id of the user */
id: bigint
/** dictionary of string key/value pairs. The max total length is 1000. */
metadata?: Record<string, string>
/** lobby member flags combined as as bitfield */
flags?: ToggleBitfield
}

View File

@@ -33,6 +33,8 @@ import {
type DiscordInviteMetadata,
type DiscordListActiveThreads,
type DiscordListArchivedThreads,
type DiscordLobby,
type DiscordLobbyMember,
type DiscordMember,
type DiscordMemberWithUser,
type DiscordMessage,
@@ -1750,6 +1752,64 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage
})
},
async createLobby(options) {
return await rest.post<DiscordLobby>(rest.routes.lobby.create(), {
body: options,
})
},
async getLobby(lobbyId) {
return await rest.get<DiscordLobby>(rest.routes.lobby.lobby(lobbyId))
},
async modifyLobby(lobbyId, options) {
return await rest.patch<DiscordLobby>(rest.routes.lobby.lobby(lobbyId), {
body: options,
})
},
async deleteLobby(lobbyId) {
return await rest.delete(rest.routes.lobby.lobby(lobbyId))
},
async addMemberToLobby(lobbyId, userId, options) {
return await rest.put<DiscordLobbyMember>(rest.routes.lobby.member(lobbyId, userId), {
body: options,
})
},
async removeMemberFromLobby(lobbyId, userId) {
return await rest.delete(rest.routes.lobby.member(lobbyId, userId))
},
async leaveLobby(lobbyId, bearerToken) {
return await rest.delete(rest.routes.lobby.leave(lobbyId), {
headers: {
authorization: `Bearer ${bearerToken}`,
},
unauthorized: true,
})
},
async linkChannelToLobby(lobbyId, bearerToken, options) {
return await rest.patch<DiscordLobby>(rest.routes.lobby.link(lobbyId), {
body: options,
headers: {
authorization: `Bearer ${bearerToken}`,
},
unauthorized: true,
})
},
async unlinkChannelToLobby(lobbyId, bearerToken) {
return await rest.patch<DiscordLobby>(rest.routes.lobby.link(lobbyId), {
headers: {
authorization: `Bearer ${bearerToken}`,
},
unauthorized: true,
})
},
preferSnakeCase(enabled: boolean) {
const camelizer = enabled ? (x: any) => x : camelize

View File

@@ -647,6 +647,28 @@ export function createRoutes(): RestRoutes {
},
},
lobby: {
create: () => {
return '/lobbies'
},
lobby: (lobbyId) => {
return `/lobbies/${lobbyId}`
},
member: (lobbyId, userId) => {
return `/lobbies/${lobbyId}/members/${userId}`
},
leave: (lobbyId) => {
return `/lobbies/${lobbyId}/members/@me`
},
link: (lobbyId) => {
return `/lobbies/${lobbyId}/channel-linking`
},
},
applicationEmoji(applicationId, emojiId) {
return `/applications/${applicationId}/emojis/${emojiId}`
},

View File

@@ -1,6 +1,7 @@
import type {
AddDmRecipientOptions,
AddGuildMemberOptions,
AddLobbyMember,
AtLeastOne,
BeginGuildPrune,
BigString,
@@ -22,6 +23,7 @@ import type {
CreateGuildRole,
CreateGuildSoundboardSound,
CreateGuildStickerOptions,
CreateLobby,
CreateMessageOptions,
CreateScheduledEvent,
CreateStageInstance,
@@ -60,6 +62,8 @@ import type {
DiscordInteractionCallbackResponse,
DiscordInvite,
DiscordInviteMetadata,
DiscordLobby,
DiscordLobbyMember,
DiscordMember,
DiscordMemberWithUser,
DiscordMessage,
@@ -114,6 +118,7 @@ import type {
InteractionCallbackData,
InteractionCallbackOptions,
InteractionResponse,
LinkChannelToLobby,
ListArchivedThreads,
ListGuildMembers,
ListSkuSubscriptionsOptions,
@@ -128,6 +133,7 @@ import type {
ModifyGuildMember,
ModifyGuildSoundboardSound,
ModifyGuildTemplate,
ModifyLobby,
ModifyRolePositions,
ModifyWebhook,
SearchMembers,
@@ -3174,6 +3180,88 @@ export interface RestManager {
applicationId: BigString,
options: Camelize<DiscordApplicationRoleConnectionMetadata>[],
) => Promise<Camelize<DiscordApplicationRoleConnectionMetadata>[]>
/**
* Creates a new lobby, adding any of the specified members to it, if provided.
*
* @param options - The options to create the lobby
* @returns The created lobby
*/
createLobby: (options: CreateLobby) => Promise<Camelize<DiscordLobby>>
/**
* Returns a lobby object for the specified lobby id, if it exists.
*
* @param lobbyId - The ID of the lobby to get
* @returns The lobby object
*/
getLobby: (lobbyId: BigString) => Promise<Camelize<DiscordLobby>>
/**
* Modifies the specified lobby with new values, if provided.
*
* @param lobbyId - The ID of the lobby to modify
* @param options - The options to modify the lobby
* @returns The modified lobby
*/
modifyLobby: (lobbyId: BigString, options: ModifyLobby) => Promise<Camelize<DiscordLobby>>
/**
* Deletes the specified lobby if it exists.
*
* It is safe to call even if the lobby is already deleted as well.
*
* @param lobbyId - The ID of the lobby to delete
* @returns Nothing
*/
deleteLobby: (lobbyId: BigString) => Promise<void>
/**
* Adds the provided user to the specified lobby. If called when the user is already a member of the lobby will update fields such as metadata on that user instead.
*
* @param lobbyId - The ID of the lobby to add the user to
* @param userId - The ID of the user to add to the lobby
* @param options - The options to add the user to the lobby
* @returns The lobby member object
*/
addMemberToLobby: (lobbyId: BigString, userId: BigString, options: AddLobbyMember) => Promise<Camelize<DiscordLobbyMember>>
/**
* Removes the provided user from the specified lobby. It is safe to call this even if the user is no longer a member of the lobby, but will fail if the lobby does not exist.
*
* @param lobbyId - The ID of the lobby to remove the user from
* @param userId - The ID of the user to remove from the lobby
* @returns Nothing
*/
removeMemberFromLobby: (lobbyId: BigString, userId: BigString) => Promise<void>
/**
* Removes the current user from the specified lobby. It is safe to call this even if the user is no longer a member of the lobby, but will fail if the lobby does not exist.
*
* @param lobbyId - The ID of the lobby to remove the user from
* @param bearerToken - The access token of the user
* @returns Nothing
*
* @remarks
* This requires a bearer token for authorization
*/
leaveLobby: (lobbyId: BigString, bearerToken: string) => Promise<void>
/**
* Links an existing text channel to a lobby.
*
* @param lobbyId - The ID of the lobby to link the channel to
* @param bearerToken - The access token of the user
* @param options - The options to link the channel to the lobby
* @returns The updated lobby object
*
* @remarks
* Uses bearer token for authorization and the user must be a lobby member with the CanLinkLobby lobby member flag.
*/
linkChannelToLobby: (lobbyId: BigString, bearerToken: string, options: LinkChannelToLobby) => Promise<Camelize<DiscordLobby>>
/**
* Unlinks any currently linked channels from the specified lobby.
*
* @param lobbyId - The ID of the lobby to unlink the channel from
* @param bearerToken - The access token of the user
* @returns The updated lobby object
*
* @remarks
* Uses bearer token for authorization and the user must be a lobby member with the CanLinkLobby lobby member flag.
*/
unlinkChannelToLobby: (lobbyId: BigString, bearerToken: string) => Promise<Camelize<DiscordLobby>>
}
export type RequestMethods = 'GET' | 'POST' | 'DELETE' | 'PATCH' | 'PUT'

View File

@@ -297,6 +297,19 @@ export interface RestRoutes {
/** Route for get/edit/delete of a guild sound */
guildSound: (guildId: BigString, soundId: BigString) => string
}
/** Routes realted to lobbies */
lobby: {
/** Route to create a lobby */
create: () => string
/** Route to get a specific lobby */
lobby: (lobbyId: BigString) => string
/** Route to add/remove a member from a lobby */
member: (lobbyId: BigString, userId: BigString) => string
/** Route to leave a lobby */
leave: (lobbyId: BigString) => string
/** Route to link a lobby */
link: (lobbyId: BigString) => string
}
/** Route to list / create an application emoji */
applicationEmojis: (applicationId: BigString) => string
/** Route to list / update application role connection metadata records */

View File

@@ -0,0 +1,33 @@
/** Types for: https://discord.com/developers/docs/resources/lobby */
import type { DiscordChannel } from './channel.js'
/** https://discord.com/developers/docs/resources/lobby#lobby-object-lobby-structure */
export interface DiscordLobby {
/** The id of this channel */
id: string
/** application that created the lobby */
application_id: string
/** dictionary of string key/value pairs. The max total length is 1000. */
metadata?: Record<string, string>
/** members of the lobby */
members: DiscordLobbyMember[]
/** the guild channel linked to the lobby */
linked_channel?: DiscordChannel
}
/** https://discord.com/developers/docs/resources/lobby#lobby-member-object-lobby-member-structure */
export interface DiscordLobbyMember {
/** The id of the user */
id: string
/** dictionary of string key/value pairs. The max total length is 1000. */
metadata?: Record<string, string>
/** lobby member flags combined as as bitfield */
flags?: number
}
/** https://discord.com/developers/docs/resources/lobby#lobby-member-object-lobby-member-flags */
export enum DiscordLobbyMemberFlags {
/** User can link a text channel to a lobby */
CanLinkLobby = 1 << 0,
}

View File

@@ -1690,3 +1690,47 @@ export interface ModifyGuildIncidentActions {
*/
dms_disabled_until?: string | null
}
/** https://discord.com/developers/docs/resources/lobby#create-lobby */
export interface CreateLobby {
/** Optional dictionary of string key/value pairs. The max total length is 1000. */
metadata?: Record<string, string> | null
/** Optional array of up to 25 users to be added to the lobby */
members?: CreateLobbyMember[]
/** Seconds to wait before shutting down a lobby after it becomes idle. Value can be between 5 and 604800 (7 days). */
idleTimeoutSeconds?: number
}
/** https://discord.com/developers/docs/resources/lobby#create-lobby */
export interface CreateLobbyMember {
/** Discord user id of the user to add to the lobby */
id: BigString
/** Optional dictionary of string key/value pairs. The max total length is 1000. */
metadata?: Record<string, string> | null
/** Lobby member flags combined as a bitfield */
flags?: number
}
/** https://discord.com/developers/docs/resources/lobby#add-a-member-to-a-lobby */
export interface ModifyLobby {
/** Optional dictionary of string key/value pairs. The max total length is 1000. Overwrites any existing metadata. */
metadata?: Record<string, string> | null
/** Optional array of up to 25 users to replace the lobby members with. If provided, lobby members not in this list will be removed from the lobby. */
members?: CreateLobbyMember[]
/** Seconds to wait before shutting down a lobby after it becomes idle. Value can be between 5 and 604800 (7 days). */
idleTimeoutSeconds?: number
}
/** https://discord.com/developers/docs/resources/lobby#add-a-member-to-a-lobby */
export interface AddLobbyMember {
/** Optional dictionary of string key/value pairs. The max total length is 1000. */
metadata?: Record<string, string> | null
/** Lobby member flags combined as a bitfield */
flags?: number
}
/** https://discord.com/developers/docs/resources/lobby#link-channel-to-lobby */
export interface LinkChannelToLobby {
/** The id of the channel to link to the lobby. If not provided, will unlink any currently linked channels from the lobby. */
channelId?: BigString
}

View File

@@ -11,6 +11,7 @@ export * from './discord/guildScheduledEvent.js'
export * from './discord/guildTemplate.js'
export * from './discord/interactions.js'
export * from './discord/invite.js'
export * from './discord/lobby.js'
export * from './discord/message.js'
export * from './discord/oauth2.js'
export * from './discord/opcodes.js'