Skip to content

Commit

Permalink
[Feature] Update webhook implementation (#2723)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
Misha-133 and quinchs authored Aug 10, 2023
1 parent 5c8d83c commit 2b8584d
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 43 deletions.
14 changes: 11 additions & 3 deletions src/Discord.Net.Core/Entities/Webhooks/IWebhook.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,20 @@ namespace Discord
public interface IWebhook : IDeletable, ISnowflakeEntity
{
/// <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>
string Token { get; }

/// <summary>
/// Gets the default name of this webhook.
/// </summary>
string Name { get; }

/// <summary>
/// Gets the ID of this webhook's default avatar.
/// </summary>
string AvatarId { get; }

/// <summary>
/// Gets the URL to this webhook's default avatar.
/// </summary>
Expand All @@ -30,10 +32,11 @@ public interface IWebhook : IDeletable, ISnowflakeEntity
/// Gets the channel for this webhook.
/// </summary>
IIntegrationChannel Channel { get; }

/// <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>
ulong ChannelId { get; }
ulong? ChannelId { get; }

/// <summary>
/// Gets the guild owning this webhook.
Expand All @@ -54,6 +57,11 @@ public interface IWebhook : IDeletable, ISnowflakeEntity
/// </summary>
ulong? ApplicationId { get; }

/// <summary>
/// Gets the type of this webhook.
/// </summary>
WebhookType Type { get; }

/// <summary>
/// Modifies this webhook.
/// </summary>
Expand Down
31 changes: 21 additions & 10 deletions src/Discord.Net.Core/Entities/Webhooks/WebhookType.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
namespace Discord
namespace Discord;

/// <summary>
/// Represents the type of a webhook.
/// </summary>
/// <remarks>
/// This type is currently unused, and is only returned in audit log responses.
/// </remarks>
public enum WebhookType
{
/// <summary>
/// Represents the type of a webhook.
/// An incoming webhook.
/// </summary>
/// <remarks>
/// This type is currently unused, and is only returned in audit log responses.
/// </remarks>
public enum WebhookType
{
/// <summary> An incoming webhook </summary>
Incoming = 1
}
Incoming = 1,

/// <summary>
/// A channel follower webhook.
/// </summary>
ChannelFollower = 2,

/// <summary>
/// An application (interaction) webhook.
/// </summary>
Application = 3,
}
57 changes: 35 additions & 22 deletions src/Discord.Net.Rest/API/Common/Webhook.cs
Original file line number Diff line number Diff line change
@@ -1,26 +1,39 @@
using Newtonsoft.Json;

namespace Discord.API
namespace Discord.API;

internal class Webhook
{
internal class Webhook
{
[JsonProperty("id")]
public ulong Id { get; set; }
[JsonProperty("channel_id")]
public ulong ChannelId { get; set; }
[JsonProperty("token")]
public string Token { get; set; }

[JsonProperty("name")]
public Optional<string> Name { get; set; }
[JsonProperty("avatar")]
public Optional<string> Avatar { get; set; }
[JsonProperty("guild_id")]
public Optional<ulong> GuildId { get; set; }

[JsonProperty("user")]
public Optional<User> Creator { get; set; }
[JsonProperty("application_id")]
public ulong? ApplicationId { get; set; }
}
[JsonProperty("id")]
public ulong Id { get; set; }

[JsonProperty("type")]
public WebhookType Type { get; set; }

[JsonProperty("guild_id")]
public Optional<ulong?> GuildId { get; set; }

[JsonProperty("channel_id")]
public ulong? ChannelId { get; set; }

[JsonProperty("user")]
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")]
public ulong? ApplicationId { get; set; }

[JsonProperty("source_guild")]
public Optional<PartialGuild> Guild { get; set; }

[JsonProperty("source_channel")]
public Optional<Channel> Channel { get; set; }
}
51 changes: 45 additions & 6 deletions src/Discord.Net.Rest/Entities/Webhooks/RestWebhook.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,50 +9,89 @@ namespace Discord.Rest
public class RestWebhook : RestEntity<ulong>, IWebhook, IUpdateable
{
#region RestWebhook

internal IGuild Guild { get; private set; }
internal IIntegrationChannel Channel { get; private set; }

/// <inheritdoc />
public string Token { get; }

/// <inheritdoc />
public ulong ChannelId { get; private set; }
public ulong? ChannelId { get; private set; }

/// <inheritdoc />
public string Name { get; private set; }

/// <inheritdoc />
public string AvatarId { get; private set; }

/// <inheritdoc />
public ulong? GuildId { get; private set; }

/// <inheritdoc />
public IUser Creator { get; private set; }

/// <inheritdoc />
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 />
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)
{
Guild = guild;
Token = token;
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;
}

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);
return entity;
}

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);
return entity;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@ internal class RestInternalWebhook : IWebhook
public ulong Id { 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 AvatarId { get; private set; }
public ulong? GuildId { get; private set; }
public ulong? ApplicationId { get; private set; }
public WebhookType Type { get; private set; }

public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id);

Expand All @@ -26,7 +27,7 @@ internal RestInternalWebhook(DiscordWebhookClient apiClient, Model model)
_client = apiClient;
Id = model.Id;
ChannelId = model.Id;
Token = model.Token;
Token = model.Token.GetValueOrDefault(null);
}
internal static RestInternalWebhook Create(DiscordWebhookClient client, Model model)
{
Expand All @@ -46,6 +47,8 @@ internal void Update(Model model)
if (model.Name.IsSpecified)
Name = model.Name.Value;

Type = model.Type;

ApplicationId = model.ApplicationId;
}

Expand Down

0 comments on commit 2b8584d

Please sign in to comment.