From 7cd14c742a9b9979dca52b56ddded82d7c1a99b9 Mon Sep 17 00:00:00 2001 From: HopeBaron Date: Tue, 7 Sep 2021 09:22:48 +0300 Subject: [PATCH 1/9] add get original response endpoint --- core/src/main/kotlin/Kord.kt | 15 ++++++++-- .../exception/EntityNotFoundException.kt | 28 +++++++++---------- .../kotlin/supplier/RestEntitySupplier.kt | 10 +++++++ rest/src/main/kotlin/route/Route.kt | 7 +++++ .../main/kotlin/service/InteractionService.kt | 8 +++++- 5 files changed, 50 insertions(+), 18 deletions(-) diff --git a/core/src/main/kotlin/Kord.kt b/core/src/main/kotlin/Kord.kt index c28a5570af6a..99f5f16eaaa3 100644 --- a/core/src/main/kotlin/Kord.kt +++ b/core/src/main/kotlin/Kord.kt @@ -64,7 +64,6 @@ class Kord( get() = defaultSupplier.getGlobalApplicationCommands(resources.applicationId) - /** * The default supplier, obtained through Kord's [resources] and configured through [KordBuilder.defaultStrategy]. * By default a strategy from [EntitySupplyStrategy.rest]. @@ -371,6 +370,10 @@ class Kord( return defaultSupplier.getGuildApplicationCommands(resources.applicationId, guildId) } + suspend fun getOriginalInteractionResponse(token: String): Message? { + return EntitySupplyStrategy.rest.supply(this).getOriginalInteractionOrNull(resources.applicationId, token) + } + suspend fun getGuildApplicationCommand(guildId: Snowflake, commandId: Snowflake): GuildApplicationCommand { return defaultSupplier.getGuildApplicationCommand(resources.applicationId, guildId, commandId) } @@ -381,12 +384,18 @@ class Kord( } - suspend inline fun getGuildApplicationCommandOf(guildId: Snowflake, commandId: Snowflake): T { + suspend inline fun getGuildApplicationCommandOf( + guildId: Snowflake, + commandId: Snowflake + ): T { return defaultSupplier.getGuildApplicationCommandOf(resources.applicationId, guildId, commandId) } - suspend inline fun getGuildApplicationCommandOfOrNull(guildId: Snowflake, commandId: Snowflake): T? { + suspend inline fun getGuildApplicationCommandOfOrNull( + guildId: Snowflake, + commandId: Snowflake + ): T? { return defaultSupplier.getGuildApplicationCommandOfOrNull(resources.applicationId, guildId, commandId) } diff --git a/core/src/main/kotlin/exception/EntityNotFoundException.kt b/core/src/main/kotlin/exception/EntityNotFoundException.kt index 846fa8d49187..8f03ae4c4dea 100644 --- a/core/src/main/kotlin/exception/EntityNotFoundException.kt +++ b/core/src/main/kotlin/exception/EntityNotFoundException.kt @@ -40,40 +40,40 @@ class EntityNotFoundException : Exception { inline fun selfNotFound(): Nothing = throw EntityNotFoundException("Self user not found") - fun roleNotFound(guildId: Snowflake, roleId: Snowflake): Nothing = + inline fun roleNotFound(guildId: Snowflake, roleId: Snowflake): Nothing = guildEntityNotFound("Role", guildId = guildId, id = roleId) - fun banNotFound(guildId: Snowflake, userId: Snowflake): Nothing = + inline fun banNotFound(guildId: Snowflake, userId: Snowflake): Nothing = guildEntityNotFound("Ban", guildId = guildId, id = userId) - fun emojiNotFound(guildId: Snowflake, emojiId: Snowflake): Nothing = + inline fun emojiNotFound(guildId: Snowflake, emojiId: Snowflake): Nothing = guildEntityNotFound("GuildEmoji", guildId = guildId, id = emojiId) - fun webhookNotFound(webhookId: Snowflake): Nothing = + inline fun webhookNotFound(webhookId: Snowflake): Nothing = entityNotFound("Webhook", webhookId) - fun inviteNotFound(code: String): Nothing = + inline fun inviteNotFound(code: String): Nothing = throw EntityNotFoundException("Invite with code $code was not found.") - fun widgetNotFound(id: Snowflake): Nothing = + inline fun widgetNotFound(id: Snowflake): Nothing = throw EntityNotFoundException("Widget for guild ${id.value} was not found.") - fun templateNotFound(code: String): Nothing = + inline fun templateNotFound(code: String): Nothing = throw EntityNotFoundException("Template $code was not found.") - fun welcomeScreenNotFound(guildId: Snowflake): Nothing = + inline fun welcomeScreenNotFound(guildId: Snowflake): Nothing = throw EntityNotFoundException("Welcome screen for guild $guildId was not found.") - fun stageInstanceNotFound(channelId: Snowflake): Nothing = - throw EntityNotFoundException("Stage instance for channel $channelId was not found") + inline fun stageInstanceNotFound(channelId: Snowflake): Nothing = + throw EntityNotFoundException("Stage instance for channel $channelId was not found.") - fun applicationCommandPermissionsNotFound(commandId: Snowflake): Nothing = + inline fun applicationCommandPermissionsNotFound(commandId: Snowflake): Nothing = entityNotFound("ApplicationCommand", commandId) inline fun applicationCommandNotFound(commandId: Snowflake): Nothing = entityNotFound(T::class.simpleName!!, commandId) - + inline fun interactionNotFound(token: String): Nothing = + throw EntityNotFoundException("Interaction with token $token was not found.") + } } - -} \ No newline at end of file diff --git a/core/src/main/kotlin/supplier/RestEntitySupplier.kt b/core/src/main/kotlin/supplier/RestEntitySupplier.kt index adac947d2f2f..97f888a8a92d 100644 --- a/core/src/main/kotlin/supplier/RestEntitySupplier.kt +++ b/core/src/main/kotlin/supplier/RestEntitySupplier.kt @@ -434,6 +434,16 @@ class RestEntitySupplier(val kord: Kord) : EntitySupplier { } } + suspend fun getOriginalInteractionOrNull(applicationId: Snowflake, token: String): Message? = catchNotFound { + val response = interaction.getInteractionResponse(applicationId, token) + val data = MessageData.from(response) + Message(data, kord) + } + + + suspend fun getOriginalInteraction(applicationId: Snowflake, token: String): Message { + return getOriginalInteractionOrNull(applicationId, token) ?: EntityNotFoundException.interactionNotFound(token) + } override fun getGuildApplicationCommandPermissions( applicationId: Snowflake, guildId: Snowflake, diff --git a/rest/src/main/kotlin/route/Route.kt b/rest/src/main/kotlin/route/Route.kt index e650ea72213e..483ff974e454 100644 --- a/rest/src/main/kotlin/route/Route.kt +++ b/rest/src/main/kotlin/route/Route.kt @@ -603,6 +603,13 @@ sealed class Route( NoStrategy ) + object OriginalInteractionResponseGet : + Route( + HttpMethod.Get, + "/webhooks/${ApplicationId}/${InteractionToken}/messages/@original", + DiscordMessage.serializer() + ) + object OriginalInteractionResponseModify : Route( HttpMethod.Patch, diff --git a/rest/src/main/kotlin/service/InteractionService.kt b/rest/src/main/kotlin/service/InteractionService.kt index bffa6e85eb3e..170cc6115a17 100644 --- a/rest/src/main/kotlin/service/InteractionService.kt +++ b/rest/src/main/kotlin/service/InteractionService.kt @@ -120,7 +120,13 @@ class InteractionService(requestHandler: RequestHandler) : RestService(requestHa body(InteractionResponseCreateRequest.serializer(), request) } - + suspend fun getInteractionResponse( + applicationId: Snowflake, + interactionToken: String, + ) = call(Route.OriginalInteractionResponseGet) { + keys[Route.ApplicationId] = applicationId + keys[Route.InteractionToken] = interactionToken + } suspend fun modifyInteractionResponse( applicationId: Snowflake, interactionToken: String, From 42394d0683489d72f1e07a897a09dd75161b3f16 Mon Sep 17 00:00:00 2001 From: HopeBaron Date: Tue, 7 Sep 2021 09:30:57 +0300 Subject: [PATCH 2/9] return named file when adding a file to a message --- .../message/create/PersistentMessageCreateBuilder.kt | 8 +++++--- .../message/modify/PersistentMessageModifyBuilder.kt | 10 +++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/rest/src/main/kotlin/builder/message/create/PersistentMessageCreateBuilder.kt b/rest/src/main/kotlin/builder/message/create/PersistentMessageCreateBuilder.kt index 37c818f47590..559e2693be84 100644 --- a/rest/src/main/kotlin/builder/message/create/PersistentMessageCreateBuilder.kt +++ b/rest/src/main/kotlin/builder/message/create/PersistentMessageCreateBuilder.kt @@ -20,14 +20,16 @@ interface PersistentMessageCreateBuilder : MessageCreateBuilder { /** * Adds a file with the [name] and [content] to the attachments. */ - fun addFile(name: String, content: InputStream) { - files += NamedFile(name, content) + fun addFile(name: String, content: InputStream): NamedFile { + val namedFile = NamedFile(name, content) + files += namedFile + return namedFile } /** * Adds a file with the given [path] to the attachments. */ - suspend fun addFile(path: Path) = withContext(Dispatchers.IO) { + suspend fun addFile(path: Path): NamedFile = withContext(Dispatchers.IO) { addFile(path.fileName.toString(), Files.newInputStream(path)) } diff --git a/rest/src/main/kotlin/builder/message/modify/PersistentMessageModifyBuilder.kt b/rest/src/main/kotlin/builder/message/modify/PersistentMessageModifyBuilder.kt index 86256e5e6c29..12a212ab36aa 100644 --- a/rest/src/main/kotlin/builder/message/modify/PersistentMessageModifyBuilder.kt +++ b/rest/src/main/kotlin/builder/message/modify/PersistentMessageModifyBuilder.kt @@ -20,13 +20,17 @@ interface PersistentMessageModifyBuilder : MessageModifyBuilder { var attachments: MutableList? - fun addFile(name: String, content: InputStream) { + fun addFile(name: String, content: InputStream): NamedFile { + val namedFile = NamedFile(name, content) + files = (files ?: mutableListOf()).also { - it.add(NamedFile(name, content)) + it.add(namedFile) } + + return namedFile } - suspend fun addFile(path: Path) = withContext(Dispatchers.IO) { + suspend fun addFile(path: Path): NamedFile = withContext(Dispatchers.IO) { addFile(path.fileName.toString(), Files.newInputStream(path)) } From 01c9e0f952a40f42a16149716c4412157479eccf Mon Sep 17 00:00:00 2001 From: HopeBaron Date: Tue, 7 Sep 2021 09:31:38 +0300 Subject: [PATCH 3/9] remove redundant application id parameter --- core/src/main/kotlin/Kord.kt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/core/src/main/kotlin/Kord.kt b/core/src/main/kotlin/Kord.kt index 99f5f16eaaa3..f194c28a5ba7 100644 --- a/core/src/main/kotlin/Kord.kt +++ b/core/src/main/kotlin/Kord.kt @@ -534,24 +534,22 @@ class Kord( } suspend fun editApplicationCommandPermissions( - applicationId: Snowflake, guildId: Snowflake, commandId: Snowflake, builder: ApplicationCommandPermissionsModifyBuilder.() -> Unit, ) { val request = ApplicationCommandPermissionsModifyBuilder().apply(builder).toRequest() - rest.interaction.editApplicationCommandPermissions(applicationId, guildId, commandId, request) + rest.interaction.editApplicationCommandPermissions(resources.applicationId, guildId, commandId, request) } suspend fun bulkEditApplicationCommandPermissions( - applicationId: Snowflake, guildId: Snowflake, builder: ApplicationCommandPermissionsBulkModifyBuilder.() -> Unit, ) { val request = ApplicationCommandPermissionsBulkModifyBuilder().apply(builder).toRequest() - rest.interaction.bulkEditApplicationCommandPermissions(applicationId, guildId, request) + rest.interaction.bulkEditApplicationCommandPermissions(resources.applicationId, guildId, request) } } From 9013c4b504f3a8daf40474da837827ec2e3bc400 Mon Sep 17 00:00:00 2001 From: HopeBaron Date: Tue, 7 Sep 2021 18:00:31 +0300 Subject: [PATCH 4/9] add rest-level dsl functions --- .../main/kotlin/service/InteractionService.kt | 423 +++++++++++++++++- 1 file changed, 401 insertions(+), 22 deletions(-) diff --git a/rest/src/main/kotlin/service/InteractionService.kt b/rest/src/main/kotlin/service/InteractionService.kt index 170cc6115a17..3b1f7e74cd0b 100644 --- a/rest/src/main/kotlin/service/InteractionService.kt +++ b/rest/src/main/kotlin/service/InteractionService.kt @@ -1,16 +1,23 @@ package dev.kord.rest.service -import dev.kord.common.annotation.KordPreview -import dev.kord.common.entity.DiscordApplicationCommand -import dev.kord.common.entity.DiscordGuildApplicationCommandPermissions -import dev.kord.common.entity.PartialDiscordGuildApplicationCommandPermissions -import dev.kord.common.entity.Snowflake +import dev.kord.common.entity.* import dev.kord.common.entity.optional.orEmpty +import dev.kord.rest.builder.interaction.* +import dev.kord.rest.builder.message.create.EphemeralFollowupMessageCreateBuilder +import dev.kord.rest.builder.message.create.EphemeralInteractionResponseCreateBuilder +import dev.kord.rest.builder.message.create.PublicFollowupMessageCreateBuilder +import dev.kord.rest.builder.message.create.PublicInteractionResponseCreateBuilder +import dev.kord.rest.builder.message.modify.EphemeralFollowupMessageModifyBuilder +import dev.kord.rest.builder.message.modify.EphemeralInteractionResponseModifyBuilder +import dev.kord.rest.builder.message.modify.PublicFollowupMessageModifyBuilder +import dev.kord.rest.builder.message.modify.PublicInteractionResponseModifyBuilder import dev.kord.rest.json.request.* import dev.kord.rest.request.RequestHandler import dev.kord.rest.route.Route import kotlinx.serialization.builtins.ListSerializer -import kotlinx.serialization.serializer +import kotlin.contracts.ExperimentalContracts +import kotlin.contracts.InvocationKind +import kotlin.contracts.contract class InteractionService(requestHandler: RequestHandler) : RestService(requestHandler) { @@ -27,7 +34,6 @@ class InteractionService(requestHandler: RequestHandler) : RestService(requestHa body(ApplicationCommandCreateRequest.serializer(), request) } - suspend fun createGlobalApplicationCommands( applicationId: Snowflake, request: List @@ -127,6 +133,7 @@ class InteractionService(requestHandler: RequestHandler) : RestService(requestHa keys[Route.ApplicationId] = applicationId keys[Route.InteractionToken] = interactionToken } + suspend fun modifyInteractionResponse( applicationId: Snowflake, interactionToken: String, @@ -163,7 +170,7 @@ class InteractionService(requestHandler: RequestHandler) : RestService(requestHa keys[Route.ApplicationId] = applicationId keys[Route.InteractionToken] = interactionToken body(FollowupMessageCreateRequest.serializer(), multipart.request) - multipart.files.orEmpty().forEach { file(it) } + multipart.files.forEach { file(it) } } @@ -207,24 +214,25 @@ class InteractionService(requestHandler: RequestHandler) : RestService(requestHa } - suspend fun getGuildCommand(applicationId: Snowflake, guildId: Snowflake, commandId: Snowflake) = call(Route.GuildApplicationCommandGet){ - keys[Route.ApplicationId] = applicationId - keys[Route.GuildId] = guildId - keys[Route.CommandId] = commandId - } + suspend fun getGuildCommand(applicationId: Snowflake, guildId: Snowflake, commandId: Snowflake) = + call(Route.GuildApplicationCommandGet) { + keys[Route.ApplicationId] = applicationId + keys[Route.GuildId] = guildId + keys[Route.CommandId] = commandId + } suspend fun getGuildApplicationCommandPermissions( - applicationId: Snowflake, - guildId: Snowflake, + applicationId: Snowflake, + guildId: Snowflake, ): List = call(Route.GuildApplicationCommandPermissionsGet) { keys[Route.ApplicationId] = applicationId keys[Route.GuildId] = guildId } suspend fun getApplicationCommandPermissions( - applicationId: Snowflake, - guildId: Snowflake, - commandId: Snowflake, + applicationId: Snowflake, + guildId: Snowflake, + commandId: Snowflake, ): DiscordGuildApplicationCommandPermissions = call(Route.ApplicationCommandPermissionsGet) { keys[Route.ApplicationId] = applicationId keys[Route.GuildId] = guildId @@ -232,10 +240,10 @@ class InteractionService(requestHandler: RequestHandler) : RestService(requestHa } suspend fun editApplicationCommandPermissions( - applicationId: Snowflake, - guildId: Snowflake, - commandId: Snowflake, - request: ApplicationCommandPermissionsEditRequest, + applicationId: Snowflake, + guildId: Snowflake, + commandId: Snowflake, + request: ApplicationCommandPermissionsEditRequest, ) = call(Route.ApplicationCommandPermissionsPut) { keys[Route.ApplicationId] = applicationId keys[Route.GuildId] = guildId @@ -254,4 +262,375 @@ class InteractionService(requestHandler: RequestHandler) : RestService(requestHa body(ListSerializer(PartialDiscordGuildApplicationCommandPermissions.serializer()), request) } + + + @OptIn(ExperimentalContracts::class) + suspend fun createGlobalChatInputApplicationCommand( + applicationId: Snowflake, + name: String, + description: String, + builder: ChatInputCreateBuilder.() -> Unit = {} + ): DiscordApplicationCommand { + contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } + return createGlobalApplicationCommand( + applicationId, + ChatInputCreateBuilder(name, description).apply(builder).toRequest() + ) + } + + + @OptIn(ExperimentalContracts::class) + suspend fun createGlobalMessageCommandApplicationCommand( + applicationId: Snowflake, + name: String, + builder: MessageCommandCreateBuilder.() -> Unit = {} + ): DiscordApplicationCommand { + + contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } + + return createGlobalApplicationCommand( + applicationId, + MessageCommandCreateBuilder(name).apply(builder).toRequest() + ) + } + + @OptIn(ExperimentalContracts::class) + suspend fun createGlobalUserCommandApplicationCommand( + applicationId: Snowflake, + name: String, + builder: UserCommandCreateBuilder.() -> Unit = {} + ): DiscordApplicationCommand { + + contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } + + return createGlobalApplicationCommand( + applicationId, + UserCommandCreateBuilder(name).apply(builder).toRequest() + ) + } + + @OptIn(ExperimentalContracts::class) + suspend inline fun createGlobalApplicationCommands( + applicationId: Snowflake, + builder: MultiApplicationCommandBuilder.() -> Unit + ): List { + + contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } + + return createGlobalApplicationCommands( + applicationId, + MultiApplicationCommandBuilder().apply(builder).build() + ) + } + + @OptIn(ExperimentalContracts::class) + suspend fun modifyGlobalChatInputApplicationCommand( + applicationId: Snowflake, + commandId: Snowflake, + builder: ChatInputModifyBuilder.() -> Unit + ): DiscordApplicationCommand { + contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } + + return modifyGlobalApplicationCommand( + applicationId, + commandId, + ChatInputModifyBuilder().apply(builder).toRequest() + ) + } + + + @OptIn(ExperimentalContracts::class) + suspend fun modifyGlobalMessageApplicationCommand( + applicationId: Snowflake, + commandId: Snowflake, + builder: MessageCommandModifyBuilder.() -> Unit + ): DiscordApplicationCommand { + contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } + + return modifyGlobalApplicationCommand( + applicationId, + commandId, + MessageCommandModifyBuilder().apply(builder).toRequest() + ) + } + + @OptIn(ExperimentalContracts::class) + suspend fun modifyGlobalUserApplicationCommand( + applicationId: Snowflake, + commandId: Snowflake, + builder: UserCommandModifyBuilder.() -> Unit + ): DiscordApplicationCommand { + contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } + return modifyGlobalApplicationCommand( + applicationId, + commandId, + UserCommandModifyBuilder().apply(builder).toRequest() + ) + } + + + + @OptIn(ExperimentalContracts::class) + suspend fun createGuildChatInputApplicationCommand( + applicationId: Snowflake, + guildId: Snowflake, + name: String, + description: String, + builder: ChatInputCreateBuilder.() -> Unit = {} + ): DiscordApplicationCommand { + contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } + return createGuildApplicationCommand( + applicationId, + guildId, + ChatInputCreateBuilder(name, description).apply(builder).toRequest() + ) + } + + + @OptIn(ExperimentalContracts::class) + suspend fun createGuildMessageCommandApplicationCommand( + applicationId: Snowflake, + guildId: Snowflake, + name: String, + builder: MessageCommandCreateBuilder.() -> Unit = {} + ): DiscordApplicationCommand { + + contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } + + return createGuildApplicationCommand( + applicationId, + guildId, + MessageCommandCreateBuilder(name).apply(builder).toRequest() + ) + } + + @OptIn(ExperimentalContracts::class) + suspend fun createGuildUserCommandApplicationCommand( + applicationId: Snowflake, + guildId: Snowflake, + name: String, + builder: UserCommandCreateBuilder.() -> Unit = {} + ): DiscordApplicationCommand { + + contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } + + return createGuildApplicationCommand( + applicationId, + guildId, + UserCommandCreateBuilder(name).apply(builder).toRequest() + ) + } + + @OptIn(ExperimentalContracts::class) + suspend inline fun createGuildApplicationCommands( + applicationId: Snowflake, + guildId: Snowflake, + builder: MultiApplicationCommandBuilder.() -> Unit + ): List { + + contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } + + return createGuildApplicationCommands( + applicationId, + guildId, + MultiApplicationCommandBuilder().apply(builder).build() + ) + } + + @OptIn(ExperimentalContracts::class) + suspend fun modifyGuildChatInputApplicationCommand( + applicationId: Snowflake, + guildId: Snowflake, + commandId: Snowflake, + builder: ChatInputModifyBuilder.() -> Unit + ): DiscordApplicationCommand { + contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } + + return modifyGuildApplicationCommand( + applicationId, + guildId, + commandId, + ChatInputModifyBuilder().apply(builder).toRequest() + ) + } + + + @OptIn(ExperimentalContracts::class) + suspend fun modifyGuildMessageApplicationCommand( + applicationId: Snowflake, + guildId: Snowflake, + commandId: Snowflake, + builder: MessageCommandModifyBuilder.() -> Unit + ): DiscordApplicationCommand { + contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } + + return modifyGuildApplicationCommand( + applicationId, + guildId, + commandId, + MessageCommandModifyBuilder().apply(builder).toRequest() + ) + } + + @OptIn(ExperimentalContracts::class) + suspend fun modifyGuildUserApplicationCommand( + applicationId: Snowflake, + guildId: Snowflake, + commandId: Snowflake, + builder: UserCommandModifyBuilder.() -> Unit + ): DiscordApplicationCommand { + contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } + return modifyGuildApplicationCommand( + applicationId, + guildId, + commandId, + UserCommandModifyBuilder().apply(builder).toRequest() + ) + } + + + suspend fun createPublicInteractionResponse( + interactionId: Snowflake, + interactionToken: String, + builder: PublicInteractionResponseCreateBuilder.() -> Unit + ) { + return createInteractionResponse( + interactionId, + interactionToken, + PublicInteractionResponseCreateBuilder().apply(builder).toRequest() + ) + } + + + suspend fun createEphemeralInteractionResponse( + interactionId: Snowflake, + interactionToken: String, + builder: EphemeralInteractionResponseCreateBuilder.() -> Unit + ) { + return createInteractionResponse( + interactionId, + interactionToken, + EphemeralInteractionResponseCreateBuilder().apply(builder).toRequest() + ) + } + + @OptIn(ExperimentalContracts::class) + suspend fun modifyPublicInteractionResponse( + applicationId: Snowflake, + interactionToken: String, + builder: PublicInteractionResponseModifyBuilder.() -> Unit + ): DiscordMessage { + contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } + return modifyInteractionResponse( + applicationId, + interactionToken, + PublicInteractionResponseModifyBuilder().apply(builder).toRequest() + ) + } + + @OptIn(ExperimentalContracts::class) + suspend fun modifyEphemeralInteractionResponse( + applicationId: Snowflake, + interactionToken: String, + builder: EphemeralInteractionResponseModifyBuilder.() -> Unit + ): DiscordMessage { + contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } + return modifyInteractionResponse( + applicationId, + interactionToken, + EphemeralInteractionResponseModifyBuilder().apply(builder).toRequest() + ) + } + + @OptIn(ExperimentalContracts::class) + suspend fun createEphemeralFollowupMessage( + applicationId: Snowflake, + interactionToken: String, + builder: EphemeralFollowupMessageCreateBuilder.() -> Unit + ): DiscordMessage { + contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } + return createFollowupMessage( + applicationId, + interactionToken, + EphemeralFollowupMessageCreateBuilder().apply(builder).toRequest() + ) + } + + @OptIn(ExperimentalContracts::class) + suspend fun createFollowupMessage( + applicationId: Snowflake, + interactionToken: String, + builder: PublicFollowupMessageCreateBuilder.() -> Unit + ): DiscordMessage { + contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } + return createFollowupMessage( + applicationId, + interactionToken, + PublicFollowupMessageCreateBuilder().apply(builder).toRequest() + ) + } + + @OptIn(ExperimentalContracts::class) + suspend fun modifyPublicFollowupMessage( + applicationId: Snowflake, + interactionToken: String, + messageId: Snowflake, + builder: PublicFollowupMessageModifyBuilder.() -> Unit = {} + ): DiscordMessage { + contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } + return modifyFollowupMessage( + applicationId, + interactionToken, + messageId, + PublicFollowupMessageModifyBuilder().apply(builder).toRequest() + ) + } + + + @OptIn(ExperimentalContracts::class) + suspend fun modifyEphemeralFollowupMessage( + applicationId: Snowflake, + interactionToken: String, + messageId: Snowflake, + builder: EphemeralFollowupMessageModifyBuilder.() -> Unit = {} + ): DiscordMessage { + contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } + return modifyFollowupMessage( + applicationId, + interactionToken, + messageId, + EphemeralFollowupMessageModifyBuilder().apply(builder).toRequest() + ) + } + + @OptIn(ExperimentalContracts::class) + suspend inline fun bulkEditApplicationCommandPermissions( + applicationId: Snowflake, + guildId: Snowflake, + builder: ApplicationCommandPermissionsBulkModifyBuilder.() -> Unit = {} + ): List { + contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } + return bulkEditApplicationCommandPermissions( + applicationId, + guildId, + ApplicationCommandPermissionsBulkModifyBuilder().apply(builder).toRequest() + ) + } + + @OptIn(ExperimentalContracts::class) + suspend inline fun editApplicationCommandPermissions( + applicationId: Snowflake, + guildId: Snowflake, + commandId: Snowflake, + builder: ApplicationCommandPermissionsModifyBuilder.() -> Unit + ): DiscordGuildApplicationCommandPermissions { + contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } + return editApplicationCommandPermissions( + applicationId, + guildId, + commandId, + ApplicationCommandPermissionsModifyBuilder().apply(builder).toRequest() + ) + } + } From 0b24316e343891541730655b4bf4eea9b08ec5a5 Mon Sep 17 00:00:00 2001 From: HopeBaron Date: Tue, 7 Sep 2021 18:06:16 +0300 Subject: [PATCH 5/9] inline dsls --- .../main/kotlin/service/InteractionService.kt | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/rest/src/main/kotlin/service/InteractionService.kt b/rest/src/main/kotlin/service/InteractionService.kt index 3b1f7e74cd0b..e7d3994e46df 100644 --- a/rest/src/main/kotlin/service/InteractionService.kt +++ b/rest/src/main/kotlin/service/InteractionService.kt @@ -265,7 +265,7 @@ class InteractionService(requestHandler: RequestHandler) : RestService(requestHa @OptIn(ExperimentalContracts::class) - suspend fun createGlobalChatInputApplicationCommand( + suspend inline fun createGlobalChatInputApplicationCommand( applicationId: Snowflake, name: String, description: String, @@ -280,7 +280,7 @@ class InteractionService(requestHandler: RequestHandler) : RestService(requestHa @OptIn(ExperimentalContracts::class) - suspend fun createGlobalMessageCommandApplicationCommand( + suspend inline fun createGlobalMessageCommandApplicationCommand( applicationId: Snowflake, name: String, builder: MessageCommandCreateBuilder.() -> Unit = {} @@ -295,7 +295,7 @@ class InteractionService(requestHandler: RequestHandler) : RestService(requestHa } @OptIn(ExperimentalContracts::class) - suspend fun createGlobalUserCommandApplicationCommand( + suspend inline fun createGlobalUserCommandApplicationCommand( applicationId: Snowflake, name: String, builder: UserCommandCreateBuilder.() -> Unit = {} @@ -324,7 +324,7 @@ class InteractionService(requestHandler: RequestHandler) : RestService(requestHa } @OptIn(ExperimentalContracts::class) - suspend fun modifyGlobalChatInputApplicationCommand( + suspend inline fun modifyGlobalChatInputApplicationCommand( applicationId: Snowflake, commandId: Snowflake, builder: ChatInputModifyBuilder.() -> Unit @@ -340,7 +340,7 @@ class InteractionService(requestHandler: RequestHandler) : RestService(requestHa @OptIn(ExperimentalContracts::class) - suspend fun modifyGlobalMessageApplicationCommand( + suspend inline fun modifyGlobalMessageApplicationCommand( applicationId: Snowflake, commandId: Snowflake, builder: MessageCommandModifyBuilder.() -> Unit @@ -355,7 +355,7 @@ class InteractionService(requestHandler: RequestHandler) : RestService(requestHa } @OptIn(ExperimentalContracts::class) - suspend fun modifyGlobalUserApplicationCommand( + suspend inline fun modifyGlobalUserApplicationCommand( applicationId: Snowflake, commandId: Snowflake, builder: UserCommandModifyBuilder.() -> Unit @@ -371,7 +371,7 @@ class InteractionService(requestHandler: RequestHandler) : RestService(requestHa @OptIn(ExperimentalContracts::class) - suspend fun createGuildChatInputApplicationCommand( + suspend inline fun createGuildChatInputApplicationCommand( applicationId: Snowflake, guildId: Snowflake, name: String, @@ -388,7 +388,7 @@ class InteractionService(requestHandler: RequestHandler) : RestService(requestHa @OptIn(ExperimentalContracts::class) - suspend fun createGuildMessageCommandApplicationCommand( + suspend inline fun createGuildMessageCommandApplicationCommand( applicationId: Snowflake, guildId: Snowflake, name: String, @@ -405,7 +405,7 @@ class InteractionService(requestHandler: RequestHandler) : RestService(requestHa } @OptIn(ExperimentalContracts::class) - suspend fun createGuildUserCommandApplicationCommand( + suspend inline fun createGuildUserCommandApplicationCommand( applicationId: Snowflake, guildId: Snowflake, name: String, @@ -438,7 +438,7 @@ class InteractionService(requestHandler: RequestHandler) : RestService(requestHa } @OptIn(ExperimentalContracts::class) - suspend fun modifyGuildChatInputApplicationCommand( + suspend inline fun modifyGuildChatInputApplicationCommand( applicationId: Snowflake, guildId: Snowflake, commandId: Snowflake, @@ -456,7 +456,7 @@ class InteractionService(requestHandler: RequestHandler) : RestService(requestHa @OptIn(ExperimentalContracts::class) - suspend fun modifyGuildMessageApplicationCommand( + suspend inline fun modifyGuildMessageApplicationCommand( applicationId: Snowflake, guildId: Snowflake, commandId: Snowflake, @@ -473,7 +473,7 @@ class InteractionService(requestHandler: RequestHandler) : RestService(requestHa } @OptIn(ExperimentalContracts::class) - suspend fun modifyGuildUserApplicationCommand( + suspend inline fun modifyGuildUserApplicationCommand( applicationId: Snowflake, guildId: Snowflake, commandId: Snowflake, @@ -489,7 +489,7 @@ class InteractionService(requestHandler: RequestHandler) : RestService(requestHa } - suspend fun createPublicInteractionResponse( + suspend inline fun createPublicInteractionResponse( interactionId: Snowflake, interactionToken: String, builder: PublicInteractionResponseCreateBuilder.() -> Unit @@ -502,7 +502,7 @@ class InteractionService(requestHandler: RequestHandler) : RestService(requestHa } - suspend fun createEphemeralInteractionResponse( + suspend inline fun createEphemeralInteractionResponse( interactionId: Snowflake, interactionToken: String, builder: EphemeralInteractionResponseCreateBuilder.() -> Unit @@ -515,7 +515,7 @@ class InteractionService(requestHandler: RequestHandler) : RestService(requestHa } @OptIn(ExperimentalContracts::class) - suspend fun modifyPublicInteractionResponse( + suspend inline fun modifyPublicInteractionResponse( applicationId: Snowflake, interactionToken: String, builder: PublicInteractionResponseModifyBuilder.() -> Unit @@ -529,7 +529,7 @@ class InteractionService(requestHandler: RequestHandler) : RestService(requestHa } @OptIn(ExperimentalContracts::class) - suspend fun modifyEphemeralInteractionResponse( + suspend inline fun modifyEphemeralInteractionResponse( applicationId: Snowflake, interactionToken: String, builder: EphemeralInteractionResponseModifyBuilder.() -> Unit @@ -543,7 +543,7 @@ class InteractionService(requestHandler: RequestHandler) : RestService(requestHa } @OptIn(ExperimentalContracts::class) - suspend fun createEphemeralFollowupMessage( + suspend inline fun createEphemeralFollowupMessage( applicationId: Snowflake, interactionToken: String, builder: EphemeralFollowupMessageCreateBuilder.() -> Unit @@ -557,7 +557,7 @@ class InteractionService(requestHandler: RequestHandler) : RestService(requestHa } @OptIn(ExperimentalContracts::class) - suspend fun createFollowupMessage( + suspend inline fun createFollowupMessage( applicationId: Snowflake, interactionToken: String, builder: PublicFollowupMessageCreateBuilder.() -> Unit @@ -571,7 +571,7 @@ class InteractionService(requestHandler: RequestHandler) : RestService(requestHa } @OptIn(ExperimentalContracts::class) - suspend fun modifyPublicFollowupMessage( + suspend inline fun modifyPublicFollowupMessage( applicationId: Snowflake, interactionToken: String, messageId: Snowflake, @@ -588,7 +588,7 @@ class InteractionService(requestHandler: RequestHandler) : RestService(requestHa @OptIn(ExperimentalContracts::class) - suspend fun modifyEphemeralFollowupMessage( + suspend inline fun modifyEphemeralFollowupMessage( applicationId: Snowflake, interactionToken: String, messageId: Snowflake, From 010179160db393dc69929c0a1f62910aa8fc88db Mon Sep 17 00:00:00 2001 From: HopeBaron Date: Wed, 8 Sep 2021 14:55:18 +0300 Subject: [PATCH 6/9] use rest builders in core --- core/src/main/kotlin/Kord.kt | 64 ++++++++++++------- .../src/main/kotlin/behavior/GuildBehavior.kt | 11 +--- 2 files changed, 45 insertions(+), 30 deletions(-) diff --git a/core/src/main/kotlin/Kord.kt b/core/src/main/kotlin/Kord.kt index f194c28a5ba7..580f73169e81 100644 --- a/core/src/main/kotlin/Kord.kt +++ b/core/src/main/kotlin/Kord.kt @@ -427,8 +427,12 @@ class Kord( builder: ChatInputCreateBuilder.() -> Unit = {}, ): GlobalChatInputCommand { contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } - val request = ChatInputCreateBuilder(name, description).apply(builder).toRequest() - val response = rest.interaction.createGlobalApplicationCommand(resources.applicationId, request) + val response = rest.interaction.createGlobalChatInputApplicationCommand( + resources.applicationId, + name, + description, + builder + ) val data = ApplicationCommandData.from(response) return GlobalChatInputCommand(data, rest.interaction) } @@ -451,8 +455,8 @@ class Kord( builder: UserCommandCreateBuilder.() -> Unit = {}, ): GlobalUserCommand { contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } - val request = UserCommandCreateBuilder(name).apply(builder).toRequest() - val response = rest.interaction.createGlobalApplicationCommand(resources.applicationId, request) + val response = + rest.interaction.createGlobalUserCommandApplicationCommand(resources.applicationId, name, builder) val data = ApplicationCommandData.from(response) return GlobalUserCommand(data, rest.interaction) } @@ -464,8 +468,7 @@ class Kord( ): Flow { contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } - val request = MultiApplicationCommandBuilder().apply(builder).build() - val commands = rest.interaction.createGlobalApplicationCommands(resources.applicationId, request) + val commands = rest.interaction.createGlobalApplicationCommands(resources.applicationId, builder) return flow { commands.forEach { val data = ApplicationCommandData.from(it) @@ -482,8 +485,14 @@ class Kord( builder: ChatInputCreateBuilder.() -> Unit = {}, ): GuildChatInputCommand { contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } - val request = ChatInputCreateBuilder(name, description).apply(builder).toRequest() - val response = rest.interaction.createGuildApplicationCommand(resources.applicationId, guildId, request) + val response = + rest.interaction.createGuildChatInputApplicationCommand( + resources.applicationId, + guildId, + name, + description, + builder + ) val data = ApplicationCommandData.from(response) return GuildChatInputCommand(data, rest.interaction) } @@ -496,8 +505,12 @@ class Kord( builder: MessageCommandCreateBuilder.() -> Unit = {}, ): GuildMessageCommand { contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } - val request = MessageCommandCreateBuilder(name).apply(builder).toRequest() - val response = rest.interaction.createGuildApplicationCommand(resources.applicationId, guildId, request) + val response = rest.interaction.createGuildMessageCommandApplicationCommand( + resources.applicationId, + guildId, + name, + builder + ) val data = ApplicationCommandData.from(response) return GuildMessageCommand(data, rest.interaction) } @@ -509,8 +522,13 @@ class Kord( builder: UserCommandCreateBuilder.() -> Unit = {}, ): GuildUserCommand { contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } - val request = UserCommandCreateBuilder(name).apply(builder).toRequest() - val response = rest.interaction.createGuildApplicationCommand(resources.applicationId, guildId, request) + val response = rest.interaction.createGuildUserCommandApplicationCommand( + resources.applicationId, + guildId, + name, + builder + ) + val data = ApplicationCommandData.from(response) return GuildUserCommand(data, rest.interaction) } @@ -522,9 +540,9 @@ class Kord( builder: MultiApplicationCommandBuilder.() -> Unit, ): Flow { contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } - val request = MultiApplicationCommandBuilder().apply(builder).build() - val commands = rest.interaction.createGuildApplicationCommands(resources.applicationId, guildId, request) + val commands = rest.interaction.createGuildApplicationCommands(resources.applicationId, guildId, builder) + return flow { commands.forEach { val data = ApplicationCommandData.from(it) @@ -533,25 +551,27 @@ class Kord( } } - suspend fun editApplicationCommandPermissions( + @OptIn(ExperimentalContracts::class) + suspend inline fun editApplicationCommandPermissions( guildId: Snowflake, commandId: Snowflake, builder: ApplicationCommandPermissionsModifyBuilder.() -> Unit, ) { - val request = ApplicationCommandPermissionsModifyBuilder().apply(builder).toRequest() - - rest.interaction.editApplicationCommandPermissions(resources.applicationId, guildId, commandId, request) + contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } + rest.interaction.editApplicationCommandPermissions(resources.applicationId, guildId, commandId, builder) } - suspend fun bulkEditApplicationCommandPermissions( + + @OptIn(ExperimentalContracts::class) + suspend inline fun bulkEditApplicationCommandPermissions( guildId: Snowflake, builder: ApplicationCommandPermissionsBulkModifyBuilder.() -> Unit, ) { - val request = ApplicationCommandPermissionsBulkModifyBuilder().apply(builder).toRequest() - - rest.interaction.bulkEditApplicationCommandPermissions(resources.applicationId, guildId, request) + contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } + rest.interaction.bulkEditApplicationCommandPermissions(resources.applicationId, guildId, builder) } + } /** diff --git a/core/src/main/kotlin/behavior/GuildBehavior.kt b/core/src/main/kotlin/behavior/GuildBehavior.kt index d387d7b7a722..436c4deb6122 100644 --- a/core/src/main/kotlin/behavior/GuildBehavior.kt +++ b/core/src/main/kotlin/behavior/GuildBehavior.kt @@ -978,13 +978,8 @@ inline fun GuildBehavior.requestMembers(builder: RequestGuildMembersBuilder.() - @OptIn(ExperimentalContracts::class) suspend inline fun GuildBehavior.bulkEditSlashCommandPermissions(noinline builder: ApplicationCommandPermissionsBulkModifyBuilder.() -> Unit) { - contract { - callsInPlace(builder, InvocationKind.EXACTLY_ONCE) - } - kord.bulkEditApplicationCommandPermissions( - kord.selfId, - id, - builder - ) + contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } + + kord.bulkEditApplicationCommandPermissions(id, builder) } From f2319625cb0df01dd91522ee4b1821d846facd75 Mon Sep 17 00:00:00 2001 From: HopeBaron Date: Sun, 12 Sep 2021 11:49:59 +0300 Subject: [PATCH 7/9] move original interaction getter function to interaction behavior --- core/src/main/kotlin/Kord.kt | 4 ---- .../main/kotlin/behavior/interaction/InteractionBehavior.kt | 5 +++++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/core/src/main/kotlin/Kord.kt b/core/src/main/kotlin/Kord.kt index 580f73169e81..cbec8526cdf7 100644 --- a/core/src/main/kotlin/Kord.kt +++ b/core/src/main/kotlin/Kord.kt @@ -370,10 +370,6 @@ class Kord( return defaultSupplier.getGuildApplicationCommands(resources.applicationId, guildId) } - suspend fun getOriginalInteractionResponse(token: String): Message? { - return EntitySupplyStrategy.rest.supply(this).getOriginalInteractionOrNull(resources.applicationId, token) - } - suspend fun getGuildApplicationCommand(guildId: Snowflake, commandId: Snowflake): GuildApplicationCommand { return defaultSupplier.getGuildApplicationCommand(resources.applicationId, guildId, commandId) } diff --git a/core/src/main/kotlin/behavior/interaction/InteractionBehavior.kt b/core/src/main/kotlin/behavior/interaction/InteractionBehavior.kt index 1cfc3fd24288..e94f88e80a2c 100644 --- a/core/src/main/kotlin/behavior/interaction/InteractionBehavior.kt +++ b/core/src/main/kotlin/behavior/interaction/InteractionBehavior.kt @@ -9,6 +9,7 @@ import dev.kord.common.entity.optional.* import dev.kord.core.Kord import dev.kord.core.behavior.channel.MessageChannelBehavior import dev.kord.core.entity.KordEntity +import dev.kord.core.entity.Message import dev.kord.core.entity.Strategizable import dev.kord.core.entity.channel.MessageChannel import dev.kord.core.supplier.EntitySupplier @@ -76,6 +77,10 @@ interface InteractionBehavior : KordEntity, Strategizable { } + suspend fun getOriginalInteractionResponse(): Message? { + return EntitySupplyStrategy.rest.supply(kord).getOriginalInteractionOrNull(applicationId, token) + } + override fun withStrategy(strategy: EntitySupplyStrategy<*>): InteractionBehavior = InteractionBehavior(id, channelId, token, applicationId, kord, strategy) From f43ff63a7cfcd6c29ae15b95824b6121b0b032a1 Mon Sep 17 00:00:00 2001 From: HopeBaron Date: Sun, 12 Sep 2021 13:49:18 +0300 Subject: [PATCH 8/9] Add new properties --- common/src/main/kotlin/entity/Interactions.kt | 3 ++- .../src/main/kotlin/cache/data/ApplicationCommandData.kt | 9 +++++++-- .../main/kotlin/entity/application/ApplicationCommand.kt | 4 ++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/common/src/main/kotlin/entity/Interactions.kt b/common/src/main/kotlin/entity/Interactions.kt index 21f5c968d800..d5c975d1163f 100644 --- a/common/src/main/kotlin/entity/Interactions.kt +++ b/common/src/main/kotlin/entity/Interactions.kt @@ -26,7 +26,8 @@ data class DiscordApplicationCommand( val guildId: OptionalSnowflake = OptionalSnowflake.Missing, val options: Optional> = Optional.Missing(), @SerialName("default_permission") - val defaultPermission: OptionalBoolean = OptionalBoolean.Missing + val defaultPermission: OptionalBoolean = OptionalBoolean.Missing, + val version: Snowflake ) @Serializable(with = ApplicationCommandType.Serializer::class) diff --git a/core/src/main/kotlin/cache/data/ApplicationCommandData.kt b/core/src/main/kotlin/cache/data/ApplicationCommandData.kt index b30cb3c656b9..1039e67cbb62 100644 --- a/core/src/main/kotlin/cache/data/ApplicationCommandData.kt +++ b/core/src/main/kotlin/cache/data/ApplicationCommandData.kt @@ -15,7 +15,9 @@ data class ApplicationCommandData( val name: String, val description: String, val guildId: OptionalSnowflake, - val options: Optional> + val options: Optional>, + val defaultPermission: OptionalBoolean = OptionalBoolean.Missing, + val version: Snowflake ) { companion object { val description = description(ApplicationCommandData::id) { @@ -30,7 +32,10 @@ data class ApplicationCommandData( name, description, guildId, - options.mapList { ApplicationCommandOptionData.from(it) }) + options.mapList { ApplicationCommandOptionData.from(it) }, + defaultPermission, + version + ) } } } diff --git a/core/src/main/kotlin/entity/application/ApplicationCommand.kt b/core/src/main/kotlin/entity/application/ApplicationCommand.kt index 815260883901..c97eb9cbe00e 100644 --- a/core/src/main/kotlin/entity/application/ApplicationCommand.kt +++ b/core/src/main/kotlin/entity/application/ApplicationCommand.kt @@ -29,6 +29,10 @@ sealed interface ApplicationCommand : ApplicationCommandBehavior { val name: String get() = data.name + val version: Snowflake get() = data.version + + val defaultPermission: Boolean? get() = data.defaultPermission.discordBoolean + } From 6223be657221f6aabbefab43aee7fe8742809a16 Mon Sep 17 00:00:00 2001 From: HopeBaron Date: Mon, 13 Sep 2021 07:18:05 +0300 Subject: [PATCH 9/9] document unclear property names --- .../main/kotlin/entity/application/ApplicationCommand.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/src/main/kotlin/entity/application/ApplicationCommand.kt b/core/src/main/kotlin/entity/application/ApplicationCommand.kt index c97eb9cbe00e..15f4bc527b05 100644 --- a/core/src/main/kotlin/entity/application/ApplicationCommand.kt +++ b/core/src/main/kotlin/entity/application/ApplicationCommand.kt @@ -29,8 +29,14 @@ sealed interface ApplicationCommand : ApplicationCommandBehavior { val name: String get() = data.name + /** + * auto-incrementing version identifier updated during substantial record changes. + */ val version: Snowflake get() = data.version + /** + * whether the command is enabled by default when the app is added to a guild. + */ val defaultPermission: Boolean? get() = data.defaultPermission.discordBoolean