From 59e2754f7cbefda161c652a253ca7e90b2d52174 Mon Sep 17 00:00:00 2001 From: Chr_ Date: Thu, 2 Nov 2023 09:39:33 +0800 Subject: [PATCH] misc --- Directory.Build.props | 2 +- XinjingdailyBot.Command/AdminCommand.cs | 50 ++++++++++++++++++ XinjingdailyBot.Command/CommonCommand.cs | 22 +++++++- XinjingdailyBot.Command/NormalCommand.cs | 29 +++++------ .../Extensions/BotClientExtension.cs | 52 +++++++++++++++++++ .../Bot/Common/IChannelService.cs | 3 ++ .../Bot/Handler/ICommandHandler.cs | 4 ++ .../Data/IPostService.cs | 4 ++ .../Data/IReviewStatusService.cs | 24 ++++++++- .../Helper/IMarkupHelperService.cs | 7 ++- XinjingdailyBot.Model/Models/Users.cs | 4 +- .../Helper/MarkupHelperService.cs | 30 ++++++++--- .../Helper/TextHelperService.cs | 3 -- XinjingdailyBot.Tasks/ReviewStatusTask.cs | 4 +- 14 files changed, 203 insertions(+), 35 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index b1fa7ac1..2932b168 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,6 +1,6 @@ - 2.2.3.6 + 2.2.4.0 diff --git a/XinjingdailyBot.Command/AdminCommand.cs b/XinjingdailyBot.Command/AdminCommand.cs index de2ef2c0..4ea3c408 100644 --- a/XinjingdailyBot.Command/AdminCommand.cs +++ b/XinjingdailyBot.Command/AdminCommand.cs @@ -530,6 +530,7 @@ public async Task ResponseQueryBan(Message message, string[] args) } else { + sb.AppendLine("投稿机器人封禁状态:"); var records = await _banRecordService.Queryable() .Where(x => x.UserID == targetUser.UserID) .OrderByDescending(static x => new { x.BanTime }).ToListAsync(); @@ -583,6 +584,19 @@ public async Task ResponseQueryBan(Message message, string[] args) sb.AppendLine($"在 {date} 因为 {record.Reason}{admin} {operate}"); } } + + sb.AppendLine(); + sb.AppendLine("频道和群组封禁状态:"); + sb.AppendLine(await _botClient.GetChatMemberStatusAsync(_channelService.AcceptChannel, targetUser.UserID)); + sb.AppendLine(await _botClient.GetChatMemberStatusAsync(_channelService.RejectChannel, targetUser.UserID)); + sb.AppendLine(await _botClient.GetChatMemberStatusAsync(_channelService.CommentGroup, targetUser.UserID)); + sb.AppendLine(await _botClient.GetChatMemberStatusAsync(_channelService.SubGroup, targetUser.UserID)); + if (_channelService.HasSecondChannel) + { + sb.AppendLine(await _botClient.GetChatMemberStatusAsync(_channelService.SecondChannel, targetUser.UserID)); + sb.AppendLine(await _botClient.GetChatMemberStatusAsync(_channelService.SecondCommentGroup, targetUser.UserID)); + } + } await _botClient.SendCommandReply(sb.ToString(), message, false, parsemode: ParseMode.Html); @@ -1696,4 +1710,40 @@ public async Task QResponseGotoLatest(Users dbUser, CallbackQuery callbackQuery) await _botClient.AutoReplyAsync("今天没有未审核的稿件", callbackQuery, false); } } + + //TODO + //[TextCmd("RECENTMESSAGE", EUserRights.AdminCmd, Description = "查询最近发言", Alias = "RECENTMSG")] + public async Task ResponseRecentMessage(Message message, string[] args) + { + async Task exec() + { + var targetUser = await _userService.FetchTargetUser(message); + + if (targetUser == null) + { + if (args.Any()) + { + targetUser = await _userService.FetchUserByUserNameOrUserID(args.First()); + } + } + + if (targetUser == null) + { + return "找不到指定用户"; + } + + if (targetUser.Id == _channelService.BotUser.Id) + { + return "无法查询当前机器人的发言"; + } + + var sb = new StringBuilder(); + + + return sb.ToString(); + } + + var text = await exec(); + await _botClient.SendCommandReply(text, message, false, parsemode: ParseMode.Html); + } } diff --git a/XinjingdailyBot.Command/CommonCommand.cs b/XinjingdailyBot.Command/CommonCommand.cs index 60294f22..f0e31f6b 100644 --- a/XinjingdailyBot.Command/CommonCommand.cs +++ b/XinjingdailyBot.Command/CommonCommand.cs @@ -7,6 +7,7 @@ using XinjingdailyBot.Infrastructure.Attribute; using XinjingdailyBot.Infrastructure.Enums; using XinjingdailyBot.Infrastructure.Extensions; +using XinjingdailyBot.Interface.Bot.Common; using XinjingdailyBot.Interface.Bot.Handler; using XinjingdailyBot.Interface.Data; using XinjingdailyBot.Interface.Helper; @@ -25,19 +26,22 @@ internal class CommonCommand private readonly IBanRecordService _banRecordService; private readonly ITextHelperService _textHelperService; private readonly ICommandHandler _commandHandler; + private readonly IChannelService _channelService; public CommonCommand( ITelegramBotClient botClient, IOptions options, IBanRecordService banRecordService, ITextHelperService textHelperService, - ICommandHandler commandHandler) + ICommandHandler commandHandler, + IChannelService channelService) { _botClient = botClient; _optionsSetting = options.Value; _banRecordService = banRecordService; _textHelperService = textHelperService; _commandHandler = commandHandler; + _channelService = channelService; } /// @@ -151,6 +155,7 @@ public async Task ResponseMyBan(Users dbUser, Message message) var sb = new StringBuilder(); + sb.AppendLine("投稿机器人封禁状态:"); string status = dbUser.IsBan ? "已封禁" : "正常"; sb.AppendLine($"用户名: {dbUser.EscapedFullName()}"); sb.AppendLine($"用户ID: {dbUser.UserID}"); @@ -180,7 +185,7 @@ public async Task ResponseMyBan(Users dbUser, Message message) EBanType.GlobalUnBan => "撤销全局封禁", _ => "其他", }; - sb.AppendLine($"在 {date} 因为 {record.Reason} 被{operate}"); + sb.AppendLine($"在 {date} 因为 {record.Reason} 被 {operate}"); if (record.Type == EBanType.UnBan || record.Type == EBanType.Ban) { sb.AppendLine(); @@ -189,6 +194,19 @@ public async Task ResponseMyBan(Users dbUser, Message message) } sb.AppendLine("\n仅显示90天内的警告记录"); + sb.AppendLine(); + sb.AppendLine("频道和群组封禁状态:"); + sb.AppendLine(await _botClient.GetChatMemberStatusAsync(_channelService.AcceptChannel, dbUser.UserID)); + sb.AppendLine(await _botClient.GetChatMemberStatusAsync(_channelService.RejectChannel, dbUser.UserID)); + sb.AppendLine(await _botClient.GetChatMemberStatusAsync(_channelService.CommentGroup, dbUser.UserID)); + sb.AppendLine(await _botClient.GetChatMemberStatusAsync(_channelService.SubGroup, dbUser.UserID)); + + if (_channelService.HasSecondChannel) + { + sb.AppendLine(await _botClient.GetChatMemberStatusAsync(_channelService.SecondChannel, dbUser.UserID)); + sb.AppendLine(await _botClient.GetChatMemberStatusAsync(_channelService.SecondCommentGroup, dbUser.UserID)); + } + await _botClient.SendCommandReply(sb.ToString(), message, parsemode: ParseMode.Html); } } diff --git a/XinjingdailyBot.Command/NormalCommand.cs b/XinjingdailyBot.Command/NormalCommand.cs index 8f132f98..0d98c2d0 100644 --- a/XinjingdailyBot.Command/NormalCommand.cs +++ b/XinjingdailyBot.Command/NormalCommand.cs @@ -189,16 +189,14 @@ public async Task ResponseMyRight(Users dbUser, Message message) [TextCmd("ADMIN", EUserRights.NormalCmd, Description = "艾特群管理")] public async Task ResponseCallAdmins(Users dbUser, Message message) { - var sb = new StringBuilder(); - if (message.Chat.Type != ChatType.Group && message.Chat.Type != ChatType.Supergroup) { - sb.AppendLine("该命令仅在群组内有效"); + await _botClient.SendCommandReply("该命令仅在群组内有效", message, false, ParseMode.Html); } else { + var sb = new StringBuilder(); var admins = await _botClient.GetChatAdministratorsAsync(message.Chat.Id); - foreach (var menber in admins) { var admin = menber.User; @@ -207,21 +205,18 @@ public async Task ResponseCallAdmins(Users dbUser, Message message) sb.AppendLine($"@{admin.Username}"); } } - } - sb.AppendLine($"用户 {dbUser} 呼叫群管理"); + var msg = await _botClient.SendCommandReply(sb.ToString(), message, false, ParseMode.Html); + await Task.Delay(2000); - var msg = await _botClient.SendCommandReply(sb.ToString(), message, false, ParseMode.Html); - - await Task.Delay(2000); - - try - { - await _botClient.EditMessageTextAsync(msg, $"用户 {dbUser} 呼叫群管理", ParseMode.Html); - } - catch (Exception) - { - _logger.LogWarning("编辑消息失败"); + try + { + await _botClient.EditMessageTextAsync(msg, $"用户 {dbUser} 呼叫群管理", ParseMode.Html); + } + catch (Exception) + { + _logger.LogWarning("编辑消息失败"); + } } } diff --git a/XinjingdailyBot.Infrastructure/Extensions/BotClientExtension.cs b/XinjingdailyBot.Infrastructure/Extensions/BotClientExtension.cs index 54619278..ee4e9255 100644 --- a/XinjingdailyBot.Infrastructure/Extensions/BotClientExtension.cs +++ b/XinjingdailyBot.Infrastructure/Extensions/BotClientExtension.cs @@ -149,6 +149,14 @@ public static async Task SendCommandReply( return msg; } + /// + /// 发送会话状态 + /// + /// + /// + /// + /// + /// public static Task SendChatActionAsync( this ITelegramBotClient botClient, Message message, @@ -165,4 +173,48 @@ public static Task SendChatActionAsync( return Task.CompletedTask; } } + + /// + /// 获取群成员状态 + /// + /// + /// + /// + /// + public static async Task GetChatMemberStatusAsync( + this ITelegramBotClient botClient, + Chat? chat, + long userId) + { + string title = chat?.Title?.EscapeHtml() ?? "未设置群组"; + + string status; + if (chat != null) + { + try + { + var chatMember = await botClient.GetChatMemberAsync(chat, userId); + status = chatMember.Status switch { + ChatMemberStatus.Creator or + ChatMemberStatus.Administrator or + ChatMemberStatus.Member or + ChatMemberStatus.Left => "正常", + ChatMemberStatus.Kicked => "封禁", + ChatMemberStatus.Restricted => "受限", + _ => "未知", + }; + } + catch (Exception ex) + { + _logger.Error(ex, "读取用户状态出错"); + status = "出错"; + } + } + else + { + status = "---"; + } + + return string.Format("{0}: {1}", title, status); + } } diff --git a/XinjingdailyBot.Interface/Bot/Common/IChannelService.cs b/XinjingdailyBot.Interface/Bot/Common/IChannelService.cs index d0c0b5d6..933c51e6 100644 --- a/XinjingdailyBot.Interface/Bot/Common/IChannelService.cs +++ b/XinjingdailyBot.Interface/Bot/Common/IChannelService.cs @@ -31,6 +31,9 @@ public interface IChannelService /// 第二频道 /// Chat? SecondChannel { get; } + /// + /// 第二频道评论区 + /// Chat? SecondCommentGroup { get; } /// /// 拒绝频道 diff --git a/XinjingdailyBot.Interface/Bot/Handler/ICommandHandler.cs b/XinjingdailyBot.Interface/Bot/Handler/ICommandHandler.cs index 760dbc48..a7bd1648 100644 --- a/XinjingdailyBot.Interface/Bot/Handler/ICommandHandler.cs +++ b/XinjingdailyBot.Interface/Bot/Handler/ICommandHandler.cs @@ -39,5 +39,9 @@ public interface ICommandHandler /// /// Task OnQueryCommandReceived(Users dbUser, CallbackQuery query); + /// + /// 清除机器人命令 + /// + /// Task ClearCommandsMenu(); } diff --git a/XinjingdailyBot.Interface/Data/IPostService.cs b/XinjingdailyBot.Interface/Data/IPostService.cs index 682ecf3f..512f8212 100644 --- a/XinjingdailyBot.Interface/Data/IPostService.cs +++ b/XinjingdailyBot.Interface/Data/IPostService.cs @@ -44,6 +44,10 @@ public interface IPostService : IBaseService /// /// Task FetchPostFromReplyToMessage(Message message); + /// + /// 获取最新未审核稿件 + /// + /// Task GetLatestReviewingPostLink(); /// diff --git a/XinjingdailyBot.Interface/Data/IReviewStatusService.cs b/XinjingdailyBot.Interface/Data/IReviewStatusService.cs index f292d69f..ecd3655f 100644 --- a/XinjingdailyBot.Interface/Data/IReviewStatusService.cs +++ b/XinjingdailyBot.Interface/Data/IReviewStatusService.cs @@ -1,11 +1,33 @@ using Telegram.Bot.Types; +using XinjingdailyBot.Interface.Data.Base; using XinjingdailyBot.Model.Models; namespace XinjingdailyBot.Interface.Data; -public interface IReviewStatusService +/// +/// 审核状态服务 +/// +public interface IReviewStatusService : IBaseService { + /// + /// 创建新记录 + /// + /// + /// Task CreateNewReviewStatus(Message message); + /// + /// 删除旧记录 + /// + /// Task DeleteOldReviewStatus(); + /// + /// 删除记录 + /// + /// + /// Task DeleteReviewStatus(ReviewStatus reviewStatus); + /// + /// 获取旧的审核状态 + /// + /// Task GetOldReviewStatu(); } \ No newline at end of file diff --git a/XinjingdailyBot.Interface/Helper/IMarkupHelperService.cs b/XinjingdailyBot.Interface/Helper/IMarkupHelperService.cs index 6549baa6..95da3721 100644 --- a/XinjingdailyBot.Interface/Helper/IMarkupHelperService.cs +++ b/XinjingdailyBot.Interface/Helper/IMarkupHelperService.cs @@ -94,7 +94,12 @@ public interface IMarkupHelperService /// /// InlineKeyboardMarkup ReviewKeyboardB(); - InlineKeyboardMarkup ReviewStatusButton(); + /// + /// 获取指向今日最早未审核稿件的链接 + /// + /// + /// + InlineKeyboardMarkup ReviewStatusButton(NewPosts? post); /// /// 频道选项键盘 diff --git a/XinjingdailyBot.Model/Models/Users.cs b/XinjingdailyBot.Model/Models/Users.cs index c108c839..d9cdee11 100644 --- a/XinjingdailyBot.Model/Models/Users.cs +++ b/XinjingdailyBot.Model/Models/Users.cs @@ -124,11 +124,11 @@ public override string ToString() { if (string.IsNullOrEmpty(UserName)) { - return $"{FullName}(#{UserID})"; + return $"{FullName}(#{UserID})".EscapeHtml(); } else { - return $"{FullName}(@{UserName})"; + return $"{FullName}(@{UserName})".EscapeHtml(); } } diff --git a/XinjingdailyBot.Service/Helper/MarkupHelperService.cs b/XinjingdailyBot.Service/Helper/MarkupHelperService.cs index 07f965d1..bbc8b41a 100644 --- a/XinjingdailyBot.Service/Helper/MarkupHelperService.cs +++ b/XinjingdailyBot.Service/Helper/MarkupHelperService.cs @@ -539,16 +539,32 @@ public InlineKeyboardMarkup NukeMenuKeyboard(Users dbUser, Users targetUser, str return line.Any() ? new InlineKeyboardMarkup(new[] { line }) : null; } - public InlineKeyboardMarkup ReviewStatusButton() + public InlineKeyboardMarkup ReviewStatusButton(NewPosts? post) { - var keyboard = new InlineKeyboardMarkup(new[] + InlineKeyboardMarkup keyboard; + if (post != null) { - new[] - { - InlineKeyboardButton.WithCallbackData("今日最早未审核稿件", $"cmd -1 gotolatest"), - }, - }); + var chatId = Math.Abs(post.ReviewChatID + 1000000000000); + var link = $"https://t.me/c/{chatId}/{post.ReviewMsgID}"; + keyboard = new InlineKeyboardMarkup(new[] + { + new[] + { + InlineKeyboardButton.WithUrl($"前往稿件 {post.Id}", link), + }, + }); + } + else + { + keyboard = new InlineKeyboardMarkup(new[] + { + new[] + { + InlineKeyboardButton.WithCallbackData("无待审核稿件", $"cmd -1 say 无待审核稿件"), + }, + }); + } return keyboard; } } diff --git a/XinjingdailyBot.Service/Helper/TextHelperService.cs b/XinjingdailyBot.Service/Helper/TextHelperService.cs index b0853a2f..13ec1eea 100644 --- a/XinjingdailyBot.Service/Helper/TextHelperService.cs +++ b/XinjingdailyBot.Service/Helper/TextHelperService.cs @@ -17,15 +17,12 @@ namespace XinjingdailyBot.Service.Helper; [AppService(typeof(ITextHelperService), LifeTime.Transient)] internal sealed class TextHelperService : ITextHelperService { - private readonly IChannelService _channelService; private readonly TagRepository _tagRepository; public TextHelperService( - IChannelService channelService, IOptions options, TagRepository tagRepository) { - _channelService = channelService; _tagRepository = tagRepository; var postOption = options.Value.Post; diff --git a/XinjingdailyBot.Tasks/ReviewStatusTask.cs b/XinjingdailyBot.Tasks/ReviewStatusTask.cs index 17d351a2..5b97516b 100644 --- a/XinjingdailyBot.Tasks/ReviewStatusTask.cs +++ b/XinjingdailyBot.Tasks/ReviewStatusTask.cs @@ -71,7 +71,9 @@ public async Task Execute(IJobExecutionContext context) var oldPost = await _reviewStatusService.GetOldReviewStatu(); var reviewGroup = _channelService.ReviewGroup; - var kbd = _markupHelperService.ReviewStatusButton(); + + var newestPost = await _postService.GetLatestReviewingPostLink(); + var kbd = _markupHelperService.ReviewStatusButton(newestPost); if (oldPost != null) {