Skip to content
2 changes: 1 addition & 1 deletion NetCord/Rest/AllowedMentionsProperties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public partial class AllowedMentionsProperties
/// <summary>
/// A list of mentionable role IDs. Allows all roles if set to <see langword="null"/>.
/// </summary>
/// /// <remarks>
/// <remarks>
/// <para>
/// If a role's <see cref="Role.Mentionable"/> property is set to <see langword="false"/>, and <see cref="Permissions.MentionEveryone"/> is not set, it will not be mentioned regardless.
/// </para>
Expand Down
14 changes: 14 additions & 0 deletions NetCord/Rest/JsonModels/JsonChannelPins.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.Text.Json.Serialization;

using NetCord.JsonModels;

namespace NetCord.Rest.JsonModels;

internal class JsonChannelPins
{
[JsonPropertyName("items")]
public JsonMessagePin[] Items { get; set; }

[JsonPropertyName("has_more")]
public bool HasMore { get; set; }
}
14 changes: 14 additions & 0 deletions NetCord/Rest/JsonModels/JsonMessagePin.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.Text.Json.Serialization;

using NetCord.JsonModels;

namespace NetCord.Rest.JsonModels;

public class JsonMessagePin
{
[JsonPropertyName("pinned_at")]
public DateTimeOffset PinnedAt { get; set; }

[JsonPropertyName("message")]
public JsonMessage Message { get; set; }
}
19 changes: 19 additions & 0 deletions NetCord/Rest/MessagePin.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace NetCord.Rest;

