[Feature] Update webhook implementation (#2723)

* initial commit

* add partial guild & channel props

* Apply suggestions from code review

Co-authored-by: Quin Lynch <49576606+quinchs@users.noreply.github.com>

---------

Co-authored-by: Quin Lynch <49576606+quinchs@users.noreply.github.com>
This commit is contained in:
Misha133
2023-08-10 16:14:00 +03:00
committed by GitHub
parent 5c8d83cf85
commit 2b8584d07d
5 changed files with 115 additions and 41 deletions

View File

@@ -9,7 +9,7 @@ namespace Discord
public interface IWebhook : IDeletable, ISnowflakeEntity public interface IWebhook : IDeletable, ISnowflakeEntity
{ {
/// <summary> /// <summary>
/// Gets the token of this webhook. /// Gets the token of this webhook; <see langword="null"/> if the <see cref="Type"/> is <see cref="WebhookType.ChannelFollower"/>.
/// </summary> /// </summary>
string Token { get; } string Token { get; }
@@ -17,10 +17,12 @@ namespace Discord
/// Gets the default name of this webhook. /// Gets the default name of this webhook.
/// </summary> /// </summary>
string Name { get; } string Name { get; }
/// <summary> /// <summary>
/// Gets the ID of this webhook's default avatar. /// Gets the ID of this webhook's default avatar.
/// </summary> /// </summary>
string AvatarId { get; } string AvatarId { get; }
/// <summary> /// <summary>
/// Gets the URL to this webhook's default avatar. /// Gets the URL to this webhook's default avatar.
/// </summary> /// </summary>
@@ -30,10 +32,11 @@ namespace Discord
/// Gets the channel for this webhook. /// Gets the channel for this webhook.
/// </summary> /// </summary>
IIntegrationChannel Channel { get; } IIntegrationChannel Channel { get; }
/// <summary> /// <summary>
/// Gets the ID of the channel for this webhook. /// Gets the ID of the channel for this webhook; <see langword="null"/> for <see cref="WebhookType.Application"/> webhooks.
/// </summary> /// </summary>
ulong ChannelId { get; } ulong? ChannelId { get; }
/// <summary> /// <summary>
/// Gets the guild owning this webhook. /// Gets the guild owning this webhook.
@@ -54,6 +57,11 @@ namespace Discord
/// </summary> /// </summary>
ulong? ApplicationId { get; } ulong? ApplicationId { get; }
/// <summary>
/// Gets the type of this webhook.
/// </summary>
WebhookType Type { get; }
/// <summary> /// <summary>
/// Modifies this webhook. /// Modifies this webhook.
/// </summary> /// </summary>

View File

@@ -1,5 +1,5 @@
namespace Discord namespace Discord;
{
/// <summary> /// <summary>
/// Represents the type of a webhook. /// Represents the type of a webhook.
/// </summary> /// </summary>
@@ -8,7 +8,18 @@ namespace Discord
/// </remarks> /// </remarks>
public enum WebhookType public enum WebhookType
{ {
/// <summary> An incoming webhook </summary> /// <summary>
Incoming = 1 /// An incoming webhook.
} /// </summary>
Incoming = 1,
/// <summary>
/// A channel follower webhook.
/// </summary>
ChannelFollower = 2,
/// <summary>
/// An application (interaction) webhook.
/// </summary>
Application = 3,
} }

View File

@@ -1,26 +1,39 @@
using Newtonsoft.Json; using Newtonsoft.Json;
namespace Discord.API namespace Discord.API;
{
internal class Webhook internal class Webhook
{ {
[JsonProperty("id")] [JsonProperty("id")]
public ulong Id { get; set; } public ulong Id { get; set; }
[JsonProperty("channel_id")]
public ulong ChannelId { get; set; }
[JsonProperty("token")]
public string Token { get; set; }
[JsonProperty("name")] [JsonProperty("type")]
public Optional<string> Name { get; set; } public WebhookType Type { get; set; }
[JsonProperty("avatar")]
public Optional<string> Avatar { get; set; }
[JsonProperty("guild_id")] [JsonProperty("guild_id")]
public Optional<ulong> GuildId { get; set; } public Optional<ulong?> GuildId { get; set; }
[JsonProperty("channel_id")]
public ulong? ChannelId { get; set; }
[JsonProperty("user")] [JsonProperty("user")]
public Optional<User> Creator { get; set; } public Optional<User> Creator { get; set; }
[JsonProperty("name")]
public Optional<string> Name { get; set; }
[JsonProperty("avatar")]
public Optional<string> Avatar { get; set; }
[JsonProperty("token")]
public Optional<string> Token { get; set; }
[JsonProperty("application_id")] [JsonProperty("application_id")]
public ulong? ApplicationId { get; set; } public ulong? ApplicationId { get; set; }
}
[JsonProperty("source_guild")]
public Optional<PartialGuild> Guild { get; set; }
[JsonProperty("source_channel")]
public Optional<Channel> Channel { get; set; }
} }

View File

@@ -9,6 +9,7 @@ namespace Discord.Rest
public class RestWebhook : RestEntity<ulong>, IWebhook, IUpdateable public class RestWebhook : RestEntity<ulong>, IWebhook, IUpdateable
{ {
#region RestWebhook #region RestWebhook
internal IGuild Guild { get; private set; } internal IGuild Guild { get; private set; }
internal IIntegrationChannel Channel { get; private set; } internal IIntegrationChannel Channel { get; private set; }
@@ -16,43 +17,81 @@ namespace Discord.Rest
public string Token { get; } public string Token { get; }
/// <inheritdoc /> /// <inheritdoc />
public ulong ChannelId { get; private set; } public ulong? ChannelId { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
public string Name { get; private set; } public string Name { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
public string AvatarId { get; private set; } public string AvatarId { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
public ulong? GuildId { get; private set; } public ulong? GuildId { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
public IUser Creator { get; private set; } public IUser Creator { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
public ulong? ApplicationId { get; private set; } public ulong? ApplicationId { get; private set; }
/// <inheritdoc />
public WebhookType Type { get; private set; }
/// <summary>
/// Gets the partial guild of the followed channel. <see langword="null"/> if <see cref="Type"/> is not <see cref="WebhookType.ChannelFollower"/>.
/// </summary>
public PartialGuild PartialGuild { get; private set; }
/// <summary>
/// Gets the id of the followed channel. <see langword="null"/> if <see cref="Type"/> is not <see cref="WebhookType.ChannelFollower"/>.
/// </summary>
public ulong? FollowedChannelId { get; private set; }
/// <summary>
/// Gets the name of the followed channel. <see langword="null"/> if <see cref="Type"/> is not <see cref="WebhookType.ChannelFollower"/>.
/// </summary>
public string FollowedChannelName { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id); public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id);
internal RestWebhook(BaseDiscordClient discord, IGuild guild, ulong id, string token, ulong channelId) internal RestWebhook(BaseDiscordClient discord, IGuild guild, ulong id, string token, ulong? channelId, WebhookType type, PartialGuild partialGuild,
ulong? followedChannelId, string followedChannelName)
: base(discord, id) : base(discord, id)
{ {
Guild = guild; Guild = guild;
Token = token; Token = token;
ChannelId = channelId; ChannelId = channelId;
Type = type;
PartialGuild = partialGuild;
FollowedChannelId = followedChannelId;
FollowedChannelName = followedChannelName;
} }
internal RestWebhook(BaseDiscordClient discord, IIntegrationChannel channel, ulong id, string token, ulong channelId)
: this(discord, channel.Guild, id, token, channelId) internal RestWebhook(BaseDiscordClient discord, IIntegrationChannel channel, ulong id, string token, ulong? channelId, WebhookType type, PartialGuild partialGuild,
ulong? followedChannelId, string followedChannelName)
: this(discord, channel.Guild, id, token, channelId, type, partialGuild, followedChannelId, followedChannelName)
{ {
Channel = channel; Channel = channel;
} }
internal static RestWebhook Create(BaseDiscordClient discord, IGuild guild, Model model) internal static RestWebhook Create(BaseDiscordClient discord, IGuild guild, Model model)
{ {
var entity = new RestWebhook(discord, guild, model.Id, model.Token, model.ChannelId); var entity = new RestWebhook(discord, guild, model.Id, model.Token.GetValueOrDefault(null), model.ChannelId, model.Type,
model.Guild.IsSpecified ? PartialGuildExtensions.Create(model.Guild.Value) : null,
model.Channel.IsSpecified ? model.Channel.Value.Id : null,
model.Channel.IsSpecified ? model.Channel.Value.Name.GetValueOrDefault(null) : null
);
entity.Update(model); entity.Update(model);
return entity; return entity;
} }
internal static RestWebhook Create(BaseDiscordClient discord, IIntegrationChannel channel, Model model) internal static RestWebhook Create(BaseDiscordClient discord, IIntegrationChannel channel, Model model)
{ {
var entity = new RestWebhook(discord, channel, model.Id, model.Token, model.ChannelId); var entity = new RestWebhook(discord, channel, model.Id, model.Token.GetValueOrDefault(null), model.ChannelId, model.Type,
model.Guild.IsSpecified ? PartialGuildExtensions.Create(model.Guild.Value) : null,
model.Channel.IsSpecified ? model.Channel.Value.Id : null,
model.Channel.IsSpecified ? model.Channel.Value.Name.GetValueOrDefault(null) : null);
entity.Update(model); entity.Update(model);
return entity; return entity;
} }

View File

@@ -13,11 +13,12 @@ namespace Discord.Webhook
public ulong Id { get; } public ulong Id { get; }
public string Token { get; } public string Token { get; }
public ulong ChannelId { get; private set; } public ulong? ChannelId { get; private set; }
public string Name { get; private set; } public string Name { get; private set; }
public string AvatarId { get; private set; } public string AvatarId { get; private set; }
public ulong? GuildId { get; private set; } public ulong? GuildId { get; private set; }
public ulong? ApplicationId { get; private set; } public ulong? ApplicationId { get; private set; }
public WebhookType Type { get; private set; }
public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id); public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id);
@@ -26,7 +27,7 @@ namespace Discord.Webhook
_client = apiClient; _client = apiClient;
Id = model.Id; Id = model.Id;
ChannelId = model.Id; ChannelId = model.Id;
Token = model.Token; Token = model.Token.GetValueOrDefault(null);
} }
internal static RestInternalWebhook Create(DiscordWebhookClient client, Model model) internal static RestInternalWebhook Create(DiscordWebhookClient client, Model model)
{ {
@@ -46,6 +47,8 @@ namespace Discord.Webhook
if (model.Name.IsSpecified) if (model.Name.IsSpecified)
Name = model.Name.Value; Name = model.Name.Value;
Type = model.Type;
ApplicationId = model.ApplicationId; ApplicationId = model.ApplicationId;
} }