From 46ce2220e4b9cbc8d13e8065dccfad988b95b824 Mon Sep 17 00:00:00 2001 From: HopeBaron Date: Tue, 11 May 2021 16:11:58 +0300 Subject: [PATCH 1/8] Expose the creation of application commands behavior --- core/src/main/kotlin/Unsafe.kt | 17 ++++++++++ .../GlobalApplicationCommandBehavior.kt | 33 +++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/core/src/main/kotlin/Unsafe.kt b/core/src/main/kotlin/Unsafe.kt index dc3edb0017e0..b09c1e206ba3 100644 --- a/core/src/main/kotlin/Unsafe.kt +++ b/core/src/main/kotlin/Unsafe.kt @@ -6,6 +6,7 @@ import dev.kord.common.annotation.KordUnsafe import dev.kord.common.entity.Snowflake import dev.kord.core.behavior.* import dev.kord.core.behavior.channel.* +import dev.kord.rest.service.InteractionService /** * A class that exposes the creation of `{Entity}Behavior` classes. @@ -71,4 +72,20 @@ class Unsafe(private val kord: Kord) { return "Unsafe" } + fun guildApplicationCommand( + guildId: Snowflake, + applicationId: Snowflake, + commandId: Snowflake, + service: InteractionService = kord.rest.interaction + ): GuildApplicationCommandBehavior = + GuildApplicationCommandBehavior(guildId, applicationId, commandId, service) + + fun globalApplicationCommand( + applicationId: Snowflake, + commandId: Snowflake, + service: InteractionService = kord.rest.interaction + ): GlobalApplicationCommandBehavior = + GlobalApplicationCommandBehavior(applicationId, commandId, service) + + } \ No newline at end of file diff --git a/core/src/main/kotlin/behavior/GlobalApplicationCommandBehavior.kt b/core/src/main/kotlin/behavior/GlobalApplicationCommandBehavior.kt index 9c3168ed4a0d..72a0d953b6e5 100644 --- a/core/src/main/kotlin/behavior/GlobalApplicationCommandBehavior.kt +++ b/core/src/main/kotlin/behavior/GlobalApplicationCommandBehavior.kt @@ -79,4 +79,37 @@ interface GuildApplicationCommandBehavior : ApplicationCommandBehavior { override suspend fun delete() { service.deleteGuildApplicationCommand(applicationId, guildId, id) } + +} + +@KordPreview +fun GuildApplicationCommandBehavior( + guildId: Snowflake, + applicationId: Snowflake, + id: Snowflake, + service: InteractionService +): GuildApplicationCommandBehavior = object : GuildApplicationCommandBehavior { + override val guildId: Snowflake + get() = guildId + override val applicationId: Snowflake + get() = applicationId + override val service: InteractionService + get() = service + override val id: Snowflake + get() = id } + + +@KordPreview +fun GlobalApplicationCommandBehavior( + applicationId: Snowflake, + id: Snowflake, + service: InteractionService +): GlobalApplicationCommandBehavior = object : GlobalApplicationCommandBehavior { + override val applicationId: Snowflake + get() = applicationId + override val service: InteractionService + get() = service + override val id: Snowflake + get() = id +} \ No newline at end of file From ffc820e02210fab9758d7254664ec219308274ee Mon Sep 17 00:00:00 2001 From: HopeBaron Date: Wed, 12 May 2021 16:20:26 +0300 Subject: [PATCH 2/8] Add interaction message --- .../src/main/kotlin/entity/DiscordMessage.kt | 11 +++++++++ .../src/main/kotlin/cache/data/MessageData.kt | 6 ++++- .../cache/data/MessageInteractionData.kt | 24 +++++++++++++++++++ core/src/main/kotlin/entity/Message.kt | 7 ++++++ .../entity/interaction/MessageInteraction.kt | 17 +++++++++++++ 5 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 core/src/main/kotlin/cache/data/MessageInteractionData.kt create mode 100644 core/src/main/kotlin/entity/interaction/MessageInteraction.kt diff --git a/common/src/main/kotlin/entity/DiscordMessage.kt b/common/src/main/kotlin/entity/DiscordMessage.kt index a802889e7c87..283bde6e906e 100644 --- a/common/src/main/kotlin/entity/DiscordMessage.kt +++ b/common/src/main/kotlin/entity/DiscordMessage.kt @@ -1,5 +1,6 @@ package dev.kord.common.entity +import dev.kord.common.annotation.KordPreview import dev.kord.common.entity.optional.Optional import dev.kord.common.entity.optional.OptionalBoolean import dev.kord.common.entity.optional.OptionalInt @@ -99,6 +100,7 @@ data class DiscordMessage( val stickers: Optional> = Optional.Missing(), @SerialName("referenced_message") val referencedMessage: Optional = Optional.Missing(), + val interaction: Optional = Optional.Missing() ) /** @@ -789,3 +791,12 @@ data class AllowedMentions( @SerialName("replied_user") val repliedUser: OptionalBoolean = OptionalBoolean.Missing ) + +@KordPreview +@Serializable +data class DiscordMessageInteraction( + val id: Snowflake, + val type: InteractionType, + val name: String, + val user: DiscordUser +) diff --git a/core/src/main/kotlin/cache/data/MessageData.kt b/core/src/main/kotlin/cache/data/MessageData.kt index b64740e94aac..89ff325d21fd 100644 --- a/core/src/main/kotlin/cache/data/MessageData.kt +++ b/core/src/main/kotlin/cache/data/MessageData.kt @@ -1,6 +1,8 @@ package dev.kord.core.cache.data +import cache.data.MessageInteractionData import dev.kord.cache.api.data.description +import dev.kord.common.annotation.KordPreview import dev.kord.common.entity.* import dev.kord.common.entity.optional.* import kotlinx.serialization.Serializable @@ -34,6 +36,7 @@ data class MessageData( val flags: Optional = Optional.Missing(), val stickers: Optional> = Optional.Missing(), val referencedMessage: Optional = Optional.Missing(), + val messageInteraction: Optional = Optional.Missing() ) { fun plus(selfId: Snowflake, reaction: MessageReactionAddData): MessageData { @@ -127,7 +130,8 @@ data class MessageData( messageReference.map { MessageReferenceData.from(it) }, flags, stickers.mapList { MessageStickerData.from(it) }, - referencedMessage.mapNotNull { from(it) } + referencedMessage.mapNotNull { from(it) }, + interaction.map { MessageInteractionData.from(it) } ) } } diff --git a/core/src/main/kotlin/cache/data/MessageInteractionData.kt b/core/src/main/kotlin/cache/data/MessageInteractionData.kt new file mode 100644 index 000000000000..81eb860adf21 --- /dev/null +++ b/core/src/main/kotlin/cache/data/MessageInteractionData.kt @@ -0,0 +1,24 @@ +package cache.data; + +import dev.kord.common.annotation.KordPreview +import dev.kord.common.entity.DiscordMessageInteraction +import dev.kord.common.entity.InteractionType +import dev.kord.common.entity.Snowflake +import dev.kord.core.cache.data.UserData +import dev.kord.core.cache.data.toData +import kotlinx.serialization.Serializable + +@KordPreview +@Serializable +data class MessageInteractionData( + val id:Snowflake, + val type:InteractionType, + val name:String, + val user:UserData +) { + companion object { + fun from(entity: DiscordMessageInteraction): MessageInteractionData = with(entity) { + MessageInteractionData(id, type, name, user.toData()) + } + } +} diff --git a/core/src/main/kotlin/entity/Message.kt b/core/src/main/kotlin/entity/Message.kt index 05d22f2f6668..6398a06db9f6 100644 --- a/core/src/main/kotlin/entity/Message.kt +++ b/core/src/main/kotlin/entity/Message.kt @@ -1,7 +1,10 @@ package dev.kord.core.entity +import dev.kord.common.annotation.KordPreview import dev.kord.common.entity.MessageType import dev.kord.common.entity.Snowflake +import dev.kord.common.entity.optional.map +import dev.kord.common.entity.optional.mapNullable import dev.kord.common.entity.optional.orEmpty import dev.kord.common.exception.RequestException import dev.kord.core.Kord @@ -13,6 +16,7 @@ import dev.kord.core.entity.channel.Channel import dev.kord.core.entity.channel.GuildChannel import dev.kord.core.entity.channel.GuildMessageChannel import dev.kord.core.entity.channel.MessageChannel +import dev.kord.core.entity.interaction.MessageInteraction import dev.kord.core.exception.EntityNotFoundException import dev.kord.core.supplier.EntitySupplier import dev.kord.core.supplier.EntitySupplyStrategy @@ -174,6 +178,9 @@ class Message( */ val mentionedUserBehaviors: Set get() = data.mentions.map { UserBehavior(it, kord) }.toSet() + @KordPreview + val interaction: MessageInteraction? get() = data.messageInteraction.mapNullable { MessageInteraction(it, kord) }.value + /** * The [users][User] mentioned in this message. * diff --git a/core/src/main/kotlin/entity/interaction/MessageInteraction.kt b/core/src/main/kotlin/entity/interaction/MessageInteraction.kt new file mode 100644 index 000000000000..995e40b2ce7b --- /dev/null +++ b/core/src/main/kotlin/entity/interaction/MessageInteraction.kt @@ -0,0 +1,17 @@ +package dev.kord.core.entity.interaction + +import cache.data.MessageInteractionData +import dev.kord.common.annotation.KordPreview +import dev.kord.common.entity.InteractionType +import dev.kord.common.entity.Snowflake +import dev.kord.core.Kord +import dev.kord.core.entity.KordEntity +import dev.kord.core.entity.User + +@KordPreview +class MessageInteraction(val data: MessageInteractionData, override val kord: Kord): KordEntity { + override val id: Snowflake get() = data.id + val name: String get() = data.name + val user: User get() = User(data.user, kord) + val type: InteractionType get() = data.type +} \ No newline at end of file From e0beb76a3d6cc587d01223bacce000b13b371e0c Mon Sep 17 00:00:00 2001 From: HopeBaron Date: Fri, 14 May 2021 14:22:10 +0300 Subject: [PATCH 3/8] Apply suggestions --- .../cache/data/MessageInteractionData.kt | 4 +-- core/src/main/kotlin/entity/Message.kt | 3 ++ .../entity/interaction/MessageInteraction.kt | 29 +++++++++++++++++-- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/core/src/main/kotlin/cache/data/MessageInteractionData.kt b/core/src/main/kotlin/cache/data/MessageInteractionData.kt index 81eb860adf21..a7882ff8dc2b 100644 --- a/core/src/main/kotlin/cache/data/MessageInteractionData.kt +++ b/core/src/main/kotlin/cache/data/MessageInteractionData.kt @@ -14,11 +14,11 @@ data class MessageInteractionData( val id:Snowflake, val type:InteractionType, val name:String, - val user:UserData + val user: Snowflake ) { companion object { fun from(entity: DiscordMessageInteraction): MessageInteractionData = with(entity) { - MessageInteractionData(id, type, name, user.toData()) + MessageInteractionData(id, type, name, user.id) } } } diff --git a/core/src/main/kotlin/entity/Message.kt b/core/src/main/kotlin/entity/Message.kt index 6398a06db9f6..9f25962a1cdf 100644 --- a/core/src/main/kotlin/entity/Message.kt +++ b/core/src/main/kotlin/entity/Message.kt @@ -178,6 +178,9 @@ class Message( */ val mentionedUserBehaviors: Set get() = data.mentions.map { UserBehavior(it, kord) }.toSet() + /** + * This is sent on this message object when it is a response to an [dev.kord.core.entity.interaction.Interaction]. + */ @KordPreview val interaction: MessageInteraction? get() = data.messageInteraction.mapNullable { MessageInteraction(it, kord) }.value diff --git a/core/src/main/kotlin/entity/interaction/MessageInteraction.kt b/core/src/main/kotlin/entity/interaction/MessageInteraction.kt index 995e40b2ce7b..922b4e11e187 100644 --- a/core/src/main/kotlin/entity/interaction/MessageInteraction.kt +++ b/core/src/main/kotlin/entity/interaction/MessageInteraction.kt @@ -5,13 +5,36 @@ import dev.kord.common.annotation.KordPreview import dev.kord.common.entity.InteractionType import dev.kord.common.entity.Snowflake import dev.kord.core.Kord +import dev.kord.core.behavior.UserBehavior import dev.kord.core.entity.KordEntity -import dev.kord.core.entity.User +import dev.kord.core.entity.Message +/** + * An instance of [MessageInteraction](https://discord.com/developers/docs/interactions/slash-commands#messageinteraction) + * This is sent on the [Message] object when the message is a response to an [Interaction]. + */ @KordPreview -class MessageInteraction(val data: MessageInteractionData, override val kord: Kord): KordEntity { +class MessageInteraction( + val data: MessageInteractionData, + override val kord: Kord, +) : KordEntity { + /** + * [id][Interaction.id] of the [Interaction] this message is responding to. + */ override val id: Snowflake get() = data.id + + /** + * the [name][ApplicationCommand.name] of the [ApplicationCommand] that triggered this message. + */ val name: String get() = data.name - val user: User get() = User(data.user, kord) + + /** + * The [UserBehavior] of the [user][Interaction.user] who invoked the [Interaction] + */ + val user: UserBehavior get() = UserBehavior(data.id, kord) + + /** + * the [InteractionType] of the interaction [MessageInteraction]. + */ val type: InteractionType get() = data.type } \ No newline at end of file From 2eb43dbda1120fbf7ac2ffc3d086f6c0bd127ef1 Mon Sep 17 00:00:00 2001 From: HopeBaron Date: Fri, 14 May 2021 14:27:31 +0300 Subject: [PATCH 4/8] reference the MessageInteraction in docs --- core/src/main/kotlin/entity/Message.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/kotlin/entity/Message.kt b/core/src/main/kotlin/entity/Message.kt index 9f25962a1cdf..59bb800f28c7 100644 --- a/core/src/main/kotlin/entity/Message.kt +++ b/core/src/main/kotlin/entity/Message.kt @@ -179,7 +179,7 @@ class Message( val mentionedUserBehaviors: Set get() = data.mentions.map { UserBehavior(it, kord) }.toSet() /** - * This is sent on this message object when it is a response to an [dev.kord.core.entity.interaction.Interaction]. + * The [MessageInteraction] sent on this message object when it is a response to an [dev.kord.core.entity.interaction.Interaction]. */ @KordPreview val interaction: MessageInteraction? get() = data.messageInteraction.mapNullable { MessageInteraction(it, kord) }.value From 9c059028ebe2e08c394e030d5e9df4205ce4b737 Mon Sep 17 00:00:00 2001 From: HopeBaron Date: Fri, 14 May 2021 15:03:40 +0300 Subject: [PATCH 5/8] Implement Strategizable for MessageInteraction --- .../entity/interaction/MessageInteraction.kt | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/core/src/main/kotlin/entity/interaction/MessageInteraction.kt b/core/src/main/kotlin/entity/interaction/MessageInteraction.kt index 922b4e11e187..5e9eec43004e 100644 --- a/core/src/main/kotlin/entity/interaction/MessageInteraction.kt +++ b/core/src/main/kotlin/entity/interaction/MessageInteraction.kt @@ -4,10 +4,16 @@ import cache.data.MessageInteractionData import dev.kord.common.annotation.KordPreview import dev.kord.common.entity.InteractionType import dev.kord.common.entity.Snowflake +import dev.kord.common.exception.RequestException import dev.kord.core.Kord import dev.kord.core.behavior.UserBehavior import dev.kord.core.entity.KordEntity import dev.kord.core.entity.Message +import dev.kord.core.entity.Strategizable +import dev.kord.core.entity.User +import dev.kord.core.exception.EntityNotFoundException +import dev.kord.core.supplier.EntitySupplier +import dev.kord.core.supplier.EntitySupplyStrategy /** * An instance of [MessageInteraction](https://discord.com/developers/docs/interactions/slash-commands#messageinteraction) @@ -17,7 +23,8 @@ import dev.kord.core.entity.Message class MessageInteraction( val data: MessageInteractionData, override val kord: Kord, -) : KordEntity { + override val supplier: EntitySupplier = kord.defaultSupplier +) : KordEntity, Strategizable { /** * [id][Interaction.id] of the [Interaction] this message is responding to. */ @@ -37,4 +44,24 @@ class MessageInteraction( * the [InteractionType] of the interaction [MessageInteraction]. */ val type: InteractionType get() = data.type + + /** + * Requests the [User] of this interaction message. + * + * @throws RequestException if something went wrong while retrieving the user. + * @throws EntityNotFoundException if the user was null. + */ + suspend fun getUser(): User = supplier.getUser(user.id) + + /** + * Requests to get the user of this interaction message, + * returns null if the [User] isn't present. + * + * @throws [RequestException] if anything went wrong during the request. + */ + suspend fun getUserOrNull(): User? = supplier.getUserOrNull(user.id) + + override fun withStrategy(strategy: EntitySupplyStrategy<*>): Strategizable { + return MessageInteraction(data, kord, strategy.supply(kord)) + } } \ No newline at end of file From 52aec9c72b1d6166aaf52bd2811298339c2656f1 Mon Sep 17 00:00:00 2001 From: HopeBaron Date: Fri, 14 May 2021 16:08:02 +0300 Subject: [PATCH 6/8] cache user from interaction message --- common/src/main/kotlin/entity/DiscordMessage.kt | 1 + core/src/main/kotlin/cache/data/MessageData.kt | 8 ++++++-- .../main/kotlin/gateway/handler/MessageEventHandler.kt | 8 ++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/common/src/main/kotlin/entity/DiscordMessage.kt b/common/src/main/kotlin/entity/DiscordMessage.kt index 283bde6e906e..efb28475f702 100644 --- a/common/src/main/kotlin/entity/DiscordMessage.kt +++ b/common/src/main/kotlin/entity/DiscordMessage.kt @@ -241,6 +241,7 @@ data class DiscordPartialMessage( val stickers: Optional> = Optional.Missing(), @SerialName("referenced_message") val referencedMessage: Optional = Optional.Missing(), + val interaction: Optional = Optional.Missing(), ) @Serializable diff --git a/core/src/main/kotlin/cache/data/MessageData.kt b/core/src/main/kotlin/cache/data/MessageData.kt index 89ff325d21fd..5027c87e8ab4 100644 --- a/core/src/main/kotlin/cache/data/MessageData.kt +++ b/core/src/main/kotlin/cache/data/MessageData.kt @@ -2,7 +2,6 @@ package dev.kord.core.cache.data import cache.data.MessageInteractionData import dev.kord.cache.api.data.description -import dev.kord.common.annotation.KordPreview import dev.kord.common.entity.* import dev.kord.common.entity.optional.* import kotlinx.serialization.Serializable @@ -36,7 +35,7 @@ data class MessageData( val flags: Optional = Optional.Missing(), val stickers: Optional> = Optional.Missing(), val referencedMessage: Optional = Optional.Missing(), - val messageInteraction: Optional = Optional.Missing() + val interaction: Optional = Optional.Missing() ) { fun plus(selfId: Snowflake, reaction: MessageReactionAddData): MessageData { @@ -72,6 +71,9 @@ data class MessageData( partialMessage.mentionedChannels.mapList { it.id }.switchOnMissing(mentionedChannels.value.orEmpty()) .coerceToMissing() val stickers = partialMessage.stickers.mapList { MessageStickerData.from(it) }.switchOnMissing(this.stickers) + val referencedMessage = partialMessage.referencedMessage.mapNullable { it?.toData() ?: referencedMessage.value } + val interaction = + partialMessage.interaction.map { MessageInteractionData.from(it) }.switchOnMissing(interaction) return MessageData( id, @@ -98,6 +100,8 @@ data class MessageData( messageReference, flags, stickers = stickers, + referencedMessage = referencedMessage, + interaction = interaction ) } diff --git a/core/src/main/kotlin/gateway/handler/MessageEventHandler.kt b/core/src/main/kotlin/gateway/handler/MessageEventHandler.kt index dda8eb285ef9..c3b737047628 100644 --- a/core/src/main/kotlin/gateway/handler/MessageEventHandler.kt +++ b/core/src/main/kotlin/gateway/handler/MessageEventHandler.kt @@ -1,5 +1,6 @@ package dev.kord.core.gateway.handler +import cache.data.MessageInteractionData import dev.kord.cache.api.DataCache import dev.kord.cache.api.put import dev.kord.cache.api.query @@ -10,6 +11,7 @@ import dev.kord.core.cache.idEq import dev.kord.core.entity.Member import dev.kord.core.entity.Message import dev.kord.core.entity.ReactionEmoji +import dev.kord.core.entity.interaction.MessageInteraction import dev.kord.core.event.message.* import dev.kord.core.gateway.MasterGateway import dev.kord.gateway.* @@ -59,6 +61,12 @@ internal class MessageEventHandler( Member(memberData, userData, kord) } else null + //cache interaction user if present. + if(interaction is Optional.Value) { + val userData = UserData.from(interaction.value!!.user) + cache.put(userData) + } + mentions.forEach { val user = UserData.from(it) cache.put(user) From 109a947cc4b23caaa4f867c8f229854363869e88 Mon Sep 17 00:00:00 2001 From: HopeBaron Date: Fri, 14 May 2021 16:25:39 +0300 Subject: [PATCH 7/8] Fix compilation errors --- core/src/main/kotlin/entity/Message.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/kotlin/entity/Message.kt b/core/src/main/kotlin/entity/Message.kt index 59bb800f28c7..7ab81fcda127 100644 --- a/core/src/main/kotlin/entity/Message.kt +++ b/core/src/main/kotlin/entity/Message.kt @@ -182,7 +182,7 @@ class Message( * The [MessageInteraction] sent on this message object when it is a response to an [dev.kord.core.entity.interaction.Interaction]. */ @KordPreview - val interaction: MessageInteraction? get() = data.messageInteraction.mapNullable { MessageInteraction(it, kord) }.value + val interaction: MessageInteraction? get() = data.interaction.mapNullable { MessageInteraction(it, kord) }.value /** * The [users][User] mentioned in this message. From 3eee6849cf041bb0de6ce4d1fd0c1bb14e6a0182 Mon Sep 17 00:00:00 2001 From: Hope <34831095+HopeBaron@users.noreply.github.com> Date: Fri, 14 May 2021 16:31:35 +0300 Subject: [PATCH 8/8] Fix withStrategy return type Co-authored-by: Bart Arys --- core/src/main/kotlin/entity/interaction/MessageInteraction.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/kotlin/entity/interaction/MessageInteraction.kt b/core/src/main/kotlin/entity/interaction/MessageInteraction.kt index 5e9eec43004e..029faf32a27c 100644 --- a/core/src/main/kotlin/entity/interaction/MessageInteraction.kt +++ b/core/src/main/kotlin/entity/interaction/MessageInteraction.kt @@ -61,7 +61,7 @@ class MessageInteraction( */ suspend fun getUserOrNull(): User? = supplier.getUserOrNull(user.id) - override fun withStrategy(strategy: EntitySupplyStrategy<*>): Strategizable { + override fun withStrategy(strategy: EntitySupplyStrategy<*>): MessageInteraction { return MessageInteraction(data, kord, strategy.supply(kord)) } -} \ No newline at end of file +}