Использовать каталоги операций и фаз Telegram
ci / build-test (pull_request) Canceled after 2m33s

This commit is contained in:
2026-09-13 20:51:43 +03:00
parent b7c5e13fc3
commit b190ac75b1
4 changed files with 36 additions and 24 deletions
@@ -35,6 +35,9 @@
единый источник вместо копий в трёх сервисах. --> единый источник вместо копий в трёх сервисах. -->
<ProjectReference Include="..\..\grpc-hosting\Deal.Grpc.Hosting\Deal.Grpc.Hosting.csproj" /> <ProjectReference Include="..\..\grpc-hosting\Deal.Grpc.Hosting\Deal.Grpc.Hosting.csproj" />
<ProjectReference Include="..\..\contracts\Deal.Proto.csproj" /> <ProjectReference Include="..\..\contracts\Deal.Proto.csproj" />
<!-- Каталоги констант интеграции (TelegramOperations/TelegramAuthPhases): единый источник
строковых кодов операций и фаз вместо литералов в сервисе. -->
<ProjectReference Include="..\..\core\Deal.Contracts\Deal.Contracts.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>
@@ -1,3 +1,4 @@
using Deal.Contracts.Integrations.Models;
using Deal.Telegram.Telegram; using Deal.Telegram.Telegram;
using Grpc.Core; using Grpc.Core;
@@ -244,7 +245,7 @@ public sealed class TenantSession : IAsyncDisposable
throw; throw;
} }
if (nextStep == "password") if (nextStep == TelegramAuthPhases.Password)
{ {
_phase = AuthPhase.Password; _phase = AuthPhase.Password;
return Snapshot(); return Snapshot();
@@ -1,4 +1,5 @@
using System.Globalization; using System.Globalization;
using Deal.Contracts.Integrations.Models;
using Deal.Telegram.Caching; using Deal.Telegram.Caching;
using Deal.Telegram.Sessions; using Deal.Telegram.Sessions;
using Grpc.Core; using Grpc.Core;
@@ -31,6 +32,12 @@ public sealed class WTelegramSessionClient : ISessionClient
// Ёмкость LRU-кэша сущностей пользователей (последние использованные имена). // Ёмкость LRU-кэша сущностей пользователей (последние использованные имена).
private const int UserEntityCacheCapacity = 2000; private const int UserEntityCacheCapacity = 2000;
// Ключ конфигурации WTelegramClient с api_id приложения.
private const string ApiIdKey = "api_id";
// Ключ конфигурации WTelegramClient с api_hash приложения.
private const string ApiHashKey = "api_hash";
// LRU-кэш access_hash сущностей (ключ — подписанный id диалога; заполняется из ответов). // LRU-кэш access_hash сущностей (ключ — подписанный id диалога; заполняется из ответов).
private readonly LruCache<string, long> _entityAccessHashes = new(AccessHashCacheCapacity); private readonly LruCache<string, long> _entityAccessHashes = new(AccessHashCacheCapacity);
@@ -128,7 +135,7 @@ public sealed class WTelegramSessionClient : ISessionClient
catch (RpcException exception) when (exception.Code == 401 && exception.Message == "SESSION_PASSWORD_NEEDED") catch (RpcException exception) when (exception.Code == 401 && exception.Message == "SESSION_PASSWORD_NEEDED")
{ {
// Включён 2FA — следующий шаг: облачный пароль (submit_password). // Включён 2FA — следующий шаг: облачный пароль (submit_password).
return "password"; return TelegramAuthPhases.Password;
} }
catch (RpcException exception) when (exception.Code == 400 && exception.Message == "PHONE_CODE_INVALID") catch (RpcException exception) when (exception.Code == 400 && exception.Message == "PHONE_CODE_INVALID")
{ {
@@ -729,8 +736,8 @@ public sealed class WTelegramSessionClient : ISessionClient
private string? ConfigProvider(string what) private string? ConfigProvider(string what)
=> what switch => what switch
{ {
"api_id" => _apiId.ToString(System.Globalization.CultureInfo.InvariantCulture), ApiIdKey => _apiId.ToString(System.Globalization.CultureInfo.InvariantCulture),
"api_hash" => _apiHash, ApiHashKey => _apiHash,
_ => null, _ => null,
}; };
@@ -1,3 +1,4 @@
using Deal.Contracts.Integrations.Models;
using Deal.Grpc.Telegram; using Deal.Grpc.Telegram;
using Deal.Telegram.Core; using Deal.Telegram.Core;
using Deal.Telegram.Dialogs; using Deal.Telegram.Dialogs;
@@ -106,7 +107,7 @@ public sealed class TelegramServiceImpl : TelegramService.TelegramServiceBase
TenantSessionSnapshot snapshot = await ExecuteAsync( TenantSessionSnapshot snapshot = await ExecuteAsync(
tenantId, tenantId,
ct => _sessionFarm.StartPhoneAsync(tenantId, request.ApiId, request.ApiHash, request.Phone, ct), ct => _sessionFarm.StartPhoneAsync(tenantId, request.ApiId, request.ApiHash, request.Phone, ct),
"start_phone", TelegramOperations.StartPhone,
context).ConfigureAwait(false); context).ConfigureAwait(false);
return new StartPhoneReply { Phase = PhaseToString(snapshot.Phase) }; return new StartPhoneReply { Phase = PhaseToString(snapshot.Phase) };
@@ -122,7 +123,7 @@ public sealed class TelegramServiceImpl : TelegramService.TelegramServiceBase
TenantSessionSnapshot snapshot = await ExecuteAsync( TenantSessionSnapshot snapshot = await ExecuteAsync(
tenantId, tenantId,
ct => _sessionFarm.StartQrAsync(tenantId, request.ApiId, request.ApiHash, ct), ct => _sessionFarm.StartQrAsync(tenantId, request.ApiId, request.ApiHash, ct),
"start_qr", TelegramOperations.StartQr,
context).ConfigureAwait(false); context).ConfigureAwait(false);
var reply = new StartQrReply { Phase = PhaseToString(snapshot.Phase) }; var reply = new StartQrReply { Phase = PhaseToString(snapshot.Phase) };
@@ -144,7 +145,7 @@ public sealed class TelegramServiceImpl : TelegramService.TelegramServiceBase
TenantSessionSnapshot snapshot = await ExecuteAsync( TenantSessionSnapshot snapshot = await ExecuteAsync(
tenantId, tenantId,
ct => _sessionFarm.SendCodeAsync(tenantId, request.Code, ct), ct => _sessionFarm.SendCodeAsync(tenantId, request.Code, ct),
"send_code", TelegramOperations.SendCode,
context).ConfigureAwait(false); context).ConfigureAwait(false);
return new SendCodeReply { Phase = PhaseToString(snapshot.Phase) }; return new SendCodeReply { Phase = PhaseToString(snapshot.Phase) };
@@ -160,7 +161,7 @@ public sealed class TelegramServiceImpl : TelegramService.TelegramServiceBase
TenantSessionSnapshot snapshot = await ExecuteAsync( TenantSessionSnapshot snapshot = await ExecuteAsync(
tenantId, tenantId,
ct => _sessionFarm.SendPasswordAsync(tenantId, request.Password, ct), ct => _sessionFarm.SendPasswordAsync(tenantId, request.Password, ct),
"send_password", TelegramOperations.SendPassword,
context).ConfigureAwait(false); context).ConfigureAwait(false);
return new SendPasswordReply { Phase = PhaseToString(snapshot.Phase) }; return new SendPasswordReply { Phase = PhaseToString(snapshot.Phase) };
@@ -176,7 +177,7 @@ public sealed class TelegramServiceImpl : TelegramService.TelegramServiceBase
await ExecuteAsync( await ExecuteAsync(
tenantId, tenantId,
ct => _sessionFarm.LogoutAsync(tenantId, ct), ct => _sessionFarm.LogoutAsync(tenantId, ct),
"logout", TelegramOperations.Logout,
context).ConfigureAwait(false); context).ConfigureAwait(false);
_catalog.Reset(tenantId); _catalog.Reset(tenantId);
@@ -208,7 +209,7 @@ public sealed class TelegramServiceImpl : TelegramService.TelegramServiceBase
result.Entries.AddRange(entries); result.Entries.AddRange(entries);
return result; return result;
}, },
"refresh_dialogs", TelegramOperations.RefreshDialogs,
context).ConfigureAwait(false); context).ConfigureAwait(false);
return reply; return reply;
} }
@@ -257,7 +258,7 @@ public sealed class TelegramServiceImpl : TelegramService.TelegramServiceBase
int processed = await ExecuteAsync( int processed = await ExecuteAsync(
tenantId, tenantId,
ct => _backfill.ExecuteAsync(tenantId, request.DialogId, request.Force, ct), ct => _backfill.ExecuteAsync(tenantId, request.DialogId, request.Force, ct),
"backfill", TelegramOperations.Backfill,
context).ConfigureAwait(false); context).ConfigureAwait(false);
return new BackfillReply { Processed = processed }; return new BackfillReply { Processed = processed };
} }
@@ -285,7 +286,7 @@ public sealed class TelegramServiceImpl : TelegramService.TelegramServiceBase
await _sessionFarm.MarkReadAsync(tenantId, request.DialogId, ct).ConfigureAwait(false); await _sessionFarm.MarkReadAsync(tenantId, request.DialogId, ct).ConfigureAwait(false);
return result; return result;
}, },
"read_recent", TelegramOperations.ReadRecent,
context).ConfigureAwait(false); context).ConfigureAwait(false);
return reply; return reply;
} }
@@ -323,7 +324,7 @@ public sealed class TelegramServiceImpl : TelegramService.TelegramServiceBase
Time = message.DateMs, Time = message.DateMs,
}; };
}, },
"read_source", TelegramOperations.ReadSource,
context).ConfigureAwait(false); context).ConfigureAwait(false);
return reply; return reply;
} }
@@ -349,7 +350,7 @@ public sealed class TelegramServiceImpl : TelegramService.TelegramServiceBase
result.Results.AddRange(found.Select(DialogProtoMapper.ToEntry)); result.Results.AddRange(found.Select(DialogProtoMapper.ToEntry));
return result; return result;
}, },
"search", TelegramOperations.Search,
context).ConfigureAwait(false); context).ConfigureAwait(false);
return reply; return reply;
} }
@@ -371,7 +372,7 @@ public sealed class TelegramServiceImpl : TelegramService.TelegramServiceBase
.ConfigureAwait(false); .ConfigureAwait(false);
return new GetInfoReply { Info = DiscoveryProtoMapper.ToChannelInfo(info) }; return new GetInfoReply { Info = DiscoveryProtoMapper.ToChannelInfo(info) };
}, },
"discovery_info", TelegramOperations.DiscoveryInfo,
context).ConfigureAwait(false); context).ConfigureAwait(false);
return reply; return reply;
} }
@@ -393,7 +394,7 @@ public sealed class TelegramServiceImpl : TelegramService.TelegramServiceBase
.ConfigureAwait(false); .ConfigureAwait(false);
return DiscoveryProtoMapper.ToReadForEvalReply(result); return DiscoveryProtoMapper.ToReadForEvalReply(result);
}, },
"discovery_read", TelegramOperations.DiscoveryRead,
context).ConfigureAwait(false); context).ConfigureAwait(false);
return reply; return reply;
} }
@@ -414,7 +415,7 @@ public sealed class TelegramServiceImpl : TelegramService.TelegramServiceBase
await _discovery.JoinAsync(tenantId, normalizedUsername, ct).ConfigureAwait(false); await _discovery.JoinAsync(tenantId, normalizedUsername, ct).ConfigureAwait(false);
return true; return true;
}, },
"join", TelegramOperations.Join,
context).ConfigureAwait(false); context).ConfigureAwait(false);
return new JoinReply { Ok = true }; return new JoinReply { Ok = true };
} }
@@ -434,7 +435,7 @@ public sealed class TelegramServiceImpl : TelegramService.TelegramServiceBase
await _discovery.LeaveAsync(tenantId, request.DialogId, ct).ConfigureAwait(false); await _discovery.LeaveAsync(tenantId, request.DialogId, ct).ConfigureAwait(false);
return true; return true;
}, },
"leave", TelegramOperations.Leave,
context).ConfigureAwait(false); context).ConfigureAwait(false);
return new LeaveReply { Ok = true }; return new LeaveReply { Ok = true };
} }
@@ -534,12 +535,12 @@ public sealed class TelegramServiceImpl : TelegramService.TelegramServiceBase
private static string PhaseToString(AuthPhase phase) private static string PhaseToString(AuthPhase phase)
=> phase switch => phase switch
{ {
AuthPhase.Phone => "phone", AuthPhase.Phone => TelegramAuthPhases.Phone,
AuthPhase.Code => "code", AuthPhase.Code => TelegramAuthPhases.Code,
AuthPhase.Password => "password", AuthPhase.Password => TelegramAuthPhases.Password,
AuthPhase.Qr => "qr", AuthPhase.Qr => TelegramAuthPhases.Qr,
AuthPhase.Ready => "ready", AuthPhase.Ready => TelegramAuthPhases.Ready,
_ => "idle", _ => TelegramAuthPhases.Idle,
}; };
// Доменная ошибка сессии → RpcException контракта (код + detail = текст причины). // Доменная ошибка сессии → RpcException контракта (код + detail = текст причины).