This commit is contained in:
@@ -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 = текст причины).
|
||||||
|
|||||||
Reference in New Issue
Block a user