diff --git a/src/Discord.Net.Core/Entities/Channels/ITextChannel.cs b/src/Discord.Net.Core/Entities/Channels/ITextChannel.cs
index be4dd0260..7c6ec3908 100644
--- a/src/Discord.Net.Core/Entities/Channels/ITextChannel.cs
+++ b/src/Discord.Net.Core/Entities/Channels/ITextChannel.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.IO;
using System.Threading.Tasks;
namespace Discord
@@ -19,5 +20,12 @@ namespace Discord
/// Modifies this text channel.
Task ModifyAsync(Action func, RequestOptions options = null);
+
+ /// Creates a webhook in this text channel.
+ Task CreateWebhookAsync(string name, Stream avatar = null, RequestOptions options = null);
+ /// Gets the webhook in this text channel with the provided id, or null if not found.
+ Task GetWebhookAsync(ulong id, RequestOptions options = null);
+ /// Gets the webhooks for this text channel.
+ Task> GetWebhooksAsync(RequestOptions options = null);
}
}
\ No newline at end of file
diff --git a/src/Discord.Net.Core/Entities/Guilds/IGuild.cs b/src/Discord.Net.Core/Entities/Guilds/IGuild.cs
index 6b2d24cc6..0fdd92405 100644
--- a/src/Discord.Net.Core/Entities/Guilds/IGuild.cs
+++ b/src/Discord.Net.Core/Entities/Guilds/IGuild.cs
@@ -118,6 +118,11 @@ namespace Discord
/// Removes all users from this guild if they have not logged on in a provided number of days or, if simulate is true, returns the number of users that would be removed.
Task PruneUsersAsync(int days = 30, bool simulate = false, RequestOptions options = null);
+ /// Gets the webhook in this guild with the provided id, or null if not found.
+ Task GetWebhookAsync(ulong id, RequestOptions options = null);
+ /// Gets a collection of all webhooks for this guild.
+ Task> GetWebhooksAsync(RequestOptions options = null);
+
/// Gets a specific emote from this guild.
Task GetEmoteAsync(ulong id, RequestOptions options = null);
/// Creates a new emote in this guild.
diff --git a/src/Discord.Net.Core/Entities/Users/IWebhookUser.cs b/src/Discord.Net.Core/Entities/Users/IWebhookUser.cs
index 8f4d42187..be769b944 100644
--- a/src/Discord.Net.Core/Entities/Users/IWebhookUser.cs
+++ b/src/Discord.Net.Core/Entities/Users/IWebhookUser.cs
@@ -1,6 +1,5 @@
namespace Discord
{
- //TODO: Add webhook endpoints
public interface IWebhookUser : IGuildUser
{
ulong WebhookId { get; }
diff --git a/src/Discord.Net.Core/Entities/Webhooks/IWebhook.cs b/src/Discord.Net.Core/Entities/Webhooks/IWebhook.cs
new file mode 100644
index 000000000..ef56f72b9
--- /dev/null
+++ b/src/Discord.Net.Core/Entities/Webhooks/IWebhook.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Threading.Tasks;
+
+namespace Discord
+{
+ public interface IWebhook : IDeletable, ISnowflakeEntity
+ {
+ /// Gets the token of this webhook.
+ string Token { get; }
+
+ /// Gets the default name of this webhook.
+ string Name { get; }
+ /// Gets the id of this webhook's default avatar.
+ string AvatarId { get; }
+ /// Gets the url to this webhook's default avatar.
+ string GetAvatarUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128);
+
+ /// Gets the channel for this webhook.
+ ITextChannel Channel { get; }
+ /// Gets the id of the channel for this webhook.
+ ulong ChannelId { get; }
+
+ /// Gets the guild owning this webhook.
+ IGuild Guild { get; }
+ /// Gets the id of the guild owning this webhook.
+ ulong? GuildId { get; }
+
+ /// Gets the user that created this webhook.
+ IUser Creator { get; }
+
+ /// Modifies this webhook.
+ Task ModifyAsync(Action func, RequestOptions options = null);
+ }
+}
diff --git a/src/Discord.Net.Core/Entities/Webhooks/WebhookProperties.cs b/src/Discord.Net.Core/Entities/Webhooks/WebhookProperties.cs
new file mode 100644
index 000000000..8759a1729
--- /dev/null
+++ b/src/Discord.Net.Core/Entities/Webhooks/WebhookProperties.cs
@@ -0,0 +1,41 @@
+namespace Discord
+{
+ ///
+ /// Modify an with the specified parameters.
+ ///
+ ///
+ ///
+ /// await webhook.ModifyAsync(x =>
+ /// {
+ /// x.Name = "Bob";
+ /// x.Avatar = new Image("avatar.jpg");
+ /// });
+ ///
+ ///
+ ///
+ public class WebhookProperties
+ {
+ ///
+ /// The default name of the webhook.
+ ///
+ public Optional Name { get; set; }
+ ///
+ /// The default avatar of the webhook.
+ ///
+ public Optional Image { get; set; }
+ ///
+ /// The channel for this webhook.
+ ///
+ ///
+ /// This field is not used when authenticated with .
+ ///
+ public Optional Channel { get; set; }
+ ///
+ /// The channel id for this webhook.
+ ///
+ ///
+ /// This field is not used when authenticated with .
+ ///
+ public Optional ChannelId { get; set; }
+ }
+}
diff --git a/src/Discord.Net.Core/IDiscordClient.cs b/src/Discord.Net.Core/IDiscordClient.cs
index 23e8e9c5b..9abb959b5 100644
--- a/src/Discord.Net.Core/IDiscordClient.cs
+++ b/src/Discord.Net.Core/IDiscordClient.cs
@@ -34,5 +34,7 @@ namespace Discord
Task> GetVoiceRegionsAsync(RequestOptions options = null);
Task GetVoiceRegionAsync(string id, RequestOptions options = null);
+
+ Task GetWebhookAsync(ulong id, RequestOptions options = null);
}
}
diff --git a/src/Discord.Net.Rest/API/Common/Webhook.cs b/src/Discord.Net.Rest/API/Common/Webhook.cs
new file mode 100644
index 000000000..cbd5fdad5
--- /dev/null
+++ b/src/Discord.Net.Rest/API/Common/Webhook.cs
@@ -0,0 +1,25 @@
+#pragma warning disable CS1591
+using Newtonsoft.Json;
+
+namespace Discord.API
+{
+ 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 Name { get; set; }
+ [JsonProperty("avatar")]
+ public Optional Avatar { get; set; }
+ [JsonProperty("guild_id")]
+ public Optional GuildId { get; set; }
+
+ [JsonProperty("user")]
+ public Optional Creator { get; set; }
+ }
+}
diff --git a/src/Discord.Net.Rest/API/Rest/CreateWebhookParams.cs b/src/Discord.Net.Rest/API/Rest/CreateWebhookParams.cs
new file mode 100644
index 000000000..0d1059fab
--- /dev/null
+++ b/src/Discord.Net.Rest/API/Rest/CreateWebhookParams.cs
@@ -0,0 +1,14 @@
+#pragma warning disable CS1591
+using Newtonsoft.Json;
+
+namespace Discord.API.Rest
+{
+ [JsonObject(MemberSerialization = MemberSerialization.OptIn)]
+ internal class CreateWebhookParams
+ {
+ [JsonProperty("name")]
+ public string Name { get; set; }
+ [JsonProperty("avatar")]
+ public Optional Avatar { get; set; }
+ }
+}
diff --git a/src/Discord.Net.Rest/API/Rest/ModifyWebhookParams.cs b/src/Discord.Net.Rest/API/Rest/ModifyWebhookParams.cs
new file mode 100644
index 000000000..0f2d6e33b
--- /dev/null
+++ b/src/Discord.Net.Rest/API/Rest/ModifyWebhookParams.cs
@@ -0,0 +1,16 @@
+#pragma warning disable CS1591
+using Newtonsoft.Json;
+
+namespace Discord.API.Rest
+{
+ [JsonObject(MemberSerialization = MemberSerialization.OptIn)]
+ internal class ModifyWebhookParams
+ {
+ [JsonProperty("name")]
+ public Optional Name { get; set; }
+ [JsonProperty("avatar")]
+ public Optional Avatar { get; set; }
+ [JsonProperty("channel_id")]
+ public Optional ChannelId { get; set; }
+ }
+}
diff --git a/src/Discord.Net.Rest/API/Rest/UploadWebhookFileParams.cs b/src/Discord.Net.Rest/API/Rest/UploadWebhookFileParams.cs
index f2c34c015..6d6eb29b2 100644
--- a/src/Discord.Net.Rest/API/Rest/UploadWebhookFileParams.cs
+++ b/src/Discord.Net.Rest/API/Rest/UploadWebhookFileParams.cs
@@ -1,7 +1,7 @@
#pragma warning disable CS1591
-using Discord.Net.Rest;
using System.Collections.Generic;
using System.IO;
+using Discord.Net.Rest;
namespace Discord.API.Rest
{
@@ -15,6 +15,7 @@ namespace Discord.API.Rest
public Optional IsTTS { get; set; }
public Optional Username { get; set; }
public Optional AvatarUrl { get; set; }
+ public Optional