diff --git a/src/TelegramPanel.Core/Interfaces/ITelegramClientPool.cs b/src/TelegramPanel.Core/Interfaces/ITelegramClientPool.cs
index 193af86..081d801 100644
--- a/src/TelegramPanel.Core/Interfaces/ITelegramClientPool.cs
+++ b/src/TelegramPanel.Core/Interfaces/ITelegramClientPool.cs
@@ -11,7 +11,14 @@ public interface ITelegramClientPool
///
/// 获取或创建指定账号的客户端
///
- Task GetOrCreateClientAsync(int accountId, int apiId, string apiHash, string sessionPath, string? phoneNumber = null, long? userId = null);
+ Task GetOrCreateClientAsync(
+ int accountId,
+ int apiId,
+ string apiHash,
+ string sessionPath,
+ string? sessionKey = null,
+ string? phoneNumber = null,
+ long? userId = null);
///
/// 获取已存在的客户端
diff --git a/src/TelegramPanel.Core/Services/Telegram/AccountService.cs b/src/TelegramPanel.Core/Services/Telegram/AccountService.cs
index a7c0aec..f5281ab 100644
--- a/src/TelegramPanel.Core/Services/Telegram/AccountService.cs
+++ b/src/TelegramPanel.Core/Services/Telegram/AccountService.cs
@@ -44,7 +44,7 @@ public class AccountService : IAccountService
_logger.LogInformation("Starting login for phone {Phone}", phone);
- var client = await _clientPool.GetOrCreateClientAsync(accountId, apiId, apiHash, sessionPath, phoneNumber: phone, userId: null);
+ var client = await _clientPool.GetOrCreateClientAsync(accountId, apiId, apiHash, sessionPath, sessionKey: apiHash, phoneNumber: phone, userId: null);
string result;
try
@@ -57,7 +57,7 @@ public class AccountService : IAccountService
TryBackupCorruptedSessionIfExists(sessionPath);
await _clientPool.RemoveClientAsync(accountId);
- client = await _clientPool.GetOrCreateClientAsync(accountId, apiId, apiHash, sessionPath, phoneNumber: phone, userId: null);
+ client = await _clientPool.GetOrCreateClientAsync(accountId, apiId, apiHash, sessionPath, sessionKey: apiHash, phoneNumber: phone, userId: null);
result = await client.Login(phone);
}
diff --git a/src/TelegramPanel.Core/Services/Telegram/ChannelService.cs b/src/TelegramPanel.Core/Services/Telegram/ChannelService.cs
index e8b5261..5294d40 100644
--- a/src/TelegramPanel.Core/Services/Telegram/ChannelService.cs
+++ b/src/TelegramPanel.Core/Services/Telegram/ChannelService.cs
@@ -1,4 +1,5 @@
using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Configuration;
using TelegramPanel.Core.Interfaces;
using TelegramPanel.Core.Models;
using TelegramPanel.Core.Services;
@@ -14,15 +15,18 @@ public class ChannelService : IChannelService
{
private readonly ITelegramClientPool _clientPool;
private readonly AccountManagementService _accountManagement;
+ private readonly IConfiguration _configuration;
private readonly ILogger _logger;
public ChannelService(
ITelegramClientPool clientPool,
AccountManagementService accountManagement,
+ IConfiguration configuration,
ILogger logger)
{
_clientPool = clientPool;
_accountManagement = accountManagement;
+ _configuration = configuration;
_logger = logger;
}
@@ -81,11 +85,23 @@ public class ChannelService : IChannelService
_logger.LogInformation("Creating channel '{Title}' for account {AccountId}", title, accountId);
- var updates = await client.Channels_CreateChannel(
- title: title,
- about: about,
- broadcast: true // true=频道, false=超级群组
- );
+ UpdatesBase updates;
+ try
+ {
+ updates = await client.Channels_CreateChannel(
+ title: title,
+ about: about,
+ broadcast: true // true=频道, false=超级群组
+ );
+ }
+ catch (RpcException ex) when (ex.Code == 420 && string.Equals(ex.Message, "FROZEN_METHOD_INVALID", StringComparison.OrdinalIgnoreCase))
+ {
+ throw new InvalidOperationException(
+ "Telegram 返回 FROZEN_METHOD_INVALID:当前 ApiId/ApiHash 或账号被 Telegram 限制调用创建频道接口。" +
+ "建议:在【系统设置】更换全局 ApiId/ApiHash(推荐使用你自己在 my.telegram.org 申请的)," +
+ "并重新导入/重新登录生成 session 后再试。",
+ ex);
+ }
var channel = updates.Chats.Values.OfType().FirstOrDefault()
?? throw new InvalidOperationException("Channel creation failed");
@@ -249,8 +265,9 @@ public class ChannelService : IChannelService
var account = await _accountManagement.GetAccountAsync(accountId)
?? throw new InvalidOperationException($"账号不存在:{accountId}");
- if (account.ApiId <= 0 || string.IsNullOrWhiteSpace(account.ApiHash))
- throw new InvalidOperationException("账号缺少 ApiId/ApiHash,无法创建 Telegram 客户端");
+ var apiId = ResolveApiId(account);
+ var apiHash = ResolveApiHash(account);
+ var sessionKey = ResolveSessionKey(account, apiHash);
if (string.IsNullOrWhiteSpace(account.SessionPath))
throw new InvalidOperationException("账号缺少 SessionPath,无法创建 Telegram 客户端");
@@ -276,7 +293,7 @@ public class ChannelService : IChannelService
}
await _clientPool.RemoveClientAsync(accountId);
- var client = await _clientPool.GetOrCreateClientAsync(accountId, account.ApiId, account.ApiHash, account.SessionPath, account.Phone, account.UserId);
+ var client = await _clientPool.GetOrCreateClientAsync(accountId, apiId, apiHash, account.SessionPath, sessionKey, account.Phone, account.UserId);
try
{
@@ -303,6 +320,32 @@ public class ChannelService : IChannelService
return client;
}
+ private int ResolveApiId(TelegramPanel.Data.Entities.Account account)
+ {
+ if (int.TryParse(_configuration["Telegram:ApiId"], out var globalApiId) && globalApiId > 0)
+ return globalApiId;
+ if (account.ApiId > 0)
+ return account.ApiId;
+ throw new InvalidOperationException("未配置全局 ApiId,且账号缺少 ApiId");
+ }
+
+ private string ResolveApiHash(TelegramPanel.Data.Entities.Account account)
+ {
+ var global = _configuration["Telegram:ApiHash"];
+ if (!string.IsNullOrWhiteSpace(global))
+ return global.Trim();
+ if (!string.IsNullOrWhiteSpace(account.ApiHash))
+ return account.ApiHash.Trim();
+ throw new InvalidOperationException("未配置全局 ApiHash,且账号缺少 ApiHash");
+ }
+
+ private static string ResolveSessionKey(TelegramPanel.Data.Entities.Account account, string apiHash)
+ {
+ // session 文件加密 key(session_key)必须与生成该 session 的 key 一致
+ // 这里优先使用账号自带 ApiHash(导入时保存的),否则退回 apiHash(全局)
+ return !string.IsNullOrWhiteSpace(account.ApiHash) ? account.ApiHash.Trim() : apiHash.Trim();
+ }
+
private static bool LooksLikeSessionApiMismatchOrCorrupted(Exception ex)
{
var msg = ex.Message ?? string.Empty;
diff --git a/src/TelegramPanel.Core/Services/Telegram/GroupService.cs b/src/TelegramPanel.Core/Services/Telegram/GroupService.cs
index cc30cbe..56128ae 100644
--- a/src/TelegramPanel.Core/Services/Telegram/GroupService.cs
+++ b/src/TelegramPanel.Core/Services/Telegram/GroupService.cs
@@ -1,4 +1,5 @@
using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Configuration;
using TelegramPanel.Core.Interfaces;
using TelegramPanel.Core.Models;
using TelegramPanel.Core.Services;
@@ -13,15 +14,18 @@ public class GroupService : IGroupService
{
private readonly ITelegramClientPool _clientPool;
private readonly AccountManagementService _accountManagement;
+ private readonly IConfiguration _configuration;
private readonly ILogger _logger;
public GroupService(
ITelegramClientPool clientPool,
AccountManagementService accountManagement,
+ IConfiguration configuration,
ILogger logger)
{
_clientPool = clientPool;
_accountManagement = accountManagement;
+ _configuration = configuration;
_logger = logger;
}
@@ -116,8 +120,9 @@ public class GroupService : IGroupService
var account = await _accountManagement.GetAccountAsync(accountId)
?? throw new InvalidOperationException($"账号不存在:{accountId}");
- if (account.ApiId <= 0 || string.IsNullOrWhiteSpace(account.ApiHash))
- throw new InvalidOperationException("账号缺少 ApiId/ApiHash,无法创建 Telegram 客户端");
+ var apiId = ResolveApiId(account);
+ var apiHash = ResolveApiHash(account);
+ var sessionKey = ResolveSessionKey(account, apiHash);
if (string.IsNullOrWhiteSpace(account.SessionPath))
throw new InvalidOperationException("账号缺少 SessionPath,无法创建 Telegram 客户端");
@@ -143,7 +148,7 @@ public class GroupService : IGroupService
}
await _clientPool.RemoveClientAsync(accountId);
- var client = await _clientPool.GetOrCreateClientAsync(accountId, account.ApiId, account.ApiHash, account.SessionPath, account.Phone, account.UserId);
+ var client = await _clientPool.GetOrCreateClientAsync(accountId, apiId, apiHash, account.SessionPath, sessionKey, account.Phone, account.UserId);
try
{
@@ -170,6 +175,30 @@ public class GroupService : IGroupService
return client;
}
+ private int ResolveApiId(TelegramPanel.Data.Entities.Account account)
+ {
+ if (int.TryParse(_configuration["Telegram:ApiId"], out var globalApiId) && globalApiId > 0)
+ return globalApiId;
+ if (account.ApiId > 0)
+ return account.ApiId;
+ throw new InvalidOperationException("未配置全局 ApiId,且账号缺少 ApiId");
+ }
+
+ private string ResolveApiHash(TelegramPanel.Data.Entities.Account account)
+ {
+ var global = _configuration["Telegram:ApiHash"];
+ if (!string.IsNullOrWhiteSpace(global))
+ return global.Trim();
+ if (!string.IsNullOrWhiteSpace(account.ApiHash))
+ return account.ApiHash.Trim();
+ throw new InvalidOperationException("未配置全局 ApiHash,且账号缺少 ApiHash");
+ }
+
+ private static string ResolveSessionKey(TelegramPanel.Data.Entities.Account account, string apiHash)
+ {
+ return !string.IsNullOrWhiteSpace(account.ApiHash) ? account.ApiHash.Trim() : apiHash.Trim();
+ }
+
private static bool LooksLikeSessionApiMismatchOrCorrupted(Exception ex)
{
var msg = ex.Message ?? string.Empty;
diff --git a/src/TelegramPanel.Core/Services/Telegram/TelegramClientPool.cs b/src/TelegramPanel.Core/Services/Telegram/TelegramClientPool.cs
index ad17205..f7c61f1 100644
--- a/src/TelegramPanel.Core/Services/Telegram/TelegramClientPool.cs
+++ b/src/TelegramPanel.Core/Services/Telegram/TelegramClientPool.cs
@@ -23,7 +23,14 @@ public class TelegramClientPool : ITelegramClientPool, IDisposable
public int ActiveClientCount => _clients.Count;
- public async Task GetOrCreateClientAsync(int accountId, int apiId, string apiHash, string sessionPath, string? phoneNumber = null, long? userId = null)
+ public async Task GetOrCreateClientAsync(
+ int accountId,
+ int apiId,
+ string apiHash,
+ string sessionPath,
+ string? sessionKey = null,
+ string? phoneNumber = null,
+ long? userId = null)
{
if (_clients.TryGetValue(accountId, out var existingClient))
{
@@ -57,6 +64,7 @@ public class TelegramClientPool : ITelegramClientPool, IDisposable
"api_id" => apiId.ToString(),
"api_hash" => apiHash,
"session_pathname" => sessionPath,
+ "session_key" => string.IsNullOrWhiteSpace(sessionKey) ? null! : sessionKey,
"phone_number" => string.IsNullOrWhiteSpace(phoneNumber) ? null! : phoneNumber,
"user_id" => userId.HasValue && userId.Value > 0 ? userId.Value.ToString() : null!,
_ => null! // 使用 null! 抑制警告,这是 WTelegramClient 的预期行为