Skip to content

Commit

Permalink
Added support for creating and managing Schedule channels
Browse files Browse the repository at this point in the history
  • Loading branch information
gehongyan committed Nov 8, 2024
1 parent ea869ef commit 0b28eb9
Show file tree
Hide file tree
Showing 43 changed files with 670 additions and 74 deletions.
23 changes: 16 additions & 7 deletions samples/QQBot.Net.Samples.SimpleBot/Program.cs
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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();
Expand Down
7 changes: 6 additions & 1 deletion src/QQBot.Net.Core/Entities/Channels/ChannelType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,10 @@ public enum ChannelType
/// <summary>
/// 论坛子频道。
/// </summary>
Forum = 10007
Forum = 10007,

/// <summary>
/// 日程子频道。
/// </summary>
Schedule = 10011,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace QQBot;

/// <summary>
/// 提供用于创建 <see cref="QQBot.IApplicationChannel" /> 的属性。
/// </summary>
/// <seealso cref="QQBot.IGuild.CreateApplicationChannelAsync(System.String,System.Action{QQBot.CreateApplicationChannelProperties},QQBot.RequestOptions)"/>
public class CreateApplicationChannelProperties : CreateNestedChannelProperties
{
/// <summary>
/// 获取或设置要设置到此频道的应用频道类型。
/// </summary>
public ChannelApplication? ApplicationType { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace QQBot;

/// <summary>
/// 提供用于创建 <see cref="QQBot.ICategoryChannel" /> 的属性。
/// </summary>
/// <seealso cref="QQBot.IGuild.CreateCategoryChannelAsync(System.String,System.Action{QQBot.CreateCategoryChannelProperties},QQBot.RequestOptions)"/>
public class CreateCategoryChannelProperties : CreateGuildChannelProperties
{
/// <summary>
/// 获取或设置要设置到此频道的位置。
/// </summary>
/// <remarks>
/// 更小的数值表示更靠近列表顶部的位置。设置为与同分组下的其他频道相同的值,将会使当前频道排列于与该频道相邻更靠近列表顶部的位置。
/// 分组频道的位置顺序号至少为 <c>2</c>。
/// </remarks>
public int Position { get; set; } = 2;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace QQBot;

/// <summary>
/// 提供用于创建 <see cref="QQBot.IForumChannel" /> 的属性。
/// </summary>
/// <seealso cref="QQBot.IGuild.CreateForumChannelAsync(System.String,System.Action{QQBot.CreateForumChannelProperties},QQBot.RequestOptions)"/>
public class CreateForumChannelProperties : CreateNestedChannelProperties;
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace QQBot;

/// <summary>
/// 提供用于创建 <see cref="QQBot.IGuildChannel" /> 的属性。
/// </summary>
public class CreateGuildChannelProperties;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace QQBot;

/// <summary>
/// 提供用于创建 <see cref="QQBot.ILiveStreamChannel" /> 的属性。
/// </summary>
/// <seealso cref="QQBot.IGuild.CreateLiveStreamChannelAsync(System.String,System.Action{QQBot.CreateLiveStreamChannelProperties},QQBot.RequestOptions)"/>
public class CreateLiveStreamChannelProperties : CreateNestedChannelProperties;
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
namespace QQBot;

/// <summary>
/// 提供用于创建 <see cref="QQBot.INestedChannel" /> 的属性。
/// </summary>
public class CreateNestedChannelProperties : CreateGuildChannelProperties
{
// /// <summary>
// /// 获取或设置要设置到此频道的所属分组频道的 ID。
// /// </summary>
// /// <remarks>
// /// 将此值设置为某分组频道的 ID 可以使新建频道位于该分组频道下;将此值设置为 <c>null</c>
// /// 可以使新建频道位于服务器所有分组频道的上方,即不属于任何分组频道。
// /// </remarks>
// public ulong? CategoryId { get; set; }

/// <summary>
/// 获取或设置要设置到此频道的私有频道类型。
/// </summary>
public PrivateType? PrivateType { get; set; }

/// <summary>
/// 获取或设置要设置到此频道的发言权限。
/// </summary>
public SpeakPermission? SpeakPermission { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace QQBot;

/// <summary>
/// 提供用于创建 <see cref="QQBot.IScheduleChannel" /> 的属性。
/// </summary>
/// <seealso cref="QQBot.IGuild.CreateScheduleChannelAsync(System.String,System.Action{QQBot.CreateScheduleChannelProperties},QQBot.RequestOptions)"/>
public class CreateScheduleChannelProperties : CreateNestedChannelProperties;
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace QQBot;

/// <summary>
/// 提供用于创建 <see cref="QQBot.ITextChannel" /> 的属性。
/// </summary>
/// <seealso cref="QQBot.IGuild.CreateTextChannelAsync(System.String,System.Action{QQBot.CreateTextChannelProperties},QQBot.RequestOptions)"/>
public class CreateTextChannelProperties : CreateNestedChannelProperties
{
/// <summary>
/// 获取或设置要设置到此频道的子频道二级分类。
/// </summary>
public ChannelSubType? SubType { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace QQBot;

/// <summary>
/// 提供用于创建 <see cref="QQBot.IVoiceChannel" /> 的属性。
/// </summary>
/// <seealso cref="QQBot.IGuild.CreateVoiceChannelAsync(System.String,System.Action{QQBot.CreateVoiceChannelProperties},QQBot.RequestOptions)"/>
public class CreateVoiceChannelProperties : CreateNestedChannelProperties;
5 changes: 1 addition & 4 deletions src/QQBot.Net.Core/Entities/Channels/ICategoryChannel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,4 @@ namespace QQBot;
/// <summary>
/// 表示一个分组子频道。
/// </summary>
public interface ICategoryChannel : IGuildChannel
{

}
public interface ICategoryChannel : IGuildChannel;
5 changes: 1 addition & 4 deletions src/QQBot.Net.Core/Entities/Channels/IForumChannel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,4 @@ namespace QQBot;
/// <summary>
/// 表示一个论坛子频道。
/// </summary>
public interface IForumChannel : INestedChannel
{

}
public interface IForumChannel : INestedChannel;
5 changes: 1 addition & 4 deletions src/QQBot.Net.Core/Entities/Channels/ILiveStreamChannel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,4 @@ namespace QQBot;
/// <summary>
/// 表示一个直播子频道。
/// </summary>
public interface ILiveStreamChannel : INestedChannel
{

}
public interface ILiveStreamChannel : INestedChannel;
2 changes: 1 addition & 1 deletion src/QQBot.Net.Core/Entities/Channels/INestedChannel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public interface INestedChannel : IGuildChannel
/// <summary>
/// 获取此子频道的私密类型。
/// </summary>
ChannelPrivateType? PrivateType { get; }
PrivateType? PrivateType { get; }

/// <summary>
/// 获取此子频道的发言权限。
Expand Down
6 changes: 6 additions & 0 deletions src/QQBot.Net.Core/Entities/Channels/IScheduleChannel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace QQBot;

/// <summary>
/// 表示一个日程子频道。
/// </summary>
public interface IScheduleChannel : INestedChannel;
5 changes: 1 addition & 4 deletions src/QQBot.Net.Core/Entities/Channels/IVoiceChannel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,4 @@ namespace QQBot;
/// <summary>
/// 表示一个语音子频道。
/// </summary>
public interface IVoiceChannel : INestedChannel
{

}
public interface IVoiceChannel : INestedChannel;
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/// <summary>
/// 表示一个子频道的私密类型。
/// </summary>
public enum ChannelPrivateType
public enum PrivateType
{
/// <summary>
/// 公开子频道。
Expand Down
94 changes: 87 additions & 7 deletions src/QQBot.Net.Core/Entities/Guilds/IGuild.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,23 @@ public interface IGuild : IEntity<ulong>
/// <returns> 一个表示异步获取操作的任务。任务的结果包含与指定的 <paramref name="id"/> 关联的具有语音聊天能力的子频道;如果未找到,则返回 <c>null</c>。 </returns>
Task<IVoiceChannel?> GetVoiceChannelAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions? options = null);

/// <summary>
/// 获取此频道的所有直播子频道。
/// </summary>
/// <param name="mode"> 指示当前方法是否应该仅从缓存中获取结果,还是可以通过 API 请求获取数据。 </param>
/// <param name="options"> 发送请求时要使用的选项。 </param>
/// <returns> 一个表示异步获取操作的任务。任务的结果包含此频道的所有直播子频道。 </returns>
Task<IReadOnlyCollection<ILiveStreamChannel>> GetLiveStreamChannelsAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions? options = null);

/// <summary>
/// 获取此频道内的直播子频道。
/// </summary>
/// <param name="id"> 要获取的直播子频道的 ID。 </param>
/// <param name="mode"> 指示当前方法是否应该仅从缓存中获取结果,还是可以通过 API 请求获取数据。 </param>
/// <param name="options"> 发送请求时要使用的选项。 </param>
/// <returns> 一个表示异步获取操作的任务。任务的结果包含与指定的 <paramref name="id"/> 关联的直播子频道;如果未找到,则返回 <c>null</c>。 </returns>
Task<ILiveStreamChannel?> GetLiveStreamChannelAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions? options = null);

/// <summary>
/// 获取此频道的所有应用子频道。
/// </summary>
Expand Down Expand Up @@ -195,21 +212,21 @@ public interface IGuild : IEntity<ulong>
Task<IForumChannel?> GetForumChannelAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions? options = null);

/// <summary>
/// 获取此频道的所有直播子频道
/// 获取此频道的所有日程子频道
/// </summary>
/// <param name="mode"> 指示当前方法是否应该仅从缓存中获取结果,还是可以通过 API 请求获取数据。 </param>
/// <param name="options"> 发送请求时要使用的选项。 </param>
/// <returns> 一个表示异步获取操作的任务。任务的结果包含此频道的所有直播子频道。 </returns>
Task<IReadOnlyCollection<ILiveStreamChannel>> GetLiveStreamChannelsAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions? options = null);
/// <returns> 一个表示异步获取操作的任务。任务的结果包含此频道的所有日程子频道。 </returns>
Task<IReadOnlyCollection<IScheduleChannel>> GetScheduleChannelsAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions? options = null);

/// <summary>
/// 获取此频道内的直播子频道
/// 获取此频道内的日程子频道
/// </summary>
/// <param name="id"> 要获取的直播子频道的 ID。 </param>
/// <param name="id"> 要获取的日程子频道的 ID。 </param>
/// <param name="mode"> 指示当前方法是否应该仅从缓存中获取结果,还是可以通过 API 请求获取数据。 </param>
/// <param name="options"> 发送请求时要使用的选项。 </param>
/// <returns> 一个表示异步获取操作的任务。任务的结果包含与指定的 <paramref name="id"/> 关联的直播子频道;如果未找到,则返回 <c>null</c>。 </returns>
Task<ILiveStreamChannel?> GetLiveStreamChannelAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions? options = null);
/// <returns> 一个表示异步获取操作的任务。任务的结果包含与指定的 <paramref name="id"/> 关联的日程子频道;如果未找到,则返回 <c>null</c>。 </returns>
Task<IScheduleChannel?> GetScheduleChannelAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions? options = null);