/// <summary>
/// Represents a message pin in a channel, containing the pinned message and the time it was pinned.
/// </summary>
public class MessagePin(JsonModels.JsonMessagePin jsonModel, RestClient client) : IJsonModel<JsonModels.JsonMessagePin>
{
JsonModels.JsonMessagePin IJsonModel<JsonModels.JsonMessagePin>.JsonModel => jsonModel;

/// <summary>
/// The time the message was pinned.
/// </summary>
public DateTimeOffset PinnedAt => jsonModel.PinnedAt;

/// <summary>
/// The pinned message.
/// </summary>
public RestMessage Message { get; } = new(jsonModel.Message, client);
}
48 changes: 40 additions & 8 deletions NetCord/Rest/RestClient.Channel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,7 @@ public Task TriggerTypingAsync(ulong channelId, RestRequestProperties? propertie
=> SendRequestAsync(HttpMethod.Post, $"/channels/{channelId}/typing", null, new(channelId), properties, cancellationToken: cancellationToken);

/// <summary>
/// /// Enters a typing scope for a channel, while waiting for the typing indicator to trigger.
/// Enters a typing scope for a channel, while waiting for the typing indicator to trigger.
/// </summary>
/// <param name="channelId">The ID of the channel to type in.</param>
/// <param name="scopeProperties">Optional properties to customize the typing interval, can be <see langword="null"/>.</param>
Expand All @@ -660,7 +660,7 @@ public ValueTask<IDisposable> EnterTypingScopeAsync(ulong channelId, TypingScope
}

/// <summary>
/// /// Enters a typing scope for a channel, while waiting for the typing indicator to trigger.
/// Enters a typing scope for a channel, while waiting for the typing indicator to trigger.
/// </summary>
/// <param name="channelId">The ID of the channel to type in.</param>
/// <param name="scopeProperties">Optional properties to customize the typing interval, can be <see langword="null"/>.</param>
Expand All @@ -674,36 +674,68 @@ public IDisposable EnterTypingScope(ulong channelId, TypingScopeProperties? scop
/// <summary>
/// Retrieves all pinned messages in a channel.
/// </summary>
/// <remarks>
/// Requires the <see cref="Permissions.ViewChannel"/> permission.
/// If the user is missing the <see cref="Permissions.ReadMessageHistory"/> permission in the channel, then no pins will be returned.
/// </remarks>
/// <param name="channelId">The ID of the channel to get pinned messages from.</param>
/// <param name="properties">Optional properties to customize the request, can be <see langword="null"/>.</param>
/// <param name="paginationProperties">Optional properties to customize result pagination, can be <see langword="null"/>.</param>
/// <param name="properties">Optional properties to customize each request, can be <see langword="null"/>.</param>
/// <param name="cancellationToken">A token that can be used to cancel the operation before it completes.</param>
[GenerateAlias([typeof(TextChannel)], nameof(TextChannel.Id))]
public async Task<IReadOnlyList<RestMessage>> GetPinnedMessagesAsync(ulong channelId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default)
=> (await (await SendRequestAsync(HttpMethod.Get, $"/channels/{channelId}/pins", null, new(channelId), properties, cancellationToken: cancellationToken).ConfigureAwait(false)).ToObjectAsync(Serialization.Default.JsonMessageArray).ConfigureAwait(false)).Select(m => new RestMessage(m, this)).ToArray();
[GenerateAlias([typeof(TextChannel)], nameof(TextChannel.Id), TypeNameOverride = "Channel")]
public IAsyncEnumerable<MessagePin> GetChannelPinsAsync(ulong channelId, PaginationProperties<DateTimeOffset>? paginationProperties = null, RestRequestProperties? properties = null, CancellationToken cancellationToken = default)
{
paginationProperties =
PaginationProperties<DateTimeOffset>.PrepareWithDirectionValidation(
paginationProperties,
PaginationDirection.Before,
50);

return new OptimizedQueryPaginationAsyncEnumerable<MessagePin, DateTimeOffset>(
Comment thread
jedrek0429 marked this conversation as resolved.
this,
paginationProperties,
async s =>
{
var result = await s.ToObjectAsync(Serialization.Default.JsonChannelPins).ConfigureAwait(false);
return (result.Items.Select(m => new MessagePin(m, this)), result.HasMore);
},
m => m.PinnedAt,
HttpMethod.Get,
$"/channels/{channelId}/messages/pins",
new(paginationProperties.BatchSize.GetValueOrDefault(), paginationProperties.Direction.GetValueOrDefault(), timestamp => timestamp.ToString("s")),
new(channelId),
properties);
}

/// <summary>
/// Pins a message in a channel.
/// </summary>
/// <remarks>
/// Requires the <see cref="Permissions.PinMessages"/> permission. Fires a <see cref="GatewayClient.ChannelPinsUpdate"/> event.
/// </remarks>
/// <param name="channelId">The ID of the channel containing the message.</param>
/// <param name="messageId">The ID of the message to pin.</param>
/// <param name="properties">Optional properties to customize the request, can be <see langword="null"/>.</param>
/// <param name="cancellationToken">A token that can be used to cancel the operation before it completes.</param>
[GenerateAlias([typeof(TextChannel)], nameof(TextChannel.Id))]
[GenerateAlias([typeof(RestMessage)], nameof(RestMessage.ChannelId), nameof(RestMessage.Id), TypeNameOverride = "Message")]
public Task PinMessageAsync(ulong channelId, ulong messageId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default)
=> SendRequestAsync(HttpMethod.Put, $"/channels/{channelId}/pins/{messageId}", null, new(channelId), properties, cancellationToken: cancellationToken);
=> SendRequestAsync(HttpMethod.Put, $"/channels/{channelId}/messages/pins/{messageId}", null, new(channelId), properties, cancellationToken: cancellationToken);

/// <summary>
/// Unpins a message from a channel.
/// </summary>
/// <remarks>
/// Requires the <see cref="Permissions.PinMessages"/> permission. Fires a <see cref="GatewayClient.ChannelPinsUpdate"/> event.
/// </remarks>
/// <param name="channelId">The ID of the channel containing the message.</param>
/// <param name="messageId">The ID of the message to unpin.</param>
/// <param name="properties">Optional properties to customize the request, can be <see langword="null"/>.</param>
/// <param name="cancellationToken">A token that can be used to cancel the operation before it completes.</param>
[GenerateAlias([typeof(TextChannel)], nameof(TextChannel.Id))]
[GenerateAlias([typeof(RestMessage)], nameof(RestMessage.ChannelId), nameof(RestMessage.Id), TypeNameOverride = "Message")]
public Task UnpinMessageAsync(ulong channelId, ulong messageId, RestRequestProperties? properties = null, CancellationToken cancellationToken = default)
=> SendRequestAsync(HttpMethod.Delete, $"/channels/{channelId}/pins/{messageId}", null, new(channelId), properties, cancellationToken: cancellationToken);
=> SendRequestAsync(HttpMethod.Delete, $"/channels/{channelId}/messages/pins/{messageId}", null, new(channelId), properties, cancellationToken: cancellationToken);

/// <summary>
/// Adds a recipient to a group DM channel.
Expand Down
1 change: 1 addition & 0 deletions NetCord/Serialization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ namespace NetCord;
[JsonSerializable(typeof(JsonEntitlement[]))]
[JsonSerializable(typeof(JsonSku[]))]
[JsonSerializable(typeof(JsonAuthorizationInformation))]
[JsonSerializable(typeof(JsonChannelPins))]
[JsonSerializable(typeof(StageInstanceProperties))]
[JsonSerializable(typeof(StageInstanceOptions))]
[JsonSerializable(typeof(JsonSticker))]
Expand Down