diff --git a/common/src/main/kotlin/entity/DiscordMessage.kt b/common/src/main/kotlin/entity/DiscordMessage.kt index e8f068c8aab8..9fc5d7f3a2fa 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 @@ -102,6 +103,7 @@ data class DiscordMessage( val stickers: Optional> = Optional.Missing(), @SerialName("referenced_message") val referencedMessage: Optional = Optional.Missing(), + val interaction: Optional = Optional.Missing() ) /** @@ -242,6 +244,7 @@ data class DiscordPartialMessage( val stickers: Optional> = Optional.Missing(), @SerialName("referenced_message") val referencedMessage: Optional = Optional.Missing(), + val interaction: Optional = Optional.Missing(), ) @Serializable @@ -827,3 +830,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 1ced08364724..c85ff39b8289 100644 --- a/core/src/main/kotlin/cache/data/MessageData.kt +++ b/core/src/main/kotlin/cache/data/MessageData.kt @@ -1,5 +1,6 @@ package dev.kord.core.cache.data +import cache.data.MessageInteractionData import dev.kord.cache.api.data.description import dev.kord.common.entity.* import dev.kord.common.entity.optional.* @@ -35,6 +36,7 @@ data class MessageData( val flags: Optional = Optional.Missing(), val stickers: Optional> = Optional.Missing(), val referencedMessage: Optional = Optional.Missing(), + val interaction: Optional = Optional.Missing() ) { fun plus(selfId: Snowflake, reaction: MessageReactionAddData): MessageData { @@ -70,6 +72,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, @@ -97,6 +102,8 @@ data class MessageData( messageReference, flags, stickers = stickers, + referencedMessage = referencedMessage, + interaction = interaction ) } @@ -130,7 +137,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..a7882ff8dc2b --- /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: Snowflake +) { + companion object { + fun from(entity: DiscordMessageInteraction): MessageInteractionData = with(entity) { + 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 375ecff2d018..d7c4c28998e8 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.entity.interaction.Interaction import dev.kord.core.exception.EntityNotFoundException import dev.kord.core.supplier.EntitySupplier @@ -180,6 +184,12 @@ class Message( */ val mentionedUserBehaviors: Set get() = data.mentions.map { UserBehavior(it, kord) }.toSet() + /** + * 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.interaction.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..029faf32a27c --- /dev/null +++ b/core/src/main/kotlin/entity/interaction/MessageInteraction.kt @@ -0,0 +1,67 @@ +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.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) + * 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, + override val supplier: EntitySupplier = kord.defaultSupplier +) : KordEntity, Strategizable { + /** + * [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 + + /** + * 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 + + /** + * 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<*>): MessageInteraction { + return MessageInteraction(data, kord, strategy.supply(kord)) + } +} 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)