diff --git a/Remora.Discord.Commands/Parsers/SnowflakeParser.cs b/Remora.Discord.Commands/Parsers/SnowflakeParser.cs
index 2ee38a331c..b30a3a7521 100644
--- a/Remora.Discord.Commands/Parsers/SnowflakeParser.cs
+++ b/Remora.Discord.Commands/Parsers/SnowflakeParser.cs
@@ -20,6 +20,7 @@
// along with this program. If not, see .
//
+using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;
@@ -38,9 +39,26 @@ namespace Remora.Discord.Commands.Parsers;
[PublicAPI]
public class SnowflakeParser : AbstractTypeParser
{
+ private static readonly Regex _channelLinkRegex = new
+ (
+ @"^https://(canary\.|ptb\.)?discord\.com/channels/(?@me|[0-9]*)/(?[0-9]*)(/(?[0-9]*))?/?$",
+ RegexOptions.Compiled | RegexOptions.CultureInvariant
+ );
+
///
public override ValueTask> TryParseAsync(string value, CancellationToken ct = default)
{
+ var channelLinkMatch = _channelLinkRegex.Match(value);
+ if (channelLinkMatch.Success)
+ {
+ value = channelLinkMatch.Groups["message_id"].Value;
+
+ if (string.IsNullOrEmpty(value))
+ {
+ value = channelLinkMatch.Groups["channel_id"].Value;
+ }
+ }
+
return new
(
!DiscordSnowflake.TryParse(value.Unmention(), out var snowflake)
diff --git a/Tests/Remora.Discord.Commands.Tests/Parsers/SnowflakeParserTests.cs b/Tests/Remora.Discord.Commands.Tests/Parsers/SnowflakeParserTests.cs
index d2a0db6db8..5b089ae699 100644
--- a/Tests/Remora.Discord.Commands.Tests/Parsers/SnowflakeParserTests.cs
+++ b/Tests/Remora.Discord.Commands.Tests/Parsers/SnowflakeParserTests.cs
@@ -66,6 +66,24 @@ public async Task CanParseSnowflakeByNumber()
Assert.Equal(snowflakeValue, tryParse.Entity.Value);
}
+ ///
+ /// Tests whether the parser can parse snowflake value given by url.
+ ///
+ /// Mention that should be parsed correctly.
+ /// A representing the asynchronous unit test.
+ [InlineData("https://discord.com/channels/690919691404967977/765178263517397033")]
+ [InlineData("https://discord.com/channels/690919691404967977/1389600463250260019/765178263517397033")]
+ [InlineData("https://canary.discord.com/channels/690919691404967977/1389600463250260019/765178263517397033")]
+ [InlineData("https://ptb.discord.com/channels/690919691404967977/1389600463250260019/765178263517397033")]
+ [Theory]
+ public async Task CanParseSnowflakeByUrl(string value)
+ {
+ ulong snowflakeValue = 765178263517397033;
+ var tryParse = await _parser.TryParseAsync(value);
+ ResultAssert.Successful(tryParse);
+ Assert.Equal(snowflakeValue, tryParse.Entity.Value);
+ }
+
///
/// Tests whether the parser can parse snowflake value given by mentions.
///