diff --git a/kord-extensions/src/main/kotlin/dev/kordex/core/utils/_Message.kt b/kord-extensions/src/main/kotlin/dev/kordex/core/utils/_Message.kt index 4742412019..e30cd37785 100644 --- a/kord-extensions/src/main/kotlin/dev/kordex/core/utils/_Message.kt +++ b/kord-extensions/src/main/kotlin/dev/kordex/core/utils/_Message.kt @@ -512,3 +512,36 @@ public suspend fun CommandContext.waitForResponse( return event?.message } + +/** + * Attempt to retrieve the message that the current message is in reply to, if any. + * + * In some situations, such as when dealing with a cross-posted (forwarded) message, Discord may return an HTTP 403. + * This function returns `null` in those situations. + * + * This function also returns `null` when the messages come from different channels, to avoid cross-posted messages. + * + * @return Corresponding [Message] object if found, accessible, and correct; `null` otherwise. + */ +public suspend fun Message.repliedMessageOrNull(): Message? { + val logger = KotlinLogging.logger("dev.kordex.core.utils.repliedMessageOrNull") + val reference = messageReference?.message + + if (reference == null) { + return null + } + + try { + val newMessage = reference.asMessageOrNull() + + if (newMessage == null || newMessage.channelId != channelId) { + return null + } + + return newMessage + } catch (e: RestRequestException) { + logger.debug(e) { "Failed to retrieve referenced message (${reference.id}) for reply-message ($id)" } + + return null + } +} diff --git a/modules/integrations/pluralkit/src/main/kotlin/dev/kordex/modules/pluralkit/PKExtension.kt b/modules/integrations/pluralkit/src/main/kotlin/dev/kordex/modules/pluralkit/PKExtension.kt index dacdb505c8..b99c6a4a32 100644 --- a/modules/integrations/pluralkit/src/main/kotlin/dev/kordex/modules/pluralkit/PKExtension.kt +++ b/modules/integrations/pluralkit/src/main/kotlin/dev/kordex/modules/pluralkit/PKExtension.kt @@ -40,6 +40,7 @@ import dev.kordex.core.storage.StorageType import dev.kordex.core.storage.StorageUnit import dev.kordex.core.utils.MutableStringKeyedMap import dev.kordex.core.utils.kordExUserAgent +import dev.kordex.core.utils.repliedMessageOrNull import dev.kordex.core.utils.scheduling.Scheduler import dev.kordex.core.utils.scheduling.Task import dev.kordex.modules.pluralkit.api.PluralKit @@ -142,7 +143,7 @@ class PKExtension(val config: PKConfigBuilder) : Extension() { awaitingEvents[message.id] = event } - val referencedMessage = message.messageReference?.message?.asMessageOrNull() + val referencedMessage = message.repliedMessageOrNull() if (referencedMessage != null) { replyCache[message.id] = referencedMessage