修复Bot频道同步重复:按chat_id去重并仅记录管理员频道
This commit is contained in:
1 parent
dd85d08658
commit
e71ce7cf55
3 files changed
+49
-27
No files matched your search
@@ -52,7 +52,9 @@ public class BotTelegramService
|
||||
if (result.ValueKind != JsonValueKind.Array)
|
||||
return 0;
|
||||
|
||||
var applied = 0;
|
||||
// Telegram 会针对同一个频道连续产生多条 my_chat_member(例如 member -> administrator),
|
||||
// 这里按 chat_id 去重并只应用“最后一次状态”,避免“新增两个”的错觉/重复写库。
|
||||
var changesByChatId = new Dictionary<long, BotChatMemberChange>();
|
||||
long? maxUpdateId = null;
|
||||
|
||||
foreach (var update in result.EnumerateArray())
|
||||
@@ -74,32 +76,44 @@ public class BotTelegramService
|
||||
if (!TryParseChatMemberUpdate(myChatMember, out var chat, out var status))
|
||||
continue;
|
||||
|
||||
// channel/supergroup 才纳入列表
|
||||
if (chat.Type is not ("channel" or "supergroup"))
|
||||
// 仅同步“频道”(不包含群组/超级群组),避免把讨论群等误当成频道条目
|
||||
if (chat.Type is not "channel")
|
||||
continue;
|
||||
|
||||
if (status is "left" or "kicked")
|
||||
changesByChatId[chat.Id] = new BotChatMemberChange(chat, status);
|
||||
}
|
||||
|
||||
var affected = 0;
|
||||
foreach (var kv in changesByChatId)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var chatId = kv.Key;
|
||||
var change = kv.Value;
|
||||
|
||||
// 只把“具备管理员/创建者权限”的频道纳入 Bot 列表;
|
||||
// left/kicked 或降权为 member 等,直接从列表移除(否则导出邀请会失败且列表不准)。
|
||||
if (change.Status is "administrator" or "creator")
|
||||
{
|
||||
await _botManagement.DeleteChannelByTelegramIdAsync(bot.Id, chat.Id);
|
||||
applied++;
|
||||
continue;
|
||||
await _botManagement.UpsertChannelAsync(new BotChannel
|
||||
{
|
||||
BotId = bot.Id,
|
||||
TelegramId = chatId,
|
||||
Title = string.IsNullOrWhiteSpace(change.Chat.Title) ? $"频道 {chatId}" : change.Chat.Title,
|
||||
Username = string.IsNullOrWhiteSpace(change.Chat.Username) ? null : change.Chat.Username.Trim().TrimStart('@'),
|
||||
IsBroadcast = true,
|
||||
MemberCount = 0,
|
||||
About = null,
|
||||
AccessHash = null,
|
||||
CreatedAt = null
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
await _botManagement.DeleteChannelByTelegramIdAsync(bot.Id, chatId);
|
||||
}
|
||||
|
||||
// member/administrator/creator -> upsert
|
||||
await _botManagement.UpsertChannelAsync(new BotChannel
|
||||
{
|
||||
BotId = bot.Id,
|
||||
TelegramId = chat.Id,
|
||||
Title = string.IsNullOrWhiteSpace(chat.Title) ? $"频道 {chat.Id}" : chat.Title,
|
||||
Username = string.IsNullOrWhiteSpace(chat.Username) ? null : chat.Username.Trim().TrimStart('@'),
|
||||
IsBroadcast = chat.Type == "channel",
|
||||
MemberCount = 0,
|
||||
About = null,
|
||||
AccessHash = null,
|
||||
CreatedAt = null
|
||||
});
|
||||
|
||||
applied++;
|
||||
affected++;
|
||||
}
|
||||
|
||||
if (maxUpdateId.HasValue)
|
||||
@@ -107,7 +121,13 @@ public class BotTelegramService
|
||||
bot.LastSyncAt = DateTime.UtcNow;
|
||||
await _botManagement.UpdateBotAsync(bot);
|
||||
|
||||
return applied;
|
||||
if (affected > 0)
|
||||
{
|
||||
var ids = string.Join(", ", changesByChatId.Keys.Take(5));
|
||||
_logger.LogInformation("Bot {BotId} updates applied: affected {Affected} chats (first: {ChatIds})", botId, affected, ids);
|
||||
}
|
||||
|
||||
return affected;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -192,6 +212,6 @@ public class BotTelegramService
|
||||
return true;
|
||||
}
|
||||
|
||||
private readonly record struct BotChatMemberChange(BotApiChat Chat, string Status);
|
||||
private readonly record struct BotApiChat(long Id, string Type, string? Title, string? Username);
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@
|
||||
try
|
||||
{
|
||||
var count = await BotTelegram.SyncBotChannelsAsync(BotId, CancellationToken.None);
|
||||
Snackbar.Add($"同步完成:{count} 个频道", Severity.Success);
|
||||
Snackbar.Add($"同步完成:影响 {count} 个频道", Severity.Success);
|
||||
await LoadAll();
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -304,4 +304,3 @@
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,10 @@ public class BotAutoSyncBackgroundService : BackgroundService
|
||||
try
|
||||
{
|
||||
var count = await botTelegram.SyncBotChannelsAsync(bot.Id, cancellationToken);
|
||||
_logger.LogInformation("Bot auto sync: bot {BotId} synced {Count} channels", bot.Id, count);
|
||||
if (count > 0)
|
||||
_logger.LogInformation("Bot auto sync: bot {BotId} synced {Count} channels", bot.Id, count);
|
||||
else
|
||||
_logger.LogDebug("Bot auto sync: bot {BotId} synced 0 channels", bot.Id);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user