/// <summary>
/// 获取此频道的所有分组子频道。
Expand All @@ -228,5 +245,68 @@ public interface IGuild : IEntity<ulong>
/// <returns> 一个表示异步获取操作的任务。任务的结果包含与指定的 <paramref name="id"/> 关联的分组子频道;如果未找到,则返回 <c>null</c>。 </returns>
Task<ICategoryChannel?> GetCategoryChannelAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions? options = null);

/// <summary>
/// 在此服务器内创建一个新的文字子频道。
/// </summary>
/// <param name="name"> 频道的名称。 </param>
/// <param name="func"> 一个包含要应用到新创建频道的配置的委托。 </param>
/// <param name="options"> 发送请求时要使用的选项。 </param>
/// <returns> 一个表示异步创建操作的任务。任务的结果包含新创建的文字频道。 </returns>
Task<ITextChannel> CreateTextChannelAsync(string name, Action<CreateTextChannelProperties>? func = null, RequestOptions? options = null);

/// <summary>
/// 在此服务器内创建一个新的语音子频道。
/// </summary>
/// <param name="name"> 频道的名称。 </param>
/// <param name="func"> 一个包含要应用到新创建频道的配置的委托。 </param>
/// <param name="options"> 发送请求时要使用的选项。 </param>
/// <returns> 一个表示异步创建操作的任务。任务的结果包含新创建的语音频道。 </returns>
Task<IVoiceChannel> CreateVoiceChannelAsync(string name, Action<CreateVoiceChannelProperties>? func = null, RequestOptions? options = null);

