Skip to content

Commit

Permalink
Message interaction (kordlib#283)
Browse files Browse the repository at this point in the history
* Expose the creation of application commands behavior

* Add interaction message

* Apply suggestions

* reference the MessageInteraction in docs

* Implement Strategizable for MessageInteraction

* cache user from interaction message

* Fix compilation errors

* Fix withStrategy return type

Co-authored-by: Bart Arys <[email protected]>

Co-authored-by: Bart Arys <[email protected]>
  • Loading branch information
2 people authored and DRSchlaubi committed May 26, 2021
1 parent e300c5b commit 42c8fb5
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 1 deletion.
12 changes: 12 additions & 0 deletions common/src/main/kotlin/entity/DiscordMessage.kt
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -102,6 +103,7 @@ data class DiscordMessage(
val stickers: Optional<List<DiscordMessageSticker>> = Optional.Missing(),
@SerialName("referenced_message")
val referencedMessage: Optional<DiscordMessage?> = Optional.Missing(),
val interaction: Optional<DiscordMessageInteraction> = Optional.Missing()
)

/**
Expand Down Expand Up @@ -242,6 +244,7 @@ data class DiscordPartialMessage(
val stickers: Optional<List<DiscordMessageSticker>> = Optional.Missing(),
@SerialName("referenced_message")
val referencedMessage: Optional<DiscordMessage?> = Optional.Missing(),
val interaction: Optional<DiscordMessageInteraction> = Optional.Missing(),
)

@Serializable
Expand Down Expand Up @@ -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
)
10 changes: 9 additions & 1 deletion core/src/main/kotlin/cache/data/MessageData.kt
Original file line number Diff line number Diff line change
@@ -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.*
Expand Down Expand Up @@ -35,6 +36,7 @@ data class MessageData(
val flags: Optional<MessageFlags> = Optional.Missing(),
val stickers: Optional<List<MessageStickerData>> = Optional.Missing(),
val referencedMessage: Optional<MessageData?> = Optional.Missing(),
val interaction: Optional<MessageInteractionData> = Optional.Missing()
) {

fun plus(selfId: Snowflake, reaction: MessageReactionAddData): MessageData {
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -97,6 +102,8 @@ data class MessageData(
messageReference,
flags,
stickers = stickers,
referencedMessage = referencedMessage,
interaction = interaction
)
}

Expand Down Expand Up @@ -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) }
)
}
}
Expand Down
24 changes: 24 additions & 0 deletions core/src/main/kotlin/cache/data/MessageInteractionData.kt
Original file line number Diff line number Diff line change
@@ -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)
}
}
}
10 changes: 10 additions & 0 deletions core/src/main/kotlin/entity/Message.kt
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand Down Expand Up @@ -180,6 +184,12 @@ class Message(
*/
val mentionedUserBehaviors: Set<UserBehavior> 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.
*
Expand Down
67 changes: 67 additions & 0 deletions core/src/main/kotlin/entity/interaction/MessageInteraction.kt
Original file line number Diff line number Diff line change
@@ -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))
}
}
8 changes: 8 additions & 0 deletions core/src/main/kotlin/gateway/handler/MessageEventHandler.kt
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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.*
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 42c8fb5

Please sign in to comment.