diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/AuditLogHelper.cs b/src/Discord.Net.Rest/Entities/AuditLogs/AuditLogHelper.cs
index b3aaf582c..edbb2bea8 100644
--- a/src/Discord.Net.Rest/Entities/AuditLogs/AuditLogHelper.cs
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/AuditLogHelper.cs
@@ -52,6 +52,9 @@ namespace Discord.Rest
[ActionType.MessagePinned] = MessagePinAuditLogData.Create,
[ActionType.MessageUnpinned] = MessageUnpinAuditLogData.Create,
+ [ActionType.ThreadCreate] = ThreadCreateAuditLogData.Create,
+ [ActionType.ThreadUpdate] = ThreadUpdateAuditLogData.Create,
+ [ActionType.ThreadDelete] = ThreadDeleteAuditLogData.Create,
};
public static IAuditLogData CreateData(BaseDiscordClient discord, Model log, EntryModel entry)
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ThreadCreateAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ThreadCreateAuditLogData.cs
new file mode 100644
index 000000000..f1cacd727
--- /dev/null
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ThreadCreateAuditLogData.cs
@@ -0,0 +1,115 @@
+using System.Linq;
+
+using Model = Discord.API.AuditLog;
+using EntryModel = Discord.API.AuditLogEntry;
+
+namespace Discord.Rest
+{
+ ///
+ /// Contains a piece of audit log data related to a thread creation.
+ ///
+ public class ThreadCreateAuditLogData : IAuditLogData
+ {
+ private ThreadCreateAuditLogData(IThreadChannel thread, ulong id, string name, ThreadType type, bool archived,
+ ThreadArchiveDuration autoArchiveDuration, bool locked, int? rateLimit)
+ {
+ Thread = thread;
+ ThreadId = id;
+ ThreadName = name;
+ ThreadType = type;
+ IsArchived = archived;
+ AutoArchiveDuration = autoArchiveDuration;
+ IsLocked = locked;
+ SlowModeInterval = rateLimit;
+ }
+
+ internal static ThreadCreateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry)
+ {
+ var changes = entry.Changes;
+
+ var id = entry.TargetId.Value;
+
+ var nameModel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "name");
+ var typeModel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "type");
+
+ var archivedModel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "archived");
+ var autoArchiveDurationModel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "auto_archive_duration");
+ var lockedModel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "locked");
+ var rateLimitPerUserModel = changes.FirstOrDefault(x => x.ChangedProperty == "rate_limit_per_user");
+
+ var name = nameModel.NewValue.ToObject(discord.ApiClient.Serializer);
+ var type = typeModel.NewValue.ToObject(discord.ApiClient.Serializer);
+
+ var archived = archivedModel.NewValue.ToObject(discord.ApiClient.Serializer);
+ var autoArchiveDuration = autoArchiveDurationModel.NewValue.ToObject(discord.ApiClient.Serializer);
+ var locked = lockedModel.NewValue.ToObject(discord.ApiClient.Serializer);
+ var rateLimit = rateLimitPerUserModel?.NewValue?.ToObject(discord.ApiClient.Serializer);
+
+ var threadInfo = log.Threads.FirstOrDefault(x => x.Id == id);
+ var threadChannel = threadInfo == null ? null : RestThreadChannel.Create(discord, (IGuild)null, threadInfo);
+
+ return new ThreadCreateAuditLogData(threadChannel, id, name, type, archived, autoArchiveDuration, locked, rateLimit);
+ }
+
+ // Doc Note: Corresponds to the *current* data
+
+ ///
+ /// Gets the thread that was created if it still exists.
+ ///
+ ///
+ /// A thread object representing the thread that was created if it still exists, otherwise returns null.
+ ///
+ public IThreadChannel Thread { get; }
+ ///
+ /// Gets the snowflake ID of the thread.
+ ///
+ ///
+ /// A representing the snowflake identifier for the thread.
+ ///
+ public ulong ThreadId { get; }
+ ///
+ /// Gets the name of the thread.
+ ///
+ ///
+ /// A string containing the name of the thread.
+ ///
+ public string ThreadName { get; }
+ ///
+ /// Gets the type of the thread.
+ ///
+ ///
+ /// The type of thread.
+ ///
+ public ThreadType ThreadType { get; }
+ ///
+ /// Gets the value that indicates whether the thread is archived.
+ ///
+ ///
+ /// true if this thread has the Archived flag enabled; otherwise false.
+ ///
+ public bool IsArchived { get; }
+ ///
+ /// Gets the auto archive duration of the thread.
+ ///
+ ///
+ /// The thread auto archive duration of the thread.
+ ///
+ public ThreadArchiveDuration AutoArchiveDuration { get; }
+ ///
+ /// Gets the value that indicates whether the thread is locked.
+ ///
+ ///
+ /// true if this thread has the Locked flag enabled; otherwise false.
+ ///
+ public bool IsLocked { get; }
+ ///
+ /// Gets the slow-mode delay of the thread.
+ ///
+ ///
+ /// An representing the time in seconds required before the user can send another
+ /// message; 0 if disabled.
+ /// null if this is not mentioned in this entry.
+ ///
+ public int? SlowModeInterval { get; }
+ }
+}
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ThreadDeleteAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ThreadDeleteAuditLogData.cs
new file mode 100644
index 000000000..962ec1773
--- /dev/null
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ThreadDeleteAuditLogData.cs
@@ -0,0 +1,103 @@
+using System.Linq;
+
+using Model = Discord.API.AuditLog;
+using EntryModel = Discord.API.AuditLogEntry;
+
+namespace Discord.Rest
+{
+ ///
+ /// Contains a piece of audit log data related to a thread deletion.
+ ///
+ public class ThreadDeleteAuditLogData : IAuditLogData
+ {
+ private ThreadDeleteAuditLogData(ulong id, string name, ThreadType type, bool archived,
+ ThreadArchiveDuration autoArchiveDuration, bool locked, int? rateLimit)
+ {
+ ThreadId = id;
+ ThreadName = name;
+ ThreadType = type;
+ IsArchived = archived;
+ AutoArchiveDuration = autoArchiveDuration;
+ IsLocked = locked;
+ SlowModeInterval = rateLimit;
+ }
+
+ internal static ThreadDeleteAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry)
+ {
+ var changes = entry.Changes;
+
+ var id = entry.TargetId.Value;
+ var thread = log.Threads.FirstOrDefault(x => x.Id == id);
+
+ var nameModel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "name");
+ var typeModel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "type");
+
+ var archivedModel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "archived");
+ var autoArchiveDurationModel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "auto_archive_duration");
+ var lockedModel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "locked");
+ var rateLimitPerUserModel = changes.FirstOrDefault(x => x.ChangedProperty == "rate_limit_per_user");
+
+ var name = nameModel.OldValue.ToObject(discord.ApiClient.Serializer);
+ var type = typeModel.OldValue.ToObject(discord.ApiClient.Serializer);
+
+ var archived = archivedModel.OldValue.ToObject(discord.ApiClient.Serializer);
+ var autoArchiveDuration = autoArchiveDurationModel.OldValue.ToObject(discord.ApiClient.Serializer);
+ var locked = lockedModel.OldValue.ToObject(discord.ApiClient.Serializer);
+ var rateLimit = rateLimitPerUserModel?.NewValue?.ToObject(discord.ApiClient.Serializer);
+
+ return new ThreadDeleteAuditLogData(id, name, type, archived, autoArchiveDuration, locked, rateLimit);
+ }
+
+ ///
+ /// Gets the snowflake ID of the deleted thread.
+ ///
+ ///
+ /// A representing the snowflake identifier for the deleted thread.
+ ///
+ public ulong ThreadId { get; }
+ ///
+ /// Gets the name of the deleted thread.
+ ///
+ ///
+ /// A string containing the name of the deleted thread.
+ ///
+ public string ThreadName { get; }
+ ///
+ /// Gets the type of the deleted thread.
+ ///
+ ///
+ /// The type of thread that was deleted.
+ ///
+ public ThreadType ThreadType { get; }
+ ///
+ /// Gets the value that indicates whether the deleted thread was archived.
+ ///
+ ///
+ /// true if this thread had the Archived flag enabled; otherwise false.
+ ///
+ public bool IsArchived { get; }
+ ///
+ /// Gets the thread auto archive duration of the deleted thread.
+ ///
+ ///
+ /// The thread auto archive duration of the thread that was deleted.
+ ///
+ public ThreadArchiveDuration AutoArchiveDuration { get; }
+ ///
+ /// Gets the value that indicates whether the deleted thread was locked.
+ ///
+ ///
+ /// true if this thread had the Locked flag enabled; otherwise false.
+ ///
+ public bool IsLocked { get; }
+ ///
+ /// Gets the slow-mode delay of the deleted thread.
+ ///
+ ///
+ /// An representing the time in seconds required before the user can send another
+ /// message; 0 if disabled.
+ /// null if this is not mentioned in this entry.
+ ///
+ public int? SlowModeInterval { get; }
+ }
+}
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ThreadInfo.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ThreadInfo.cs
new file mode 100644
index 000000000..0e01ba8a7
--- /dev/null
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ThreadInfo.cs
@@ -0,0 +1,39 @@
+namespace Discord.Rest
+{
+ ///
+ /// Represents information for a thread.
+ ///
+ public class ThreadInfo
+ {
+ ///
+ /// Gets the name of the thread.
+ ///
+ public string Name { get; }
+ ///
+ /// Gets the value that indicates whether the thread is archived.
+ ///
+ public bool IsArchived { get; }
+ ///
+ /// Gets the auto archive duration of thread.
+ ///
+ public ThreadArchiveDuration AutoArchiveDuration { get; }
+ ///
+ /// Gets the value that indicates whether the thread is locked.
+ ///
+ public bool IsLocked { get; }
+
+ ///
+ /// Gets the slow-mode delay of the ´thread.
+ ///
+ public int? SlowModeInterval { get; }
+
+ internal ThreadInfo(string name, bool archived, ThreadArchiveDuration autoArchiveDuration, bool locked, int? rateLimit)
+ {
+ Name = name;
+ IsArchived = archived;
+ AutoArchiveDuration = autoArchiveDuration;
+ IsLocked = locked;
+ SlowModeInterval = rateLimit;
+ }
+ }
+}
diff --git a/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ThreadUpdateAuditLogData.cs b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ThreadUpdateAuditLogData.cs
new file mode 100644
index 000000000..2b9b95418
--- /dev/null
+++ b/src/Discord.Net.Rest/Entities/AuditLogs/DataTypes/ThreadUpdateAuditLogData.cs
@@ -0,0 +1,88 @@
+using System.Linq;
+
+using Model = Discord.API.AuditLog;
+using EntryModel = Discord.API.AuditLogEntry;
+
+namespace Discord.Rest
+{
+ ///
+ /// Contains a piece of audit log data related to a thread update.
+ ///
+ public class ThreadUpdateAuditLogData : IAuditLogData
+ {
+ private ThreadUpdateAuditLogData(IThreadChannel thread, ThreadType type, ThreadInfo before, ThreadInfo after)
+ {
+ Thread = thread;
+ ThreadType = type;
+ Before = before;
+ After = After;
+ }
+
+ internal static ThreadUpdateAuditLogData Create(BaseDiscordClient discord, Model log, EntryModel entry)
+ {
+ var changes = entry.Changes;
+
+ var id = entry.TargetId.Value;
+
+ var nameModel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "name");
+ var typeModel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "type");
+
+ var archivedModel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "archived");
+ var autoArchiveDurationModel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "auto_archive_duration");
+ var lockedModel = entry.Changes.FirstOrDefault(x => x.ChangedProperty == "locked");
+ var rateLimitPerUserModel = changes.FirstOrDefault(x => x.ChangedProperty == "rate_limit_per_user");
+
+ var type = typeModel.OldValue.ToObject(discord.ApiClient.Serializer);
+
+ var oldName = nameModel.OldValue.ToObject(discord.ApiClient.Serializer);
+ var oldArchived = archivedModel.OldValue.ToObject(discord.ApiClient.Serializer);
+ var oldAutoArchiveDuration = autoArchiveDurationModel.OldValue.ToObject(discord.ApiClient.Serializer);
+ var oldLocked = lockedModel.OldValue.ToObject(discord.ApiClient.Serializer);
+ var oldRateLimit = rateLimitPerUserModel?.OldValue?.ToObject(discord.ApiClient.Serializer);
+ var before = new ThreadInfo(oldName, oldArchived, oldAutoArchiveDuration, oldLocked, oldRateLimit);
+
+ var newName = nameModel.NewValue.ToObject(discord.ApiClient.Serializer);
+ var newArchived = archivedModel.NewValue.ToObject(discord.ApiClient.Serializer);
+ var newAutoArchiveDuration = autoArchiveDurationModel.NewValue.ToObject(discord.ApiClient.Serializer);
+ var newLocked = lockedModel.NewValue.ToObject(discord.ApiClient.Serializer);
+ var newRateLimit = rateLimitPerUserModel?.NewValue?.ToObject(discord.ApiClient.Serializer);
+ var after = new ThreadInfo(newName, newArchived, newAutoArchiveDuration, newLocked, newRateLimit);
+
+ var threadInfo = log.Threads.FirstOrDefault(x => x.Id == id);
+ var threadChannel = threadInfo == null ? null : RestThreadChannel.Create(discord, (IGuild)null, threadInfo);
+
+ return new ThreadUpdateAuditLogData(threadChannel,type, before, after);
+ }
+
+ // Doc Note: Corresponds to the *current* data
+
+ ///
+ /// Gets the thread that was created if it still exists.
+ ///
+ ///
+ /// A thread object representing the thread that was created if it still exists, otherwise returns null.
+ ///
+ public IThreadChannel Thread { get; }
+ ///
+ /// Gets the type of the thread.
+ ///
+ ///
+ /// The type of thread.
+ ///
+ public ThreadType ThreadType { get; }
+ ///
+ /// Gets the thread information before the changes.
+ ///
+ ///
+ /// A thread information object representing the thread before the changes were made.
+ ///
+ public ThreadInfo Before { get; }
+ ///
+ /// Gets the thread information after the changes.
+ ///
+ ///
+ /// A thread information object representing the thread after the changes were made.
+ ///
+ public ThreadInfo After { get; }
+ }
+}