/// <summary>
/// 在此服务器内创建一个新的直播子频道。
/// </summary>
/// <param name="name"> 频道的名称。 </param>
/// <param name="func"> 一个包含要应用到新创建频道的配置的委托。 </param>
/// <param name="options"> 发送请求时要使用的选项。 </param>
/// <returns> 一个表示异步创建操作的任务。任务的结果包含新创建的直播频道。 </returns>
Task<ILiveStreamChannel> CreateLiveStreamChannelAsync(string name, Action<CreateLiveStreamChannelProperties>? func = null, RequestOptions? options = null);

/// <summary>
/// 在此服务器内创建一个新的应用子频道。
/// </summary>
/// <param name="name"> 频道的名称。 </param>
/// <param name="func"> 一个包含要应用到新创建频道的配置的委托。 </param>
/// <param name="options"> 发送请求时要使用的选项。 </param>
/// <returns> 一个表示异步创建操作的任务。任务的结果包含新创建的应用频道。 </returns>
Task<IApplicationChannel> CreateApplicationChannelAsync(string name, Action<CreateApplicationChannelProperties>? func = null, RequestOptions? options = null);

/// <summary>
/// 在此服务器内创建一个新的论坛子频道。
/// </summary>
/// <param name="name"> 频道的名称。 </param>
/// <param name="func"> 一个包含要应用到新创建频道的配置的委托。 </param>
/// <param name="options"> 发送请求时要使用的选项。 </param>
/// <returns> 一个表示异步创建操作的任务。任务的结果包含新创建的论坛频道。 </returns>
Task<IForumChannel> CreateForumChannelAsync(string name, Action<CreateForumChannelProperties>? func = null, RequestOptions? options = null);

