Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added a function to load a message by a given message link. #951

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions core/api/core.api
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public final class dev/kord/core/Kord : kotlinx/coroutines/CoroutineScope {
public static synthetic fun getInvite$default (Ldev/kord/core/Kord;Ljava/lang/String;ZZLdev/kord/common/entity/Snowflake;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
public final fun getInviteOrNull (Ljava/lang/String;ZZLdev/kord/common/entity/Snowflake;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun getInviteOrNull$default (Ldev/kord/core/Kord;Ljava/lang/String;ZZLdev/kord/common/entity/Snowflake;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
public final fun getMessageByLink (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public final fun getNitroStickerPacks ()Lkotlinx/coroutines/flow/Flow;
public final fun getRegions ()Lkotlinx/coroutines/flow/Flow;
public final fun getResources ()Ldev/kord/core/ClientResources;
Expand Down
1 change: 1 addition & 0 deletions core/api/core.klib.api
Original file line number Diff line number Diff line change
Expand Up @@ -9274,6 +9274,7 @@ final class dev.kord.core/Kord : kotlinx.coroutines/CoroutineScope { // dev.kord
final suspend fun getGuildPreviewOrNull(dev.kord.common.entity/Snowflake, dev.kord.core.supplier/EntitySupplyStrategy<*> = ...): dev.kord.core.entity/GuildPreview? // dev.kord.core/Kord.getGuildPreviewOrNull|getGuildPreviewOrNull(dev.kord.common.entity.Snowflake;dev.kord.core.supplier.EntitySupplyStrategy<*>){}[0]
final suspend fun getInvite(kotlin/String, kotlin/Boolean = ..., kotlin/Boolean = ..., dev.kord.common.entity/Snowflake? = ...): dev.kord.core.entity/Invite // dev.kord.core/Kord.getInvite|getInvite(kotlin.String;kotlin.Boolean;kotlin.Boolean;dev.kord.common.entity.Snowflake?){}[0]
final suspend fun getInviteOrNull(kotlin/String, kotlin/Boolean = ..., kotlin/Boolean = ..., dev.kord.common.entity/Snowflake? = ...): dev.kord.core.entity/Invite? // dev.kord.core/Kord.getInviteOrNull|getInviteOrNull(kotlin.String;kotlin.Boolean;kotlin.Boolean;dev.kord.common.entity.Snowflake?){}[0]
final suspend fun getMessageByLink(kotlin/String): dev.kord.core.entity/Message? // dev.kord.core/Kord.getMessageByLink|getMessageByLink(kotlin.String){}[0]
final suspend fun getSelf(dev.kord.core.supplier/EntitySupplyStrategy<*> = ...): dev.kord.core.entity/User // dev.kord.core/Kord.getSelf|getSelf(dev.kord.core.supplier.EntitySupplyStrategy<*>){}[0]
final suspend fun getSticker(dev.kord.common.entity/Snowflake): dev.kord.core.entity/Sticker // dev.kord.core/Kord.getSticker|getSticker(dev.kord.common.entity.Snowflake){}[0]
final suspend fun getUser(dev.kord.common.entity/Snowflake, dev.kord.core.supplier/EntitySupplyStrategy<*> = ...): dev.kord.core.entity/User? // dev.kord.core/Kord.getUser|getUser(dev.kord.common.entity.Snowflake;dev.kord.core.supplier.EntitySupplyStrategy<*>){}[0]
Expand Down
35 changes: 35 additions & 0 deletions core/src/commonMain/kotlin/Kord.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import dev.kord.common.annotation.KordUnsafe
import dev.kord.common.entity.DiscordShard
import dev.kord.common.entity.Snowflake
import dev.kord.common.exception.RequestException
import dev.kord.core.behavior.channel.asChannelOfOrNull
import dev.kord.core.builder.kord.KordBuilder
import dev.kord.core.builder.kord.KordProxyBuilder
import dev.kord.core.builder.kord.KordRestOnlyBuilder
Expand All @@ -15,6 +16,7 @@ import dev.kord.core.cache.data.UserData
import dev.kord.core.entity.*
import dev.kord.core.entity.application.*
import dev.kord.core.entity.channel.Channel
import dev.kord.core.entity.channel.MessageChannel
import dev.kord.core.event.Event
import dev.kord.core.exception.EntityNotFoundException
import dev.kord.core.exception.KordInitializationException
Expand Down Expand Up @@ -43,6 +45,18 @@ import kotlinx.coroutines.channels.Channel as CoroutineChannel
public val kordLogger: mu.KLogger = mu.KotlinLogging.logger { }

private val logger = KotlinLogging.logger { }
private val messageLinkRegex = """
|(?x) # enable comments
|(?i) # allow ignore case
|(?:https?+://)?+ # https:// (or also http:// or an empty string)
|(?:(?:canary|ptb)\.)?+ # canary. or ptb.
|discord(?:app)?+\.com/channels/ # discord(app).com/channels/
|(?:(?<server>[0-9]++)|@me) # @me or the server id
|/ # '/'
|(?<channel>[0-9]++) # the channel id (should only be a message channel)
|/ # '/'
|(?<message>[0-9]++) # the message id
""".trimMargin().toRegex()

@PublishedApi
internal fun logCaughtThrowable(throwable: Throwable): Unit = logger.catching(throwable)
Expand Down Expand Up @@ -258,6 +272,27 @@ public class Kord(
strategy: EntitySupplyStrategy<*> = resources.defaultStrategy,
): Guild = strategy.supply(this).getGuild(id)

/**
* Returns the [Message] that is fetched by the given [messageLink].
* If either the channel or the message id found in the link is invalid, null is returned.
*
* @throws IllegalArgumentException if the message link doesn't match the format found in [messageLinkRegex]
*/
public suspend fun getMessageByLink(
messageLink: String
): Message? {
val matches = messageLinkRegex.matchEntire(messageLink)

require(matches != null) { "The message link has an invalid format." }

val channel = matches.groups["channel"]?.value
?.let { getChannel(Snowflake(it)) }
?.asChannelOfOrNull<MessageChannel>()

return matches.groups["message"]?.value
?.let { channel?.getMessageOrNull(Snowflake(it)) }
}

/**
* Requests to get the [Webhook] in this guild.
*
Expand Down