diff --git a/samples/QQBot.Net.Samples.SimpleBot/Program.cs b/samples/QQBot.Net.Samples.SimpleBot/Program.cs
index 0a7c606..29b479c 100644
--- a/samples/QQBot.Net.Samples.SimpleBot/Program.cs
+++ b/samples/QQBot.Net.Samples.SimpleBot/Program.cs
@@ -1,6 +1,7 @@
// See https://aka.ms/new-console-template for more information
using QQBot;
+using QQBot.Rest;
using QQBot.WebSocket;
QQBotSocketClient client = new(new QQBotSocketConfig
@@ -19,13 +20,21 @@
client.MessageReceived += async message =>
{
if (message.Source is not MessageSource.User) return;
- IUserMessage msg = await message.ReplyAsync($"""
- [Content] {message.Content}
- [Content] {Format.Escape(message.Content)}
- [Content] {Format.Sanitize(message.Content)}
- [Attachments] {message.Attachments.Count}
- """
- );
+ if (message.Channel is SocketTextChannel textChannel)
+ {
+ var channel = await textChannel.Guild.CreateApplicationChannelAsync(message.Content, x =>
+ {
+ x.ApplicationType = ChannelApplication.GameForPeace;
+ });
+ }
+
+// IUserMessage msg = await message.ReplyAsync(
+// $"""
+// [Content] {message.Content}
+// [Content] {Format.Escape(message.Content)}
+// [Content] {Format.Sanitize(message.Content)}
+// [Attachments] {message.Attachments.Count}
+// """);
};
await client.LoginAsync(0, TokenType.BotToken, "");
await client.StartAsync();
diff --git a/src/QQBot.Net.Core/Entities/Channels/ChannelType.cs b/src/QQBot.Net.Core/Entities/Channels/ChannelType.cs
index b4b6abb..7e3320e 100644
--- a/src/QQBot.Net.Core/Entities/Channels/ChannelType.cs
+++ b/src/QQBot.Net.Core/Entities/Channels/ChannelType.cs
@@ -38,5 +38,10 @@ public enum ChannelType
///
/// 论坛子频道。
///
- Forum = 10007
+ Forum = 10007,
+
+ ///
+ /// 日程子频道。
+ ///
+ Schedule = 10011,
}
diff --git a/src/QQBot.Net.Core/Entities/Channels/CreateApplicationChannelProperties.cs b/src/QQBot.Net.Core/Entities/Channels/CreateApplicationChannelProperties.cs
new file mode 100644
index 0000000..a329d6a
--- /dev/null
+++ b/src/QQBot.Net.Core/Entities/Channels/CreateApplicationChannelProperties.cs
@@ -0,0 +1,13 @@
+namespace QQBot;
+
+///
+/// 提供用于创建 的属性。
+///
+///
+public class CreateApplicationChannelProperties : CreateNestedChannelProperties
+{
+ ///
+ /// 获取或设置要设置到此频道的应用频道类型。
+ ///
+ public ChannelApplication? ApplicationType { get; set; }
+}
\ No newline at end of file
diff --git a/src/QQBot.Net.Core/Entities/Channels/CreateCategoryChannelProperties.cs b/src/QQBot.Net.Core/Entities/Channels/CreateCategoryChannelProperties.cs
new file mode 100644
index 0000000..6069b4a
--- /dev/null
+++ b/src/QQBot.Net.Core/Entities/Channels/CreateCategoryChannelProperties.cs
@@ -0,0 +1,17 @@
+namespace QQBot;
+
+///
+/// 提供用于创建 的属性。
+///
+///
+public class CreateCategoryChannelProperties : CreateGuildChannelProperties
+{
+ ///
+ /// 获取或设置要设置到此频道的位置。
+ ///
+ ///
+ /// 更小的数值表示更靠近列表顶部的位置。设置为与同分组下的其他频道相同的值,将会使当前频道排列于与该频道相邻更靠近列表顶部的位置。
+ /// 分组频道的位置顺序号至少为 2。
+ ///
+ public int Position { get; set; } = 2;
+}
diff --git a/src/QQBot.Net.Core/Entities/Channels/CreateForumChannelProperties.cs b/src/QQBot.Net.Core/Entities/Channels/CreateForumChannelProperties.cs
new file mode 100644
index 0000000..2d32a68
--- /dev/null
+++ b/src/QQBot.Net.Core/Entities/Channels/CreateForumChannelProperties.cs
@@ -0,0 +1,7 @@
+namespace QQBot;
+
+///
+/// 提供用于创建 的属性。
+///
+///
+public class CreateForumChannelProperties : CreateNestedChannelProperties;
\ No newline at end of file
diff --git a/src/QQBot.Net.Core/Entities/Channels/CreateGuildChannelProperties.cs b/src/QQBot.Net.Core/Entities/Channels/CreateGuildChannelProperties.cs
new file mode 100644
index 0000000..a1cc462
--- /dev/null
+++ b/src/QQBot.Net.Core/Entities/Channels/CreateGuildChannelProperties.cs
@@ -0,0 +1,6 @@
+namespace QQBot;
+
+///
+/// 提供用于创建 的属性。
+///
+public class CreateGuildChannelProperties;
\ No newline at end of file
diff --git a/src/QQBot.Net.Core/Entities/Channels/CreateLiveStreamChannelProperties.cs b/src/QQBot.Net.Core/Entities/Channels/CreateLiveStreamChannelProperties.cs
new file mode 100644
index 0000000..45d3d28
--- /dev/null
+++ b/src/QQBot.Net.Core/Entities/Channels/CreateLiveStreamChannelProperties.cs
@@ -0,0 +1,7 @@
+namespace QQBot;
+
+///
+/// 提供用于创建 的属性。
+///
+///
+public class CreateLiveStreamChannelProperties : CreateNestedChannelProperties;
diff --git a/src/QQBot.Net.Core/Entities/Channels/CreateNestedChannelProperties.cs b/src/QQBot.Net.Core/Entities/Channels/CreateNestedChannelProperties.cs
new file mode 100644
index 0000000..33cbf91
--- /dev/null
+++ b/src/QQBot.Net.Core/Entities/Channels/CreateNestedChannelProperties.cs
@@ -0,0 +1,26 @@
+namespace QQBot;
+
+///
+/// 提供用于创建 的属性。
+///
+public class CreateNestedChannelProperties : CreateGuildChannelProperties
+{
+ // ///
+ // /// 获取或设置要设置到此频道的所属分组频道的 ID。
+ // ///
+ // ///
+ // /// 将此值设置为某分组频道的 ID 可以使新建频道位于该分组频道下;将此值设置为 null
+ // /// 可以使新建频道位于服务器所有分组频道的上方,即不属于任何分组频道。
+ // ///
+ // public ulong? CategoryId { get; set; }
+
+ ///
+ /// 获取或设置要设置到此频道的私有频道类型。
+ ///
+ public PrivateType? PrivateType { get; set; }
+
+ ///
+ /// 获取或设置要设置到此频道的发言权限。
+ ///
+ public SpeakPermission? SpeakPermission { get; set; }
+}
\ No newline at end of file
diff --git a/src/QQBot.Net.Core/Entities/Channels/CreateScheduleChannelProperties.cs b/src/QQBot.Net.Core/Entities/Channels/CreateScheduleChannelProperties.cs
new file mode 100644
index 0000000..058ef81
--- /dev/null
+++ b/src/QQBot.Net.Core/Entities/Channels/CreateScheduleChannelProperties.cs
@@ -0,0 +1,7 @@
+namespace QQBot;
+
+///
+/// 提供用于创建 的属性。
+///
+///
+public class CreateScheduleChannelProperties : CreateNestedChannelProperties;
\ No newline at end of file
diff --git a/src/QQBot.Net.Core/Entities/Channels/CreateTextChannelProperties.cs b/src/QQBot.Net.Core/Entities/Channels/CreateTextChannelProperties.cs
new file mode 100644
index 0000000..1787c42
--- /dev/null
+++ b/src/QQBot.Net.Core/Entities/Channels/CreateTextChannelProperties.cs
@@ -0,0 +1,13 @@
+namespace QQBot;
+
+///
+/// 提供用于创建 的属性。
+///
+///
+public class CreateTextChannelProperties : CreateNestedChannelProperties
+{
+ ///
+ /// 获取或设置要设置到此频道的子频道二级分类。
+ ///
+ public ChannelSubType? SubType { get; set; }
+}
diff --git a/src/QQBot.Net.Core/Entities/Channels/CreateVoiceChannelProperties.cs b/src/QQBot.Net.Core/Entities/Channels/CreateVoiceChannelProperties.cs
new file mode 100644
index 0000000..8e9c935
--- /dev/null
+++ b/src/QQBot.Net.Core/Entities/Channels/CreateVoiceChannelProperties.cs
@@ -0,0 +1,7 @@
+namespace QQBot;
+
+///
+/// 提供用于创建 的属性。
+///
+///
+public class CreateVoiceChannelProperties : CreateNestedChannelProperties;
\ No newline at end of file
diff --git a/src/QQBot.Net.Core/Entities/Channels/ICategoryChannel.cs b/src/QQBot.Net.Core/Entities/Channels/ICategoryChannel.cs
index daa1dff..5b95ddd 100644
--- a/src/QQBot.Net.Core/Entities/Channels/ICategoryChannel.cs
+++ b/src/QQBot.Net.Core/Entities/Channels/ICategoryChannel.cs
@@ -3,7 +3,4 @@ namespace QQBot;
///
/// 表示一个分组子频道。
///
-public interface ICategoryChannel : IGuildChannel
-{
-
-}
+public interface ICategoryChannel : IGuildChannel;
diff --git a/src/QQBot.Net.Core/Entities/Channels/IForumChannel.cs b/src/QQBot.Net.Core/Entities/Channels/IForumChannel.cs
index 1d925a6..7064813 100644
--- a/src/QQBot.Net.Core/Entities/Channels/IForumChannel.cs
+++ b/src/QQBot.Net.Core/Entities/Channels/IForumChannel.cs
@@ -3,7 +3,4 @@ namespace QQBot;
///
/// 表示一个论坛子频道。
///
-public interface IForumChannel : INestedChannel
-{
-
-}
+public interface IForumChannel : INestedChannel;
diff --git a/src/QQBot.Net.Core/Entities/Channels/ILiveStreamChannel.cs b/src/QQBot.Net.Core/Entities/Channels/ILiveStreamChannel.cs
index 0f3ef1c..7f1edce 100644
--- a/src/QQBot.Net.Core/Entities/Channels/ILiveStreamChannel.cs
+++ b/src/QQBot.Net.Core/Entities/Channels/ILiveStreamChannel.cs
@@ -3,7 +3,4 @@ namespace QQBot;
///
/// 表示一个直播子频道。
///
-public interface ILiveStreamChannel : INestedChannel
-{
-
-}
+public interface ILiveStreamChannel : INestedChannel;
diff --git a/src/QQBot.Net.Core/Entities/Channels/INestedChannel.cs b/src/QQBot.Net.Core/Entities/Channels/INestedChannel.cs
index 270dff4..eef615b 100644
--- a/src/QQBot.Net.Core/Entities/Channels/INestedChannel.cs
+++ b/src/QQBot.Net.Core/Entities/Channels/INestedChannel.cs
@@ -14,7 +14,7 @@ public interface INestedChannel : IGuildChannel
///
/// 获取此子频道的私密类型。
///
- ChannelPrivateType? PrivateType { get; }
+ PrivateType? PrivateType { get; }
///
/// 获取此子频道的发言权限。
diff --git a/src/QQBot.Net.Core/Entities/Channels/IScheduleChannel.cs b/src/QQBot.Net.Core/Entities/Channels/IScheduleChannel.cs
new file mode 100644
index 0000000..249643c
--- /dev/null
+++ b/src/QQBot.Net.Core/Entities/Channels/IScheduleChannel.cs
@@ -0,0 +1,6 @@
+namespace QQBot;
+
+///
+/// 表示一个日程子频道。
+///
+public interface IScheduleChannel : INestedChannel;
diff --git a/src/QQBot.Net.Core/Entities/Channels/IVoiceChannel.cs b/src/QQBot.Net.Core/Entities/Channels/IVoiceChannel.cs
index d53ad20..d64799f 100644
--- a/src/QQBot.Net.Core/Entities/Channels/IVoiceChannel.cs
+++ b/src/QQBot.Net.Core/Entities/Channels/IVoiceChannel.cs
@@ -3,7 +3,4 @@ namespace QQBot;
///
/// 表示一个语音子频道。
///
-public interface IVoiceChannel : INestedChannel
-{
-
-}
+public interface IVoiceChannel : INestedChannel;
diff --git a/src/QQBot.Net.Core/Entities/Channels/ChannelPrivateType.cs b/src/QQBot.Net.Core/Entities/Channels/PrivateType.cs
similarity index 92%
rename from src/QQBot.Net.Core/Entities/Channels/ChannelPrivateType.cs
rename to src/QQBot.Net.Core/Entities/Channels/PrivateType.cs
index c9c4177..8b3fec5 100644
--- a/src/QQBot.Net.Core/Entities/Channels/ChannelPrivateType.cs
+++ b/src/QQBot.Net.Core/Entities/Channels/PrivateType.cs
@@ -3,7 +3,7 @@
///
/// 表示一个子频道的私密类型。
///
-public enum ChannelPrivateType
+public enum PrivateType
{
///
/// 公开子频道。
diff --git a/src/QQBot.Net.Core/Entities/Guilds/IGuild.cs b/src/QQBot.Net.Core/Entities/Guilds/IGuild.cs
index 87876aa..0a3d34b 100644
--- a/src/QQBot.Net.Core/Entities/Guilds/IGuild.cs
+++ b/src/QQBot.Net.Core/Entities/Guilds/IGuild.cs
@@ -160,6 +160,23 @@ public interface IGuild : IEntity
/// 一个表示异步获取操作的任务。任务的结果包含与指定的 关联的具有语音聊天能力的子频道;如果未找到,则返回 null。
Task GetVoiceChannelAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions? options = null);
+ ///
+ /// 获取此频道的所有直播子频道。
+ ///
+ /// 指示当前方法是否应该仅从缓存中获取结果,还是可以通过 API 请求获取数据。
+ /// 发送请求时要使用的选项。
+ /// 一个表示异步获取操作的任务。任务的结果包含此频道的所有直播子频道。
+ Task> GetLiveStreamChannelsAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions? options = null);
+
+ ///
+ /// 获取此频道内的直播子频道。
+ ///
+ /// 要获取的直播子频道的 ID。
+ /// 指示当前方法是否应该仅从缓存中获取结果,还是可以通过 API 请求获取数据。
+ /// 发送请求时要使用的选项。
+ /// 一个表示异步获取操作的任务。任务的结果包含与指定的 关联的直播子频道;如果未找到,则返回 null。
+ Task GetLiveStreamChannelAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions? options = null);
+
///
/// 获取此频道的所有应用子频道。
///
@@ -195,21 +212,21 @@ public interface IGuild : IEntity
Task GetForumChannelAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions? options = null);
///
- /// 获取此频道的所有直播子频道。
+ /// 获取此频道的所有日程子频道。
///
/// 指示当前方法是否应该仅从缓存中获取结果,还是可以通过 API 请求获取数据。
/// 发送请求时要使用的选项。
- /// 一个表示异步获取操作的任务。任务的结果包含此频道的所有直播子频道。
- Task> GetLiveStreamChannelsAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions? options = null);
+ /// 一个表示异步获取操作的任务。任务的结果包含此频道的所有日程子频道。
+ Task> GetScheduleChannelsAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions? options = null);
///
- /// 获取此频道内的直播子频道。
+ /// 获取此频道内的日程子频道。
///
- /// 要获取的直播子频道的 ID。
+ /// 要获取的日程子频道的 ID。
/// 指示当前方法是否应该仅从缓存中获取结果,还是可以通过 API 请求获取数据。
/// 发送请求时要使用的选项。
- /// 一个表示异步获取操作的任务。任务的结果包含与指定的 关联的直播子频道;如果未找到,则返回 null。
- Task GetLiveStreamChannelAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions? options = null);
+ /// 一个表示异步获取操作的任务。任务的结果包含与指定的 关联的日程子频道;如果未找到,则返回 null。
+ Task GetScheduleChannelAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions? options = null);
///
/// 获取此频道的所有分组子频道。
@@ -228,5 +245,68 @@ public interface IGuild : IEntity
/// 一个表示异步获取操作的任务。任务的结果包含与指定的 关联的分组子频道;如果未找到,则返回 null。
Task GetCategoryChannelAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions? options = null);
+ ///
+ /// 在此服务器内创建一个新的文字子频道。
+ ///
+ /// 频道的名称。
+ /// 一个包含要应用到新创建频道的配置的委托。
+ /// 发送请求时要使用的选项。
+ /// 一个表示异步创建操作的任务。任务的结果包含新创建的文字频道。
+ Task CreateTextChannelAsync(string name, Action? func = null, RequestOptions? options = null);
+
+ ///
+ /// 在此服务器内创建一个新的语音子频道。
+ ///
+ /// 频道的名称。
+ /// 一个包含要应用到新创建频道的配置的委托。
+ /// 发送请求时要使用的选项。
+ /// 一个表示异步创建操作的任务。任务的结果包含新创建的语音频道。
+ Task CreateVoiceChannelAsync(string name, Action? func = null, RequestOptions? options = null);
+
+ ///
+ /// 在此服务器内创建一个新的直播子频道。
+ ///
+ /// 频道的名称。
+ /// 一个包含要应用到新创建频道的配置的委托。
+ /// 发送请求时要使用的选项。
+ /// 一个表示异步创建操作的任务。任务的结果包含新创建的直播频道。
+ Task CreateLiveStreamChannelAsync(string name, Action? func = null, RequestOptions? options = null);
+
+ ///
+ /// 在此服务器内创建一个新的应用子频道。
+ ///
+ /// 频道的名称。
+ /// 一个包含要应用到新创建频道的配置的委托。
+ /// 发送请求时要使用的选项。
+ /// 一个表示异步创建操作的任务。任务的结果包含新创建的应用频道。
+ Task CreateApplicationChannelAsync(string name, Action? func = null, RequestOptions? options = null);
+
+ ///
+ /// 在此服务器内创建一个新的论坛子频道。
+ ///
+ /// 频道的名称。
+ /// 一个包含要应用到新创建频道的配置的委托。
+ /// 发送请求时要使用的选项。
+ /// 一个表示异步创建操作的任务。任务的结果包含新创建的论坛频道。
+ Task CreateForumChannelAsync(string name, Action? func = null, RequestOptions? options = null);
+
+ ///
+ /// 在此服务器内创建一个新的日程子频道。
+ ///
+ /// 频道的名称。
+ /// 一个包含要应用到新创建频道的配置的委托。
+ /// 发送请求时要使用的选项。
+ /// 一个表示异步创建操作的任务。任务的结果包含新创建的日程频道。
+ Task CreateScheduleChannelAsync(string name, Action? func = null, RequestOptions? options = null);
+
+ ///
+ /// 在此服务器内创建一个新的分组子频道。
+ ///
+ /// 频道的名称。
+ /// 一个包含要应用到新创建频道的配置的委托。
+ /// 发送请求时要使用的选项。
+ /// 一个表示异步创建操作的任务。任务的结果包含新创建的分组频道。
+ Task CreateCategoryChannelAsync(string name, Action? func = null, RequestOptions? options = null);
+
#endregion
}
diff --git a/src/QQBot.Net.Core/Net/HttpException.cs b/src/QQBot.Net.Core/Net/HttpException.cs
index 6b33ee7..cad6371 100644
--- a/src/QQBot.Net.Core/Net/HttpException.cs
+++ b/src/QQBot.Net.Core/Net/HttpException.cs
@@ -68,6 +68,6 @@ private static string CreateMessage(HttpStatusCode httpCode, QQBotErrorCode? qqB
string closeInfo = qqBotCode.HasValue && qqBotCode != 0
? qqBotCode.Value.ToString()
: httpCode.ToString();
- return $"The server responded with error {closeInfo}: {reason ?? httpCode.ToString()} ({closeCode}, {traceId})";
+ return $"The server responded with error {closeInfo}: {reason ?? httpCode.ToString()} ({closeCode}{(traceId is not null ? $", trace ID: {traceId}" : string.Empty)})";
}
}
diff --git a/src/QQBot.Net.Core/QQBotErrorCode.cs b/src/QQBot.Net.Core/QQBotErrorCode.cs
index 006fb91..4573bed 100644
--- a/src/QQBot.Net.Core/QQBotErrorCode.cs
+++ b/src/QQBot.Net.Core/QQBotErrorCode.cs
@@ -87,6 +87,16 @@ public enum QQBotErrorCode
#endregion
+ #region SubChannel (200XXX)
+
+ CreateChannelSecurityHit = 200011,
+ CreateChannelSuccessButGetInfoError = 200013,
+ NameEmpty = 200016,
+ PositionError = 200017,
+ CreateChannelCategoryError = 200019,
+
+ #endregion
+
#region SubChannel Permission Errors (301XXX)
SubChannelInvalidParameter = 301000,
diff --git a/src/QQBot.Net.Core/Utils/Preconditions.cs b/src/QQBot.Net.Core/Utils/Preconditions.cs
index f629c14..d25e206 100644
--- a/src/QQBot.Net.Core/Utils/Preconditions.cs
+++ b/src/QQBot.Net.Core/Utils/Preconditions.cs
@@ -13,7 +13,7 @@ internal static class Preconditions
#region Objects
/// 不可为 null.
- public static void NotNull([NotNull] T? obj, string name, string? msg = null) where T : class
+ public static void NotNull([NotNull] T? obj, string name, string? msg = null)
{
if (obj == null)
throw CreateNotNullException(name, msg);
diff --git a/src/QQBot.Net.Rest/API/Common/Channel.cs b/src/QQBot.Net.Rest/API/Common/Channel.cs
index 7b6cd9d..7eba56f 100644
--- a/src/QQBot.Net.Rest/API/Common/Channel.cs
+++ b/src/QQBot.Net.Rest/API/Common/Channel.cs
@@ -30,7 +30,7 @@ internal class Channel
public required ulong OwnerId { get; set; }
[JsonPropertyName("private_type")]
- public ChannelPrivateType? PrivateType { get; set; }
+ public PrivateType? PrivateType { get; set; }
[JsonPropertyName("speak_permission")]
public SpeakPermission? SpeakPermission { get; set; }
diff --git a/src/QQBot.Net.Rest/API/Rest/CreateChannelParams.cs b/src/QQBot.Net.Rest/API/Rest/CreateChannelParams.cs
index 8026cc5..d91f062 100644
--- a/src/QQBot.Net.Rest/API/Rest/CreateChannelParams.cs
+++ b/src/QQBot.Net.Rest/API/Rest/CreateChannelParams.cs
@@ -15,19 +15,19 @@ internal class CreateChannelParams
public ChannelSubType? SubType { get; set; }
[JsonPropertyName("position")]
- public int Position { get; set; }
+ public int? Position { get; set; }
[JsonPropertyName("parent_id")]
public ulong? CategoryId { get; set; }
[JsonPropertyName("private_type")]
- public ChannelPrivateType? PrivateType { get; set; }
+ public PrivateType? PrivateType { get; set; }
[JsonPropertyName("private_user_ids")]
public ulong[]? PrivateUserIds { get; set; }
[JsonPropertyName("speak_permission")]
- public SpeakPermission SpeakPermission { get; set; }
+ public SpeakPermission? SpeakPermission { get; set; }
[JsonPropertyName("application_id")]
[JsonConverter(typeof(ChannelApplicationJsonConverter))]
diff --git a/src/QQBot.Net.Rest/API/Rest/ModifyChannelParams.cs b/src/QQBot.Net.Rest/API/Rest/ModifyChannelParams.cs
index 8bae73c..72aafcf 100644
--- a/src/QQBot.Net.Rest/API/Rest/ModifyChannelParams.cs
+++ b/src/QQBot.Net.Rest/API/Rest/ModifyChannelParams.cs
@@ -14,7 +14,7 @@ internal class ModifyChannelParams
public ulong? CategoryId { get; set; }
[JsonPropertyName("private_type")]
- public ChannelPrivateType? PrivateType { get; set; }
+ public PrivateType? PrivateType { get; set; }
[JsonPropertyName("speak_permission")]
public SpeakPermission SpeakPermission { get; set; }
diff --git a/src/QQBot.Net.Rest/Entities/Channels/RestApplicationChannel.cs b/src/QQBot.Net.Rest/Entities/Channels/RestApplicationChannel.cs
index a00762b..1071ed9 100644
--- a/src/QQBot.Net.Rest/Entities/Channels/RestApplicationChannel.cs
+++ b/src/QQBot.Net.Rest/Entities/Channels/RestApplicationChannel.cs
@@ -13,7 +13,7 @@ public class RestApplicationChannel : RestGuildChannel, IApplicationChannel
public ulong? CategoryId { get; private set; }
///
- public ChannelPrivateType? PrivateType { get; private set; }
+ public PrivateType? PrivateType { get; private set; }
///
public SpeakPermission? SpeakPermission { get; private set; }
diff --git a/src/QQBot.Net.Rest/Entities/Channels/RestForumChannel.cs b/src/QQBot.Net.Rest/Entities/Channels/RestForumChannel.cs
index ab180bb..10e50a1 100644
--- a/src/QQBot.Net.Rest/Entities/Channels/RestForumChannel.cs
+++ b/src/QQBot.Net.Rest/Entities/Channels/RestForumChannel.cs
@@ -13,7 +13,7 @@ public class RestForumChannel : RestGuildChannel, IForumChannel
public ulong? CategoryId { get; private set; }
///
- public ChannelPrivateType? PrivateType { get; private set; }
+ public PrivateType? PrivateType { get; private set; }
///
public SpeakPermission? SpeakPermission { get; private set; }
diff --git a/src/QQBot.Net.Rest/Entities/Channels/RestGuildChannel.cs b/src/QQBot.Net.Rest/Entities/Channels/RestGuildChannel.cs
index f08fc3a..db66a4e 100644
--- a/src/QQBot.Net.Rest/Entities/Channels/RestGuildChannel.cs
+++ b/src/QQBot.Net.Rest/Entities/Channels/RestGuildChannel.cs
@@ -45,6 +45,7 @@ internal static RestGuildChannel Create(BaseQQBotClient client, IGuild guild, Mo
ChannelType.LiveStream => RestLiveStreamChannel.Create(client, guild, model),
ChannelType.Application => RestApplicationChannel.Create(client, guild, model),
ChannelType.Forum => RestForumChannel.Create(client, guild, model),
+ ChannelType.Schedule => RestScheduleChannel.Create(client, guild, model),
_ => new RestGuildChannel(client, model.Id, guild)
};
diff --git a/src/QQBot.Net.Rest/Entities/Channels/RestLiveStreamChannel.cs b/src/QQBot.Net.Rest/Entities/Channels/RestLiveStreamChannel.cs
index 0d5c9c0..d0431ab 100644
--- a/src/QQBot.Net.Rest/Entities/Channels/RestLiveStreamChannel.cs
+++ b/src/QQBot.Net.Rest/Entities/Channels/RestLiveStreamChannel.cs
@@ -13,7 +13,7 @@ public class RestLiveStreamChannel : RestGuildChannel, ILiveStreamChannel
public ulong? CategoryId { get; private set; }
///
- public ChannelPrivateType? PrivateType { get; private set; }
+ public PrivateType? PrivateType { get; private set; }
///
public SpeakPermission? SpeakPermission { get; private set; }
diff --git a/src/QQBot.Net.Rest/Entities/Channels/RestScheduleChannel.cs b/src/QQBot.Net.Rest/Entities/Channels/RestScheduleChannel.cs
new file mode 100644
index 0000000..83bdc95
--- /dev/null
+++ b/src/QQBot.Net.Rest/Entities/Channels/RestScheduleChannel.cs
@@ -0,0 +1,47 @@
+using System.Diagnostics;
+using QQBot.API;
+
+namespace QQBot.Rest;
+
+///
+/// 表示频道中的一个基于 REST 的日程子频道。
+///
+[DebuggerDisplay("{DebuggerDisplay,nq}")]
+public class RestScheduleChannel : RestGuildChannel, IScheduleChannel
+{
+ ///
+ public ulong? CategoryId { get; private set; }
+
+ ///
+ public PrivateType? PrivateType { get; private set; }
+
+ ///
+ public SpeakPermission? SpeakPermission { get; private set; }
+
+ ///
+ public ChannelPermission? Permission { get; private set; }
+
+ internal RestScheduleChannel(BaseQQBotClient client, ulong id, IGuild guild)
+ : base(client, id, guild)
+ {
+ Type = ChannelType.Schedule;
+ }
+
+ internal static new RestScheduleChannel Create(BaseQQBotClient client, IGuild guild, Channel model)
+ {
+ RestScheduleChannel entity = new(client, model.Id, guild);
+ entity.Update(model);
+ return entity;
+ }
+
+ internal override void Update(Channel model)
+ {
+ base.Update(model);
+ CategoryId = model.ParentId;
+ PrivateType = model.PrivateType;
+ SpeakPermission = model.SpeakPermission;
+ Permission = model.Permissions is not null ? Enum.Parse(model.Permissions) : null; // TODO
+ }
+
+ private string DebuggerDisplay => $"{Name} ({Id}, Schedule)";
+}
diff --git a/src/QQBot.Net.Rest/Entities/Channels/RestTextChannel.cs b/src/QQBot.Net.Rest/Entities/Channels/RestTextChannel.cs
index c1b3968..e81e993 100644
--- a/src/QQBot.Net.Rest/Entities/Channels/RestTextChannel.cs
+++ b/src/QQBot.Net.Rest/Entities/Channels/RestTextChannel.cs
@@ -17,7 +17,7 @@ public class RestTextChannel : RestGuildChannel, ITextChannel
public ulong? CategoryId { get; private set; }
///
- public ChannelPrivateType? PrivateType { get; private set; }
+ public PrivateType? PrivateType { get; private set; }
///
public SpeakPermission? SpeakPermission { get; private set; }
diff --git a/src/QQBot.Net.Rest/Entities/Channels/RestVoiceChannel.cs b/src/QQBot.Net.Rest/Entities/Channels/RestVoiceChannel.cs
index 56771de..bb456ba 100644
--- a/src/QQBot.Net.Rest/Entities/Channels/RestVoiceChannel.cs
+++ b/src/QQBot.Net.Rest/Entities/Channels/RestVoiceChannel.cs
@@ -13,7 +13,7 @@ public class RestVoiceChannel : RestGuildChannel, IVoiceChannel
public ulong? CategoryId { get; private set; }
///
- public ChannelPrivateType? PrivateType { get; private set; }
+ public PrivateType? PrivateType { get; private set; }
///
public SpeakPermission? SpeakPermission { get; private set; }
diff --git a/src/QQBot.Net.Rest/Entities/Guilds/GuildHelper.cs b/src/QQBot.Net.Rest/Entities/Guilds/GuildHelper.cs
index ce42ff5..7e1dc66 100644
--- a/src/QQBot.Net.Rest/Entities/Guilds/GuildHelper.cs
+++ b/src/QQBot.Net.Rest/Entities/Guilds/GuildHelper.cs
@@ -5,10 +5,14 @@ namespace QQBot.Rest;
internal static class GuildHelper
{
- public static async Task> GetChannelsAsync(IGuild guild, BaseQQBotClient client,
+ #region Channels
+
+ public static async Task> GetChannelsAsync(IGuild guild,
+ BaseQQBotClient client,
RequestOptions? options)
{
- IReadOnlyCollection models = await client.ApiClient.GetChannelsAsync(guild.Id, options).ConfigureAwait(false);
+ IReadOnlyCollection models =
+ await client.ApiClient.GetChannelsAsync(guild.Id, options).ConfigureAwait(false);
return [..models.Select(x => RestGuildChannel.Create(client, guild, x))];
}
@@ -19,6 +23,129 @@ public static async Task GetChannelAsync(IGuild guild, BaseQQB
return RestGuildChannel.Create(client, guild, model);
}
+ public static async Task CreateTextChannelAsync(IGuild guild, BaseQQBotClient client,
+ string name, Action? func, RequestOptions? options)
+ {
+ CreateTextChannelProperties props = new();
+ func?.Invoke(props);
+ CreateChannelParams args = new()
+ {
+ Name = name,
+ Type = ChannelType.Text,
+ // Position = props.Position,
+ SubType = props.SubType,
+ PrivateType = props.PrivateType,
+ SpeakPermission = props.SpeakPermission,
+ };
+ Channel model = await client.ApiClient.CreateChannelAsync(guild.Id, args, options).ConfigureAwait(false);
+ return RestTextChannel.Create(client, guild, model);
+ }
+
+ public static async Task CreateVoiceChannelAsync(IGuild guild, BaseQQBotClient client,
+ string name, Action? func, RequestOptions? options)
+ {
+ CreateVoiceChannelProperties props = new();
+ func?.Invoke(props);
+ CreateChannelParams args = new()
+ {
+ Name = name,
+ Type = ChannelType.Voice,
+ // Position = props.Position,
+ PrivateType = props.PrivateType,
+ SpeakPermission = props.SpeakPermission,
+ };
+ Channel model = await client.ApiClient.CreateChannelAsync(guild.Id, args, options).ConfigureAwait(false);
+ return RestVoiceChannel.Create(client, guild, model);
+ }
+
+ public static async Task CreateLiveStreamChannelAsync(IGuild guild, BaseQQBotClient client,
+ string name, Action? func, RequestOptions? options)
+ {
+ CreateLiveStreamChannelProperties props = new();
+ func?.Invoke(props);
+ CreateChannelParams args = new()
+ {
+ Name = name,
+ Type = ChannelType.LiveStream,
+ // Position = props.Position,
+ PrivateType = props.PrivateType,
+ SpeakPermission = props.SpeakPermission,
+ };
+ Channel model = await client.ApiClient.CreateChannelAsync(guild.Id, args, options).ConfigureAwait(false);
+ return RestLiveStreamChannel.Create(client, guild, model);
+ }
+
+ public static async Task CreateApplicationChannelAsync(IGuild guild, BaseQQBotClient client,
+ string name, Action? func, RequestOptions? options)
+ {
+ CreateApplicationChannelProperties props = new();
+ func?.Invoke(props);
+ CreateChannelParams args = new()
+ {
+ Name = name,
+ Type = ChannelType.Application,
+ // Position = props.Position,
+ PrivateType = props.PrivateType,
+ SpeakPermission = props.SpeakPermission,
+ ApplicationId = props.ApplicationType,
+ };
+ Channel model = await client.ApiClient.CreateChannelAsync(guild.Id, args, options).ConfigureAwait(false);
+ return RestApplicationChannel.Create(client, guild, model);
+ }
+
+ public static async Task CreateForumChannelAsync(IGuild guild, BaseQQBotClient client,
+ string name, Action? func, RequestOptions? options)
+ {
+ CreateForumChannelProperties props = new();
+ func?.Invoke(props);
+ CreateChannelParams args = new()
+ {
+ Name = name,
+ Type = ChannelType.Forum,
+ // Position = props.Position,
+ PrivateType = props.PrivateType,
+ SpeakPermission = props.SpeakPermission,
+ };
+ Channel model = await client.ApiClient.CreateChannelAsync(guild.Id, args, options).ConfigureAwait(false);
+ return RestForumChannel.Create(client, guild, model);
+ }
+
+ public static async Task CreateScheduleChannelAsync(IGuild guild, BaseQQBotClient client,
+ string name, Action? func, RequestOptions? options)
+ {
+ CreateScheduleChannelProperties props = new();
+ func?.Invoke(props);
+ CreateChannelParams args = new()
+ {
+ Name = name,
+ Type = ChannelType.Schedule,
+ // Position = props.Position,
+ PrivateType = props.PrivateType,
+ SpeakPermission = props.SpeakPermission,
+ };
+ Channel model = await client.ApiClient.CreateChannelAsync(guild.Id, args, options).ConfigureAwait(false);
+ return RestScheduleChannel.Create(client, guild, model);
+ }
+
+ public static async Task CreateCategoryChannelAsync(IGuild guild, BaseQQBotClient client,
+ string name, Action? func, RequestOptions? options)
+ {
+ CreateCategoryChannelProperties props = new();
+ func?.Invoke(props);
+ CreateChannelParams args = new()
+ {
+ Name = name,
+ Type = ChannelType.Category,
+ Position = props.Position
+ };
+ Channel model = await client.ApiClient.CreateChannelAsync(guild.Id, args, options).ConfigureAwait(false);
+ return RestCategoryChannel.Create(client, guild, model);
+ }
+
+ #endregion
+
+ #region Users
+
public static async Task GetUserAsync(IGuild guild, BaseQQBotClient client,
ulong id, RequestOptions? options)
{
@@ -54,4 +181,6 @@ public static IAsyncEnumerable> GetMembersAsync(
count: limit
);
}
+
+ #endregion
}
diff --git a/src/QQBot.Net.Rest/Entities/Guilds/RestGuild.cs b/src/QQBot.Net.Rest/Entities/Guilds/RestGuild.cs
index 4dcae79..6b0e520 100644
--- a/src/QQBot.Net.Rest/Entities/Guilds/RestGuild.cs
+++ b/src/QQBot.Net.Rest/Entities/Guilds/RestGuild.cs
@@ -126,6 +126,29 @@ public async Task> GetVoiceChannelsAsync(Requ
return channel as IVoiceChannel;
}
+ ///
+ /// 获取此频道的所有直播子频道。
+ ///
+ /// 发送请求时要使用的选项。
+ /// 一个表示异步获取操作的任务。任务的结果包含此频道的所有直播子频道。
+ public async Task> GetLiveStreamChannelsAsync(RequestOptions? options = null)
+ {
+ IReadOnlyCollection channels = await GuildHelper.GetChannelsAsync(this, Client, options).ConfigureAwait(false);
+ return channels.OfType().ToArray();
+ }
+
+ ///
+ /// 获取此频道内的直播子频道。
+ ///
+ /// 要获取的直播子频道的 ID。
+ /// 发送请求时要使用的选项。
+ /// 一个表示异步获取操作的任务。任务的结果包含与指定的 关联的直播子频道;如果未找到,则返回 null。
+ public async Task GetLiveStreamChannelAsync(ulong id, RequestOptions? options = null)
+ {
+ RestGuildChannel channel = await GuildHelper.GetChannelAsync(this, Client, id, options).ConfigureAwait(false);
+ return channel as ILiveStreamChannel;
+ }
+
///
/// 获取此频道的所有应用子频道。
///
@@ -173,26 +196,26 @@ public async Task> GetForumChannelsAsync(Requ
}
///
- /// 获取此频道的所有直播子频道。
+ /// 获取此频道的所有日程子频道。
///
/// 发送请求时要使用的选项。
- /// 一个表示异步获取操作的任务。任务的结果包含此频道的所有直播子频道。
- public async Task> GetLiveStreamChannelsAsync(RequestOptions? options = null)
+ /// 一个表示异步获取操作的任务。任务的结果包含此频道的所有日程子频道。
+ public async Task> GetScheduleChannelsAsync(RequestOptions? options = null)
{
IReadOnlyCollection channels = await GuildHelper.GetChannelsAsync(this, Client, options).ConfigureAwait(false);
- return channels.OfType().ToArray();
+ return channels.OfType().ToArray();
}
///
- /// 获取此频道内的直播子频道。
+ /// 获取此频道内的日程子频道。
///
- /// 要获取的直播子频道的 ID。
+ /// 要获取的论坛子频道的 ID。
/// 发送请求时要使用的选项。
- /// 一个表示异步获取操作的任务。任务的结果包含与指定的 关联的直播子频道;如果未找到,则返回 null。
- public async Task GetLiveStreamChannelAsync(ulong id, RequestOptions? options = null)
+ /// 一个表示异步获取操作的任务。任务的结果包含与指定的 关联的日程子频道;如果未找到,则返回 null。
+ public async Task GetScheduleChannelAsync(ulong id, RequestOptions? options = null)
{
RestGuildChannel channel = await GuildHelper.GetChannelAsync(this, Client, id, options).ConfigureAwait(false);
- return channel as ILiveStreamChannel;
+ return channel as IScheduleChannel;
}
///
@@ -218,6 +241,41 @@ public async Task> GetCategoryChannelsAsyn
return channel as ICategoryChannel;
}
+ ///
+ public Task CreateTextChannelAsync(string name,
+ Action? func = null, RequestOptions? options = null) =>
+ GuildHelper.CreateTextChannelAsync(this, Client, name, func, options);
+
+ ///
+ public Task CreateVoiceChannelAsync(string name,
+ Action? func = null, RequestOptions? options = null) =>
+ GuildHelper.CreateVoiceChannelAsync(this, Client, name, func, options);
+
+ ///
+ public Task CreateLiveStreamChannelAsync(string name,
+ Action? func = null, RequestOptions? options = null) =>
+ GuildHelper.CreateLiveStreamChannelAsync(this, Client, name, func, options);
+
+ ///
+ public Task CreateApplicationChannelAsync(string name,
+ Action? func = null, RequestOptions? options = null) =>
+ GuildHelper.CreateApplicationChannelAsync(this, Client, name, func, options);
+
+ ///
+ public Task CreateForumChannelAsync(string name,
+ Action? func = null, RequestOptions? options = null) =>
+ GuildHelper.CreateForumChannelAsync(this, Client, name, func, options);
+
+ ///
+ public Task CreateScheduleChannelAsync(string name,
+ Action? func = null, RequestOptions? options = null) =>
+ GuildHelper.CreateScheduleChannelAsync(this, Client, name, func, options);
+
+ ///
+ public Task CreateCategoryChannelAsync(string name,
+ Action? func = null, RequestOptions? options = null) =>
+ GuildHelper.CreateCategoryChannelAsync(this, Client, name, func, options);
+
#endregion
#region Roles
@@ -271,6 +329,14 @@ async Task> IGuild.GetVoiceChannelsAsync(Cach
async Task IGuild.GetVoiceChannelAsync(ulong id, CacheMode mode, RequestOptions? options) =>
mode == CacheMode.AllowDownload ? await GetVoiceChannelAsync(id, options).ConfigureAwait(false) : null;
+ ///
+ async Task> IGuild.GetLiveStreamChannelsAsync(CacheMode mode, RequestOptions? options) =>
+ mode == CacheMode.AllowDownload ? await GetLiveStreamChannelsAsync(options).ConfigureAwait(false) : [];
+
+ ///
+ async Task IGuild.GetLiveStreamChannelAsync(ulong id, CacheMode mode, RequestOptions? options) =>
+ mode == CacheMode.AllowDownload ? await GetLiveStreamChannelAsync(id, options).ConfigureAwait(false) : null;
+
///
async Task> IGuild.GetApplicationChannelsAsync(CacheMode mode, RequestOptions? options) =>
mode == CacheMode.AllowDownload ? await GetApplicationChannelsAsync(options).ConfigureAwait(false) : [];
@@ -288,12 +354,12 @@ async Task> IGuild.GetForumChannelsAsync(Cach
mode == CacheMode.AllowDownload ? await GetForumChannelAsync(id, options).ConfigureAwait(false) : null;
///
- async Task> IGuild.GetLiveStreamChannelsAsync(CacheMode mode, RequestOptions? options) =>
- mode == CacheMode.AllowDownload ? await GetLiveStreamChannelsAsync(options).ConfigureAwait(false) : [];
+ async Task> IGuild.GetScheduleChannelsAsync(CacheMode mode, RequestOptions? options) =>
+ mode == CacheMode.AllowDownload ? await GetScheduleChannelsAsync(options).ConfigureAwait(false) : [];
///
- async Task IGuild.GetLiveStreamChannelAsync(ulong id, CacheMode mode, RequestOptions? options) =>
- mode == CacheMode.AllowDownload ? await GetLiveStreamChannelAsync(id, options).ConfigureAwait(false) : null;
+ async Task IGuild.GetScheduleChannelAsync(ulong id, CacheMode mode, RequestOptions? options) =>
+ mode == CacheMode.AllowDownload ? await GetScheduleChannelAsync(id, options).ConfigureAwait(false) : null;
///
async Task> IGuild.GetCategoryChannelsAsync(CacheMode mode, RequestOptions? options) =>
@@ -307,5 +373,26 @@ async Task> IGuild.GetCategoryChannelsAsyn
async Task IGuild.GetUserAsync(ulong id, CacheMode mode, RequestOptions? options) =>
mode == CacheMode.AllowDownload ? await GetUserAsync(id, options).ConfigureAwait(false) : null;
+ async Task IGuild.CreateTextChannelAsync(string name, Action? action, RequestOptions? options) =>
+ await CreateTextChannelAsync(name, action, options).ConfigureAwait(false);
+
+ async Task IGuild.CreateVoiceChannelAsync(string name, Action? action, RequestOptions? options) =>
+ await CreateVoiceChannelAsync(name, action, options).ConfigureAwait(false);
+
+ async Task IGuild.CreateLiveStreamChannelAsync(string name, Action? action, RequestOptions? options) =>
+ await CreateLiveStreamChannelAsync(name, action, options).ConfigureAwait(false);
+
+ async Task IGuild.CreateApplicationChannelAsync(string name, Action? action, RequestOptions? options) =>
+ await CreateApplicationChannelAsync(name, action, options).ConfigureAwait(false);
+
+ async Task IGuild.CreateForumChannelAsync(string name, Action? action, RequestOptions? options) =>
+ await CreateForumChannelAsync(name, action, options).ConfigureAwait(false);
+
+ async Task IGuild.CreateScheduleChannelAsync(string name, Action? action, RequestOptions? options) =>
+ await CreateScheduleChannelAsync(name, action, options).ConfigureAwait(false);
+
+ async Task IGuild.CreateCategoryChannelAsync(string name, Action? action, RequestOptions? options) =>
+ await CreateCategoryChannelAsync(name, action, options).ConfigureAwait(false);
+
#endregion
}
diff --git a/src/QQBot.Net.Rest/QQBotRestApiClient.cs b/src/QQBot.Net.Rest/QQBotRestApiClient.cs
index 6ddfa8a..10bc11a 100644
--- a/src/QQBot.Net.Rest/QQBotRestApiClient.cs
+++ b/src/QQBot.Net.Rest/QQBotRestApiClient.cs
@@ -428,6 +428,13 @@ public async Task GetChannelAsync(ulong channelId, RequestOptions? opti
public async Task CreateChannelAsync(ulong guildId, CreateChannelParams args, RequestOptions? options = null)
{
Preconditions.NotEqual(guildId, 0, nameof(guildId));
+ Preconditions.NotNullOrEmpty(args.Name, nameof(args.Name));
+ if (args.Type is ChannelType.Category)
+ {
+ Preconditions.NotNull(args.Position, nameof(args.Position));
+ Preconditions.AtLeast(args.Position.Value, 2, nameof(args.Position));
+ }
+
options = RequestOptions.CreateOrClone(options);
BucketIds ids = new(guildId);
diff --git a/src/QQBot.Net.WebSocket/Entities/Channels/SocketApplicationChannel.cs b/src/QQBot.Net.WebSocket/Entities/Channels/SocketApplicationChannel.cs
index a4d6b88..e03c238 100644
--- a/src/QQBot.Net.WebSocket/Entities/Channels/SocketApplicationChannel.cs
+++ b/src/QQBot.Net.WebSocket/Entities/Channels/SocketApplicationChannel.cs
@@ -13,7 +13,7 @@ public class SocketApplicationChannel : SocketGuildChannel, IApplicationChannel
public ulong? CategoryId { get; private set; }
///
- public ChannelPrivateType? PrivateType { get; private set; }
+ public PrivateType? PrivateType { get; private set; }
///
public SpeakPermission? SpeakPermission { get; private set; }
diff --git a/src/QQBot.Net.WebSocket/Entities/Channels/SocketForumChannel.cs b/src/QQBot.Net.WebSocket/Entities/Channels/SocketForumChannel.cs
index 6ed5e09..fd90a53 100644
--- a/src/QQBot.Net.WebSocket/Entities/Channels/SocketForumChannel.cs
+++ b/src/QQBot.Net.WebSocket/Entities/Channels/SocketForumChannel.cs
@@ -13,7 +13,7 @@ public class SocketForumChannel : SocketGuildChannel, IForumChannel
public ulong? CategoryId { get; private set; }
///
- public ChannelPrivateType? PrivateType { get; private set; }
+ public PrivateType? PrivateType { get; private set; }
///
public SpeakPermission? SpeakPermission { get; private set; }
diff --git a/src/QQBot.Net.WebSocket/Entities/Channels/SocketGuildChannel.cs b/src/QQBot.Net.WebSocket/Entities/Channels/SocketGuildChannel.cs
index 4f76244..9b7f6b7 100644
--- a/src/QQBot.Net.WebSocket/Entities/Channels/SocketGuildChannel.cs
+++ b/src/QQBot.Net.WebSocket/Entities/Channels/SocketGuildChannel.cs
@@ -45,6 +45,7 @@ internal static SocketGuildChannel Create(SocketGuild guild, ClientState state,
ChannelType.LiveStream => SocketLiveStreamChannel.Create(guild, state, model),
ChannelType.Application => SocketApplicationChannel.Create(guild, state, model),
ChannelType.Forum => SocketForumChannel.Create(guild, state, model),
+ ChannelType.Schedule => SocketScheduleChannel.Create(guild, state, model),
_ => new SocketGuildChannel(guild.Client, model.Id, guild)
};
diff --git a/src/QQBot.Net.WebSocket/Entities/Channels/SocketLiveStreamChannel.cs b/src/QQBot.Net.WebSocket/Entities/Channels/SocketLiveStreamChannel.cs
index d89f62d..88d94e0 100644
--- a/src/QQBot.Net.WebSocket/Entities/Channels/SocketLiveStreamChannel.cs
+++ b/src/QQBot.Net.WebSocket/Entities/Channels/SocketLiveStreamChannel.cs
@@ -13,7 +13,7 @@ public class SocketLiveStreamChannel : SocketGuildChannel, ILiveStreamChannel
public ulong? CategoryId { get; private set; }
///
- public ChannelPrivateType? PrivateType { get; private set; }
+ public PrivateType? PrivateType { get; private set; }
///
public SpeakPermission? SpeakPermission { get; private set; }
diff --git a/src/QQBot.Net.WebSocket/Entities/Channels/SocketScheduleChannel.cs b/src/QQBot.Net.WebSocket/Entities/Channels/SocketScheduleChannel.cs
new file mode 100644
index 0000000..03d2ca2
--- /dev/null
+++ b/src/QQBot.Net.WebSocket/Entities/Channels/SocketScheduleChannel.cs
@@ -0,0 +1,47 @@
+using System.Diagnostics;
+using QQBot.API;
+
+namespace QQBot.WebSocket;
+
+///
+/// 表示频道中的一个基于网关的直播子频道。
+///
+[DebuggerDisplay("{DebuggerDisplay,nq}")]
+public class SocketScheduleChannel : SocketGuildChannel, IScheduleChannel
+{
+ ///
+ public ulong? CategoryId { get; private set; }
+
+ ///
+ public PrivateType? PrivateType { get; private set; }
+
+ ///
+ public SpeakPermission? SpeakPermission { get; private set; }
+
+ ///
+ public ChannelPermission? Permission { get; private set; }
+
+ internal SocketScheduleChannel(QQBotSocketClient client, ulong id, SocketGuild guild)
+ : base(client, id, guild)
+ {
+ Type = ChannelType.Schedule;
+ }
+
+ internal static new SocketScheduleChannel Create(SocketGuild guild, ClientState state, Channel model)
+ {
+ SocketScheduleChannel entity = new(guild.Client, model.Id, guild);
+ entity.Update(state, model);
+ return entity;
+ }
+
+ internal override void Update(ClientState state, Channel model)
+ {
+ base.Update(state, model);
+ CategoryId = model.ParentId;
+ PrivateType = model.PrivateType;
+ SpeakPermission = model.SpeakPermission;
+ Permission = model.Permissions is not null ? Enum.Parse(model.Permissions) : null; // TODO
+ }
+
+ private string DebuggerDisplay => $"{Name} ({Id}, Schedule)";
+}
diff --git a/src/QQBot.Net.WebSocket/Entities/Channels/SocketTextChannel.cs b/src/QQBot.Net.WebSocket/Entities/Channels/SocketTextChannel.cs
index 8dcd914..744cfbc 100644
--- a/src/QQBot.Net.WebSocket/Entities/Channels/SocketTextChannel.cs
+++ b/src/QQBot.Net.WebSocket/Entities/Channels/SocketTextChannel.cs
@@ -19,7 +19,7 @@ public class SocketTextChannel : SocketGuildChannel, ITextChannel, ISocketMessag
public ulong? CategoryId { get; private set; }
///
- public ChannelPrivateType? PrivateType { get; private set; }
+ public PrivateType? PrivateType { get; private set; }
///
public SpeakPermission? SpeakPermission { get; private set; }
diff --git a/src/QQBot.Net.WebSocket/Entities/Channels/SocketVoiceChannel.cs b/src/QQBot.Net.WebSocket/Entities/Channels/SocketVoiceChannel.cs
index fa817b1..d530b04 100644
--- a/src/QQBot.Net.WebSocket/Entities/Channels/SocketVoiceChannel.cs
+++ b/src/QQBot.Net.WebSocket/Entities/Channels/SocketVoiceChannel.cs
@@ -13,7 +13,7 @@ public class SocketVoiceChannel : SocketGuildChannel, IVoiceChannel
public ulong? CategoryId { get; private set; }
///
- public ChannelPrivateType? PrivateType { get; private set; }
+ public PrivateType? PrivateType { get; private set; }
///
public SpeakPermission? SpeakPermission { get; private set; }
diff --git a/src/QQBot.Net.WebSocket/Entities/Guilds/SocketGuild.cs b/src/QQBot.Net.WebSocket/Entities/Guilds/SocketGuild.cs
index 12195b7..b70539a 100644
--- a/src/QQBot.Net.WebSocket/Entities/Guilds/SocketGuild.cs
+++ b/src/QQBot.Net.WebSocket/Entities/Guilds/SocketGuild.cs
@@ -79,6 +79,11 @@ public class SocketGuild : SocketEntity, IGuild, IUpdateable
///
public IReadOnlyCollection VoiceChannels => [..Channels.OfType()];
+ ///
+ /// 获取此频道中所有直播子频道。
+ ///
+ public IReadOnlyCollection LiveStreamChannels => [..Channels.OfType()];
+
///
/// 获取此频道中所有应用程序子频道。
///
@@ -90,9 +95,9 @@ public class SocketGuild : SocketEntity, IGuild, IUpdateable
public IReadOnlyCollection ForumChannels => [..Channels.OfType()];
///
- /// 获取此频道中所有直播子频道。
+ /// 获取此频道中所有日程子频道。
///
- public IReadOnlyCollection LiveStreamChannels => [..Channels.OfType()];
+ public IReadOnlyCollection ScheduleChannels => [..Channels.OfType()];
///
/// 获取此频道中的所有分组子频道。
@@ -245,6 +250,13 @@ public async Task DownloadUsersAsync(RequestOptions? options = null) =>
/// 与指定的 关联的具有语音聊天能力的子频道;如果未找到,则返回 null。
public SocketVoiceChannel? GetVoiceChannel(ulong id) => GetChannel(id) as SocketVoiceChannel;
+ ///
+ /// 获取此子频道中的直播子频道。
+ ///
+ /// 要获取的子频道的 ID。
+ /// 与指定的 关联的直播子频道;如果未找到,则返回 null。
+ public SocketLiveStreamChannel? GetLiveStreamChannel(ulong id) => GetChannel(id) as SocketLiveStreamChannel;
+
///
/// 获取此子频道中的应用程序子频道。
///
@@ -260,11 +272,11 @@ public async Task DownloadUsersAsync(RequestOptions? options = null) =>
public SocketForumChannel? GetForumChannel(ulong id) => GetChannel(id) as SocketForumChannel;
///
- /// 获取此子频道中的直播子频道。
+ /// 获取此子频道中的日程子频道。
///
/// 要获取的子频道的 ID。
- /// 与指定的 关联的直播子频道;如果未找到,则返回 null。
- public SocketLiveStreamChannel? GetLiveStreamChannel(ulong id) => GetChannel(id) as SocketLiveStreamChannel;
+ /// 与指定的 关联的日程子频道;如果未找到,则返回 null。
+ public SocketScheduleChannel? GetScheduleChannel(ulong id) => GetChannel(id) as SocketScheduleChannel;
///
/// 获取此子频道中的分组子频道。
@@ -273,6 +285,41 @@ public async Task DownloadUsersAsync(RequestOptions? options = null) =>
/// 与指定的 关联的分组子频道;如果未找到,则返回 null。
public SocketCategoryChannel? GetCategoryChannel(ulong id) => GetChannel(id) as SocketCategoryChannel;
+ ///
+ public Task CreateTextChannelAsync(string name,
+ Action? func = null, RequestOptions? options = null) =>
+ GuildHelper.CreateTextChannelAsync(this, Client, name, func, options);
+
+ ///
+ public Task CreateVoiceChannelAsync(string name,
+ Action? func = null, RequestOptions? options = null) =>
+ GuildHelper.CreateVoiceChannelAsync(this, Client, name, func, options);
+
+ ///
+ public Task CreateLiveStreamChannelAsync(string name,
+ Action? func = null, RequestOptions? options = null) =>
+ GuildHelper.CreateLiveStreamChannelAsync(this, Client, name, func, options);
+
+ ///
+ public Task CreateApplicationChannelAsync(string name,
+ Action? func = null, RequestOptions? options = null) =>
+ GuildHelper.CreateApplicationChannelAsync(this, Client, name, func, options);
+
+ ///
+ public Task CreateForumChannelAsync(string name,
+ Action? func = null, RequestOptions? options = null) =>
+ GuildHelper.CreateForumChannelAsync(this, Client, name, func, options);
+
+ ///
+ public Task CreateScheduleChannelAsync(string name,
+ Action? func = null, RequestOptions? options = null) =>
+ GuildHelper.CreateScheduleChannelAsync(this, Client, name, func, options);
+
+ ///
+ public Task CreateCategoryChannelAsync(string name,
+ Action? func = null, RequestOptions? options = null) =>
+ GuildHelper.CreateCategoryChannelAsync(this, Client, name, func, options);
+
#endregion
#region IGuild
@@ -301,6 +348,14 @@ Task> IGuild.GetVoiceChannelsAsync(CacheMode
Task IGuild.GetVoiceChannelAsync(ulong id, CacheMode mode, RequestOptions? options) =>
Task.FromResult(GetVoiceChannel(id));
+ ///
+ Task> IGuild.GetLiveStreamChannelsAsync(CacheMode mode, RequestOptions? options) =>
+ Task.FromResult>(LiveStreamChannels);
+
+ ///
+ Task IGuild.GetLiveStreamChannelAsync(ulong id, CacheMode mode, RequestOptions? options) =>
+ Task.FromResult(GetLiveStreamChannel(id));
+
///
Task> IGuild.GetApplicationChannelsAsync(CacheMode mode, RequestOptions? options) =>
Task.FromResult>(ApplicationChannels);
@@ -318,12 +373,12 @@ Task> IGuild.GetForumChannelsAsync(CacheMode
Task.FromResult(GetForumChannel(id));
///
- Task> IGuild.GetLiveStreamChannelsAsync(CacheMode mode, RequestOptions? options) =>
- Task.FromResult>(LiveStreamChannels);
+ Task> IGuild.GetScheduleChannelsAsync(CacheMode mode, RequestOptions? options) =>
+ Task.FromResult>(ScheduleChannels);
///
- Task IGuild.GetLiveStreamChannelAsync(ulong id, CacheMode mode, RequestOptions? options) =>
- Task.FromResult(GetLiveStreamChannel(id));
+ Task IGuild.GetScheduleChannelAsync(ulong id, CacheMode mode, RequestOptions? options) =>
+ Task.FromResult(GetScheduleChannel(id));
///
Task> IGuild.GetCategoryChannelsAsync(CacheMode mode, RequestOptions? options) =>
@@ -333,6 +388,27 @@ Task> IGuild.GetCategoryChannelsAsync(Cach
Task IGuild.GetCategoryChannelAsync(ulong id, CacheMode mode, RequestOptions? options) =>
Task.FromResult(GetCategoryChannel(id));
+ async Task IGuild.CreateTextChannelAsync(string name, Action? action, RequestOptions? options) =>
+ await CreateTextChannelAsync(name, action, options).ConfigureAwait(false);
+
+ async Task IGuild.CreateVoiceChannelAsync(string name, Action? action, RequestOptions? options) =>
+ await CreateVoiceChannelAsync(name, action, options).ConfigureAwait(false);
+
+ async Task IGuild.CreateLiveStreamChannelAsync(string name, Action? action, RequestOptions? options) =>
+ await CreateLiveStreamChannelAsync(name, action, options).ConfigureAwait(false);
+
+ async Task IGuild.CreateApplicationChannelAsync(string name, Action? action, RequestOptions? options) =>
+ await CreateApplicationChannelAsync(name, action, options).ConfigureAwait(false);
+
+ async Task IGuild.CreateForumChannelAsync(string name, Action? action, RequestOptions? options) =>
+ await CreateForumChannelAsync(name, action, options).ConfigureAwait(false);
+
+ async Task IGuild.CreateScheduleChannelAsync(string name, Action? action, RequestOptions? options) =>
+ await CreateScheduleChannelAsync(name, action, options).ConfigureAwait(false);
+
+ async Task IGuild.CreateCategoryChannelAsync(string name, Action? action, RequestOptions? options) =>
+ await CreateCategoryChannelAsync(name, action, options).ConfigureAwait(false);
+
///
async Task IGuild.GetUserAsync(ulong id, CacheMode mode, RequestOptions? options)
{