/// <summary>
/// 在此服务器内创建一个新的日程子频道。
/// </summary>
/// <param name="name"> 频道的名称。 </param>
/// <param name="func"> 一个包含要应用到新创建频道的配置的委托。 </param>
/// <param name="options"> 发送请求时要使用的选项。 </param>
/// <returns> 一个表示异步创建操作的任务。任务的结果包含新创建的日程频道。 </returns>
Task<IScheduleChannel> CreateScheduleChannelAsync(string name, Action<CreateScheduleChannelProperties>? func = null, RequestOptions? options = null);

/// <summary>
/// 在此服务器内创建一个新的分组子频道。
/// </summary>
/// <param name="name"> 频道的名称。 </param>
/// <param name="func"> 一个包含要应用到新创建频道的配置的委托。 </param>
/// <param name="options"> 发送请求时要使用的选项。 </param>
/// <returns> 一个表示异步创建操作的任务。任务的结果包含新创建的分组频道。 </returns>
Task<ICategoryChannel> CreateCategoryChannelAsync(string name, Action<CreateCategoryChannelProperties>? func = null, RequestOptions? options = null);

#endregion
}
2 changes: 1 addition & 1 deletion src/QQBot.Net.Core/Net/HttpException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)})";
}
}
10 changes: 10 additions & 0 deletions src/QQBot.Net.Core/QQBotErrorCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/QQBot.Net.Core/Utils/Preconditions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ internal static class Preconditions
#region Objects

/// <exception cref="ArgumentNullException"> <paramref name="obj"/> 不可为 <c>null</c>. </exception>
public static void NotNull<T>([NotNull] T? obj, string name, string? msg = null) where T : class
public static void NotNull<T>([NotNull] T? obj, string name, string? msg = null)
{
if (obj == null)
throw CreateNotNullException(name, msg);
Expand Down
2 changes: 1 addition & 1 deletion src/QQBot.Net.Rest/API/Common/Channel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand Down
Loading

0 comments on commit 0b28eb9

Please sign in to comment.