Отформатировать списки параметров по код-стайлу
Больше двух параметров — каждый на отдельной строке (закрывающая скобка в конце последнего); два и меньше — в одну строку. Правило добавлено в docs/spec/Код-стайл-Дейл.md; применено к 628 сигнатурам в 253 файлах.
This commit is contained in:
@@ -39,7 +39,10 @@ public sealed class CoreIngressClient : ICoreIngressClient
|
||||
/// <param name="options">Конфигурация (адрес из env, service-token).</param>
|
||||
/// <param name="logger">Логгер.</param>
|
||||
/// <param name="mtlsCertificates">Сертификаты mTLS (Ruling 6, Task 13): null — plaintext-канал (dev).</param>
|
||||
public CoreIngressClient(CoreIngressOptions options, ILogger<CoreIngressClient> logger, MtlsCertificates? mtlsCertificates = null)
|
||||
public CoreIngressClient(
|
||||
CoreIngressOptions options,
|
||||
ILogger<CoreIngressClient> logger,
|
||||
MtlsCertificates? mtlsCertificates = null)
|
||||
{
|
||||
_options = options;
|
||||
_logger = logger;
|
||||
@@ -47,7 +50,10 @@ public sealed class CoreIngressClient : ICoreIngressClient
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<PushMessageReply> PushMessageAsync(string tenantId, PushMessageRequest message, CancellationToken cancellationToken)
|
||||
public async Task<PushMessageReply> PushMessageAsync(
|
||||
string tenantId,
|
||||
PushMessageRequest message,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
IngressService.IngressServiceClient client = GetClient();
|
||||
try
|
||||
@@ -61,7 +67,10 @@ public sealed class CoreIngressClient : ICoreIngressClient
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IReadOnlyList<string>> SyncDialogsAsync(string tenantId, IReadOnlyList<DialogEntry> entries, CancellationToken cancellationToken)
|
||||
public async Task<IReadOnlyList<string>> SyncDialogsAsync(
|
||||
string tenantId,
|
||||
IReadOnlyList<DialogEntry> entries,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
IngressService.IngressServiceClient client = GetClient();
|
||||
var request = new SyncDialogsRequest();
|
||||
|
||||
@@ -21,7 +21,10 @@ public interface ICoreIngressClient
|
||||
/// <param name="message">Сообщение в контракте PushMessageRequest.</param>
|
||||
/// <param name="cancellationToken">Отмена вызова.</param>
|
||||
/// <returns>Ответ ядра (accepted/duplicate — дубль dialog+msgId в очереди не растёт).</returns>
|
||||
public Task<PushMessageReply> PushMessageAsync(string tenantId, PushMessageRequest message, CancellationToken cancellationToken);
|
||||
public Task<PushMessageReply> PushMessageAsync(
|
||||
string tenantId,
|
||||
PushMessageRequest message,
|
||||
CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Синхронизирует каталог с ядром (Ingress.SyncDialogs → SyncFromTelegram, Ruling 7). Ядро применяет
|
||||
@@ -32,5 +35,8 @@ public interface ICoreIngressClient
|
||||
/// <param name="entries">Актуальный каталог диалогов (как refresh_dialogs).</param>
|
||||
/// <param name="cancellationToken">Отмена вызова.</param>
|
||||
/// <returns>Список id диалогов с включённым мониторингом (по версии ядра).</returns>
|
||||
public Task<IReadOnlyList<string>> SyncDialogsAsync(string tenantId, IReadOnlyList<DialogEntry> entries, CancellationToken cancellationToken);
|
||||
public Task<IReadOnlyList<string>> SyncDialogsAsync(
|
||||
string tenantId,
|
||||
IReadOnlyList<DialogEntry> entries,
|
||||
CancellationToken cancellationToken);
|
||||
}
|
||||
|
||||
@@ -89,7 +89,11 @@ public sealed class BackfillService
|
||||
/// <param name="force">True — «Перечитать» по кнопке (семантика флага — в ядре, см. класс).</param>
|
||||
/// <param name="cancellationToken">Отмена операции.</param>
|
||||
/// <returns>Сколько сообщений отправлено в ядро (0 — диалог уже перечитывается/нет текстов).</returns>
|
||||
public async Task<int> ExecuteAsync(string tenantId, string dialogId, bool force, CancellationToken cancellationToken)
|
||||
public async Task<int> ExecuteAsync(
|
||||
string tenantId,
|
||||
string dialogId,
|
||||
bool force,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var key = (tenantId, dialogId);
|
||||
if (!_running.TryAdd(key, 0))
|
||||
@@ -168,7 +172,10 @@ public sealed class BackfillService
|
||||
// dialogId: Подписанный id диалога.
|
||||
// cancellationToken: Отмена операции.
|
||||
// Возвращает: Сколько сообщений отправлено в ядро.
|
||||
private async Task<int> BackfillDialogAsync(string tenantId, string dialogId, CancellationToken cancellationToken)
|
||||
private async Task<int> BackfillDialogAsync(
|
||||
string tenantId,
|
||||
string dialogId,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
IReadOnlyList<TelegramMessage> messages = await _sessionFarm
|
||||
.GetMessagesAsync(tenantId, dialogId, MessagesLimit, cancellationToken)
|
||||
|
||||
@@ -43,7 +43,10 @@ public sealed class DialogCatalog
|
||||
/// <param name="tenantId">Id тенанта.</param>
|
||||
/// <param name="dialogId">Id диалога.</param>
|
||||
/// <param name="enabled">Мониторить (true) или выключить (false).</param>
|
||||
public void SetMonitored(string tenantId, string dialogId, bool enabled)
|
||||
public void SetMonitored(
|
||||
string tenantId,
|
||||
string dialogId,
|
||||
bool enabled)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(tenantId);
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(dialogId);
|
||||
|
||||
@@ -17,5 +17,8 @@ public interface IBackfillPacer
|
||||
/// <param name="maxSeconds">Верхняя граница паузы, секунды (≥ minSeconds).</param>
|
||||
/// <param name="cancellationToken">Отмена ожидания.</param>
|
||||
/// <returns>Задача ожидания.</returns>
|
||||
public Task WaitAsync(double minSeconds, double maxSeconds, CancellationToken cancellationToken);
|
||||
public Task WaitAsync(
|
||||
double minSeconds,
|
||||
double maxSeconds,
|
||||
CancellationToken cancellationToken);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,10 @@ namespace Deal.Telegram.Dialogs;
|
||||
public sealed class RandomBackfillPacer : IBackfillPacer
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public async Task WaitAsync(double minSeconds, double maxSeconds, CancellationToken cancellationToken)
|
||||
public async Task WaitAsync(
|
||||
double minSeconds,
|
||||
double maxSeconds,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
if (maxSeconds < 0 || minSeconds < 0 || minSeconds > maxSeconds)
|
||||
{
|
||||
|
||||
@@ -47,7 +47,11 @@ public sealed class RealtimeSweep
|
||||
/// <param name="catalog">Зеркало каталога/мониторинга (актуализируется ответом SyncDialogs).</param>
|
||||
/// <param name="ingress">Канал в ядро (PushMessage/SyncDialogs).</param>
|
||||
/// <param name="logger">Логгер.</param>
|
||||
public RealtimeSweep(SessionFarm sessionFarm, DialogCatalog catalog, ICoreIngressClient ingress, ILogger<RealtimeSweep> logger)
|
||||
public RealtimeSweep(
|
||||
SessionFarm sessionFarm,
|
||||
DialogCatalog catalog,
|
||||
ICoreIngressClient ingress,
|
||||
ILogger<RealtimeSweep> logger)
|
||||
{
|
||||
_sessionFarm = sessionFarm;
|
||||
_catalog = catalog;
|
||||
@@ -136,7 +140,10 @@ public sealed class RealtimeSweep
|
||||
// tenantId: Id тенанта.
|
||||
// dialog: Диалог с unread_count > 0.
|
||||
// cancellationToken: Отмена операции.
|
||||
private async Task SweepDialogAsync(string tenantId, TelegramDialog dialog, CancellationToken cancellationToken)
|
||||
private async Task SweepDialogAsync(
|
||||
string tenantId,
|
||||
TelegramDialog dialog,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -48,7 +48,10 @@ public sealed class DiscoveryOps
|
||||
/// <param name="sessionFarm">Пул сессий тенантов (операции только на сессии своего тенанта).</param>
|
||||
/// <param name="pacer">Анти-бан-паузы (реальный — случайные 2–4 с, тесты — фейк).</param>
|
||||
/// <param name="logger">Логгер.</param>
|
||||
public DiscoveryOps(SessionFarm sessionFarm, IBackfillPacer pacer, ILogger<DiscoveryOps> logger)
|
||||
public DiscoveryOps(
|
||||
SessionFarm sessionFarm,
|
||||
IBackfillPacer pacer,
|
||||
ILogger<DiscoveryOps> logger)
|
||||
{
|
||||
_sessionFarm = sessionFarm;
|
||||
_pacer = pacer;
|
||||
@@ -65,7 +68,11 @@ public sealed class DiscoveryOps
|
||||
/// <param name="limit">Верхняя граница результата (≤ 0 — прототип-дефолт 30).</param>
|
||||
/// <param name="cancellationToken">Отмена операции.</param>
|
||||
/// <returns>Найденные источники (каналы/группы/личные) без дублей, не длиннее limit.</returns>
|
||||
public async Task<IReadOnlyList<TelegramDialog>> SearchAsync(string tenantId, string query, int limit, CancellationToken cancellationToken)
|
||||
public async Task<IReadOnlyList<TelegramDialog>> SearchAsync(
|
||||
string tenantId,
|
||||
string query,
|
||||
int limit,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
int effectiveLimit = limit > 0 ? limit : SearchDefaultLimit;
|
||||
IReadOnlyList<TelegramDialog> found = await _sessionFarm
|
||||
@@ -84,7 +91,10 @@ public sealed class DiscoveryOps
|
||||
/// <param name="dialogId">Подписанный id источника («-100…»/«-…»/«+…»).</param>
|
||||
/// <param name="cancellationToken">Отмена операции.</param>
|
||||
/// <returns>Инфо об источнике (сбои определения не бросаются — см. ISessionClient.GetInfoAsync).</returns>
|
||||
public Task<TelegramSourceInfo> GetInfoAsync(string tenantId, string dialogId, CancellationToken cancellationToken)
|
||||
public Task<TelegramSourceInfo> GetInfoAsync(
|
||||
string tenantId,
|
||||
string dialogId,
|
||||
CancellationToken cancellationToken)
|
||||
=> _sessionFarm.GetInfoAsync(tenantId, dialogId, cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
@@ -95,7 +105,11 @@ public sealed class DiscoveryOps
|
||||
/// <param name="limit">Размер выборки (≤ 0 — дефолт; форумы читаются по активным темам).</param>
|
||||
/// <param name="cancellationToken">Отмена операции.</param>
|
||||
/// <returns>ok/сообщения либо ok=false/error="no_history" (не ошибка RPC).</returns>
|
||||
public Task<DiscoveryReadResult> ReadForEvalAsync(string tenantId, string dialogId, int limit, CancellationToken cancellationToken)
|
||||
public Task<DiscoveryReadResult> ReadForEvalAsync(
|
||||
string tenantId,
|
||||
string dialogId,
|
||||
int limit,
|
||||
CancellationToken cancellationToken)
|
||||
=> _sessionFarm.ReadForEvalAsync(tenantId, dialogId, limit > 0 ? limit : ReadForEvalDefaultLimit, cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
@@ -106,7 +120,10 @@ public sealed class DiscoveryOps
|
||||
/// <param name="tenantId">Id тенанта.</param>
|
||||
/// <param name="username">Username источника («@»/пробелы нормализуются).</param>
|
||||
/// <param name="cancellationToken">Отмена операции.</param>
|
||||
public async Task JoinAsync(string tenantId, string username, CancellationToken cancellationToken)
|
||||
public async Task JoinAsync(
|
||||
string tenantId,
|
||||
string username,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
string normalized = NormalizeUsername(username);
|
||||
if (normalized.Length == 0)
|
||||
@@ -124,7 +141,10 @@ public sealed class DiscoveryOps
|
||||
/// <param name="tenantId">Id тенанта.</param>
|
||||
/// <param name="dialogId">Подписанный id диалога.</param>
|
||||
/// <param name="cancellationToken">Отмена операции.</param>
|
||||
public Task LeaveAsync(string tenantId, string dialogId, CancellationToken cancellationToken)
|
||||
public Task LeaveAsync(
|
||||
string tenantId,
|
||||
string dialogId,
|
||||
CancellationToken cancellationToken)
|
||||
=> _sessionFarm.LeaveAsync(tenantId, dialogId, cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -18,7 +18,10 @@ public sealed class SessionException : Exception
|
||||
/// <param name="code">gRPC-статус ошибки (контракт telegram.proto, шапка файла).</param>
|
||||
/// <param name="message">Текст причины — detail RPC (1:1 с текстами прототипа).</param>
|
||||
/// <param name="innerException">Внутренняя причина (исключение Telegram/адаптера), если есть.</param>
|
||||
public SessionException(StatusCode code, string message, Exception? innerException = null)
|
||||
public SessionException(
|
||||
StatusCode code,
|
||||
string message,
|
||||
Exception? innerException = null)
|
||||
: base(message, innerException)
|
||||
{
|
||||
Code = code;
|
||||
|
||||
@@ -56,7 +56,10 @@ public sealed class SessionFarm
|
||||
/// <param name="tenantId">Id тенанта.</param>
|
||||
/// <param name="limit">Верхняя граница числа диалогов.</param>
|
||||
/// <param name="cancellationToken">Отмена операции.</param>
|
||||
public Task<IReadOnlyList<TelegramDialog>> ListDialogsAsync(string tenantId, int limit, CancellationToken cancellationToken)
|
||||
public Task<IReadOnlyList<TelegramDialog>> ListDialogsAsync(
|
||||
string tenantId,
|
||||
int limit,
|
||||
CancellationToken cancellationToken)
|
||||
=> RequireSession(tenantId).ListDialogsAsync(limit, cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
@@ -66,7 +69,11 @@ public sealed class SessionFarm
|
||||
/// <param name="dialogId">Подписанный id диалога.</param>
|
||||
/// <param name="limit">Сколько последних сообщений запросить.</param>
|
||||
/// <param name="cancellationToken">Отмена операции.</param>
|
||||
public Task<IReadOnlyList<TelegramMessage>> GetMessagesAsync(string tenantId, string dialogId, int limit, CancellationToken cancellationToken)
|
||||
public Task<IReadOnlyList<TelegramMessage>> GetMessagesAsync(
|
||||
string tenantId,
|
||||
string dialogId,
|
||||
int limit,
|
||||
CancellationToken cancellationToken)
|
||||
=> RequireSession(tenantId).GetMessagesAsync(dialogId, limit, cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
@@ -75,7 +82,10 @@ public sealed class SessionFarm
|
||||
/// <param name="tenantId">Id тенанта.</param>
|
||||
/// <param name="dialogId">Подписанный id диалога.</param>
|
||||
/// <param name="cancellationToken">Отмена операции.</param>
|
||||
public Task MarkReadAsync(string tenantId, string dialogId, CancellationToken cancellationToken)
|
||||
public Task MarkReadAsync(
|
||||
string tenantId,
|
||||
string dialogId,
|
||||
CancellationToken cancellationToken)
|
||||
=> RequireSession(tenantId).MarkReadAsync(dialogId, cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
@@ -85,7 +95,11 @@ public sealed class SessionFarm
|
||||
/// <param name="query">Поисковый запрос (ключ задачи discovery).</param>
|
||||
/// <param name="limit">Верхняя граница результата.</param>
|
||||
/// <param name="cancellationToken">Отмена операции.</param>
|
||||
public Task<IReadOnlyList<TelegramDialog>> SearchAsync(string tenantId, string query, int limit, CancellationToken cancellationToken)
|
||||
public Task<IReadOnlyList<TelegramDialog>> SearchAsync(
|
||||
string tenantId,
|
||||
string query,
|
||||
int limit,
|
||||
CancellationToken cancellationToken)
|
||||
=> RequireSession(tenantId).SearchAsync(query, limit, cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
@@ -94,7 +108,10 @@ public sealed class SessionFarm
|
||||
/// <param name="tenantId">Id тенанта.</param>
|
||||
/// <param name="dialogId">Подписанный id источника.</param>
|
||||
/// <param name="cancellationToken">Отмена операции.</param>
|
||||
public Task<TelegramSourceInfo> GetInfoAsync(string tenantId, string dialogId, CancellationToken cancellationToken)
|
||||
public Task<TelegramSourceInfo> GetInfoAsync(
|
||||
string tenantId,
|
||||
string dialogId,
|
||||
CancellationToken cancellationToken)
|
||||
=> RequireSession(tenantId).GetInfoAsync(dialogId, cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
@@ -104,7 +121,11 @@ public sealed class SessionFarm
|
||||
/// <param name="dialogId">Подписанный id источника.</param>
|
||||
/// <param name="limit">Размер выборки.</param>
|
||||
/// <param name="cancellationToken">Отмена операции.</param>
|
||||
public Task<DiscoveryReadResult> ReadForEvalAsync(string tenantId, string dialogId, int limit, CancellationToken cancellationToken)
|
||||
public Task<DiscoveryReadResult> ReadForEvalAsync(
|
||||
string tenantId,
|
||||
string dialogId,
|
||||
int limit,
|
||||
CancellationToken cancellationToken)
|
||||
=> RequireSession(tenantId).ReadForEvalAsync(dialogId, limit, cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
@@ -113,7 +134,10 @@ public sealed class SessionFarm
|
||||
/// <param name="tenantId">Id тенанта.</param>
|
||||
/// <param name="username">Username (без «@»; нормализует DiscoveryOps).</param>
|
||||
/// <param name="cancellationToken">Отмена операции.</param>
|
||||
public Task JoinAsync(string tenantId, string username, CancellationToken cancellationToken)
|
||||
public Task JoinAsync(
|
||||
string tenantId,
|
||||
string username,
|
||||
CancellationToken cancellationToken)
|
||||
=> RequireSession(tenantId).JoinAsync(username, cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
@@ -122,7 +146,10 @@ public sealed class SessionFarm
|
||||
/// <param name="tenantId">Id тенанта.</param>
|
||||
/// <param name="dialogId">Подписанный id диалога.</param>
|
||||
/// <param name="cancellationToken">Отмена операции.</param>
|
||||
public Task LeaveAsync(string tenantId, string dialogId, CancellationToken cancellationToken)
|
||||
public Task LeaveAsync(
|
||||
string tenantId,
|
||||
string dialogId,
|
||||
CancellationToken cancellationToken)
|
||||
=> RequireSession(tenantId).LeaveAsync(dialogId, cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
@@ -133,7 +160,12 @@ public sealed class SessionFarm
|
||||
/// <param name="apiHash">api_hash приложения.</param>
|
||||
/// <param name="phone">Номер телефона.</param>
|
||||
/// <param name="cancellationToken">Отмена операции.</param>
|
||||
public Task<TenantSessionSnapshot> StartPhoneAsync(string tenantId, int apiId, string apiHash, string phone, CancellationToken cancellationToken)
|
||||
public Task<TenantSessionSnapshot> StartPhoneAsync(
|
||||
string tenantId,
|
||||
int apiId,
|
||||
string apiHash,
|
||||
string phone,
|
||||
CancellationToken cancellationToken)
|
||||
=> GetOrCreate(tenantId).StartPhoneAsync(apiId, apiHash, phone, cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
@@ -143,7 +175,11 @@ public sealed class SessionFarm
|
||||
/// <param name="apiId">api_id приложения.</param>
|
||||
/// <param name="apiHash">api_hash приложения.</param>
|
||||
/// <param name="cancellationToken">Отмена операции.</param>
|
||||
public Task<TenantSessionSnapshot> StartQrAsync(string tenantId, int apiId, string apiHash, CancellationToken cancellationToken)
|
||||
public Task<TenantSessionSnapshot> StartQrAsync(
|
||||
string tenantId,
|
||||
int apiId,
|
||||
string apiHash,
|
||||
CancellationToken cancellationToken)
|
||||
=> GetOrCreate(tenantId).StartQrAsync(apiId, apiHash, cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
@@ -152,7 +188,10 @@ public sealed class SessionFarm
|
||||
/// <param name="tenantId">Id тенанта.</param>
|
||||
/// <param name="code">Код.</param>
|
||||
/// <param name="cancellationToken">Отмена операции.</param>
|
||||
public Task<TenantSessionSnapshot> SendCodeAsync(string tenantId, string code, CancellationToken cancellationToken)
|
||||
public Task<TenantSessionSnapshot> SendCodeAsync(
|
||||
string tenantId,
|
||||
string code,
|
||||
CancellationToken cancellationToken)
|
||||
=> RequireSession(tenantId).SendCodeAsync(code, cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
@@ -161,7 +200,10 @@ public sealed class SessionFarm
|
||||
/// <param name="tenantId">Id тенанта.</param>
|
||||
/// <param name="password">Пароль.</param>
|
||||
/// <param name="cancellationToken">Отмена операции.</param>
|
||||
public Task<TenantSessionSnapshot> SendPasswordAsync(string tenantId, string password, CancellationToken cancellationToken)
|
||||
public Task<TenantSessionSnapshot> SendPasswordAsync(
|
||||
string tenantId,
|
||||
string password,
|
||||
CancellationToken cancellationToken)
|
||||
=> RequireSession(tenantId).SendPasswordAsync(password, cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -32,7 +32,10 @@ public sealed class SessionStore
|
||||
/// <param name="options">Опции хранения сессий (каталог, ключ шифрования).</param>
|
||||
/// <param name="cipher">AES-GCM-обёртка файлов сессий.</param>
|
||||
/// <param name="logger">Логгер.</param>
|
||||
public SessionStore(TgOptions options, SessionFileCipher cipher, ILogger<SessionStore> logger)
|
||||
public SessionStore(
|
||||
TgOptions options,
|
||||
SessionFileCipher cipher,
|
||||
ILogger<SessionStore> logger)
|
||||
{
|
||||
_sessionsDirectory = options.SessionsDirectory;
|
||||
_cipher = cipher;
|
||||
@@ -101,7 +104,10 @@ public sealed class SessionStore
|
||||
/// <param name="tenantId">Id тенанта.</param>
|
||||
/// <param name="session">Открытое содержимое сессии для шифрования at-rest.</param>
|
||||
/// <param name="cancellationToken">Отмена операции.</param>
|
||||
public async Task SaveAsync(string tenantId, StoredSession session, CancellationToken cancellationToken = default)
|
||||
public async Task SaveAsync(
|
||||
string tenantId,
|
||||
StoredSession session,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
string filePath = PathFor(tenantId);
|
||||
byte[] plainBytes = JsonSerializer.SerializeToUtf8Bytes(session);
|
||||
|
||||
@@ -90,7 +90,11 @@ public sealed class TenantSession : IAsyncDisposable
|
||||
/// <param name="cancellationToken">Отмена операции.</param>
|
||||
/// <returns>Снимок состояния после операции (фаза "code").</returns>
|
||||
/// <exception cref="SessionException">Нет ключей (INVALID_ARGUMENT) / ошибки Telegram.</exception>
|
||||
public async Task<TenantSessionSnapshot> StartPhoneAsync(int apiId, string apiHash, string phone, CancellationToken cancellationToken)
|
||||
public async Task<TenantSessionSnapshot> StartPhoneAsync(
|
||||
int apiId,
|
||||
string apiHash,
|
||||
string phone,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
await _gate.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||
try
|
||||
@@ -148,7 +152,10 @@ public sealed class TenantSession : IAsyncDisposable
|
||||
/// <param name="cancellationToken">Отмена операции.</param>
|
||||
/// <returns>Снимок состояния: Qr с qrUrl или Ready (авторизация уже была).</returns>
|
||||
/// <exception cref="SessionException">Нет ключей (INVALID_ARGUMENT) / ошибки Telegram до первого URL.</exception>
|
||||
public async Task<TenantSessionSnapshot> StartQrAsync(int apiId, string apiHash, CancellationToken cancellationToken)
|
||||
public async Task<TenantSessionSnapshot> StartQrAsync(
|
||||
int apiId,
|
||||
string apiHash,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
await _gate.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||
try
|
||||
@@ -410,7 +417,10 @@ public sealed class TenantSession : IAsyncDisposable
|
||||
/// <param name="limit">Сколько последних сообщений запросить.</param>
|
||||
/// <param name="cancellationToken">Отмена операции.</param>
|
||||
/// <returns>Сообщения диалога (от новых к старым, непустые тексты).</returns>
|
||||
public async Task<IReadOnlyList<TelegramMessage>> GetMessagesAsync(string dialogId, int limit, CancellationToken cancellationToken)
|
||||
public async Task<IReadOnlyList<TelegramMessage>> GetMessagesAsync(
|
||||
string dialogId,
|
||||
int limit,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
await _gate.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||
try
|
||||
@@ -452,7 +462,10 @@ public sealed class TenantSession : IAsyncDisposable
|
||||
/// <param name="limit">Верхняя граница результата.</param>
|
||||
/// <param name="cancellationToken">Отмена операции.</param>
|
||||
/// <returns>Найденные источники (нейтральный вид; личные чаты отсеивает ядро, Ruling 10).</returns>
|
||||
public async Task<IReadOnlyList<TelegramDialog>> SearchAsync(string query, int limit, CancellationToken cancellationToken)
|
||||
public async Task<IReadOnlyList<TelegramDialog>> SearchAsync(
|
||||
string query,
|
||||
int limit,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
await _gate.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||
try
|
||||
@@ -493,7 +506,10 @@ public sealed class TenantSession : IAsyncDisposable
|
||||
/// <param name="limit">Размер выборки (limit ≤ 0 — пусто без сети).</param>
|
||||
/// <param name="cancellationToken">Отмена операции.</param>
|
||||
/// <returns>Результат чтения (ok/messages либо no_history).</returns>
|
||||
public async Task<DiscoveryReadResult> ReadForEvalAsync(string dialogId, int limit, CancellationToken cancellationToken)
|
||||
public async Task<DiscoveryReadResult> ReadForEvalAsync(
|
||||
string dialogId,
|
||||
int limit,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
await _gate.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||
try
|
||||
@@ -812,7 +828,10 @@ public sealed class TenantSession : IAsyncDisposable
|
||||
// apiId: api_id приложения.
|
||||
// apiHash: api_hash приложения.
|
||||
// cancellationToken: Отмена операции.
|
||||
private async Task EnsureClientAsync(int apiId, string apiHash, CancellationToken cancellationToken)
|
||||
private async Task EnsureClientAsync(
|
||||
int apiId,
|
||||
string apiHash,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
if (_client is not null && _clientApiId == apiId && _clientApiHash == apiHash)
|
||||
{
|
||||
@@ -988,7 +1007,10 @@ public sealed class TenantSession : IAsyncDisposable
|
||||
// firstUrlTcs: TCS первого URL.
|
||||
// cancellationToken: Отмена операции.
|
||||
// Возвращает: Первый URL либо null (задача завершилась без URL).
|
||||
private static async Task<string?> WaitForFirstQrUrlAsync(Task qrTask, TaskCompletionSource<string?> firstUrlTcs, CancellationToken cancellationToken)
|
||||
private static async Task<string?> WaitForFirstQrUrlAsync(
|
||||
Task qrTask,
|
||||
TaskCompletionSource<string?> firstUrlTcs,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
Task<string?> urlTask = firstUrlTcs.Task;
|
||||
Task completed = await Task.WhenAny(urlTask, qrTask).WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
@@ -12,6 +12,9 @@ namespace Deal.Telegram.Telegram;
|
||||
public sealed class ClientFactory : ITelegramClientFactory
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public ISessionClient Create(int apiId, string apiHash, byte[]? storedSession)
|
||||
public ISessionClient Create(
|
||||
int apiId,
|
||||
string apiHash,
|
||||
byte[]? storedSession)
|
||||
=> new WTelegramSessionClient(apiId, apiHash, storedSession);
|
||||
}
|
||||
|
||||
@@ -18,7 +18,12 @@ public sealed record DiscoveryMessage
|
||||
/// <param name="dateMs">Время сообщения, epoch-ms.</param>
|
||||
/// <param name="topicId">Id темы форума (для обычных источников пуст).</param>
|
||||
/// <param name="topicTitle">Название темы форума (для обычных источников пусто).</param>
|
||||
public DiscoveryMessage(long id, string text, long dateMs, long? topicId, string? topicTitle)
|
||||
public DiscoveryMessage(
|
||||
long id,
|
||||
string text,
|
||||
long dateMs,
|
||||
long? topicId,
|
||||
string? topicTitle)
|
||||
{
|
||||
Id = id;
|
||||
Text = text;
|
||||
|
||||
@@ -25,7 +25,10 @@ public sealed record DiscoveryReadResult
|
||||
/// <param name="ok">True — выборка получена; false — история недоступна.</param>
|
||||
/// <param name="error">Код причины при ok=false ("no_history"); иначе null.</param>
|
||||
/// <param name="messages">Сообщения выборки (форумы — по темам, topic_id/topic_title заполнены).</param>
|
||||
public DiscoveryReadResult(bool ok, string? error, IReadOnlyList<DiscoveryMessage> messages)
|
||||
public DiscoveryReadResult(
|
||||
bool ok,
|
||||
string? error,
|
||||
IReadOnlyList<DiscoveryMessage> messages)
|
||||
{
|
||||
Ok = ok;
|
||||
Error = error;
|
||||
|
||||
@@ -114,7 +114,10 @@ public interface ISessionClient : IAsyncDisposable
|
||||
/// <param name="limit">Сколько последних сообщений запросить.</param>
|
||||
/// <param name="cancellationToken">Отмена операции.</param>
|
||||
/// <returns>Сообщения диалога (с канальными полями для PushMessage).</returns>
|
||||
public Task<IReadOnlyList<TelegramMessage>> GetMessagesAsync(string dialogId, int limit, CancellationToken cancellationToken);
|
||||
public Task<IReadOnlyList<TelegramMessage>> GetMessagesAsync(
|
||||
string dialogId,
|
||||
int limit,
|
||||
CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Помечает весь диалог прочитанным (send_read_acknowledge прототипа L277/L383/L454/L609).
|
||||
@@ -145,7 +148,10 @@ public interface ISessionClient : IAsyncDisposable
|
||||
/// <param name="limit">Верхняя граница результата (прототип: default 30).</param>
|
||||
/// <param name="cancellationToken">Отмена операции.</param>
|
||||
/// <returns>Найденные источники в нейтральном виде (каналы/группы/личные).</returns>
|
||||
public Task<IReadOnlyList<TelegramDialog>> SearchAsync(string query, int limit, CancellationToken cancellationToken);
|
||||
public Task<IReadOnlyList<TelegramDialog>> SearchAsync(
|
||||
string query,
|
||||
int limit,
|
||||
CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Инфо об источнике для оценки кандидата (discovery_info L666–716): имя/username/kind + участники
|
||||
@@ -169,7 +175,10 @@ public interface ISessionClient : IAsyncDisposable
|
||||
/// <param name="limit">Размер выборки (прототип: limit сообщений/тем; limit ≤ 0 — пусто без сети).</param>
|
||||
/// <param name="cancellationToken">Отмена операции.</param>
|
||||
/// <returns>Результат чтения выборки (ok + сообщения либо no_history).</returns>
|
||||
public Task<DiscoveryReadResult> ReadForEvalAsync(string dialogId, int limit, CancellationToken cancellationToken);
|
||||
public Task<DiscoveryReadResult> ReadForEvalAsync(
|
||||
string dialogId,
|
||||
int limit,
|
||||
CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Вступить в канал/группу по username (discovery_join L818–839; ручной join вне квот — паузу перед
|
||||
|
||||
@@ -19,5 +19,8 @@ public interface ITelegramClientFactory
|
||||
/// либо null — новая сессия (нет файла или ключи приложения сменились).
|
||||
/// </param>
|
||||
/// <returns>Клиент, готовый к ConnectAsync/логину.</returns>
|
||||
public ISessionClient Create(int apiId, string apiHash, byte[]? storedSession);
|
||||
public ISessionClient Create(
|
||||
int apiId,
|
||||
string apiHash,
|
||||
byte[]? storedSession);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,13 @@ public sealed record TelegramDialog
|
||||
/// <param name="kind">Тип канона: channel|group|forum|chat (шапка telegram.proto).</param>
|
||||
/// <param name="unreadCount">Число непрочитанных сообщений (для realtime_sweep).</param>
|
||||
/// <param name="topMessageId">Id самого свежего сообщения диалога (для read-ack).</param>
|
||||
public TelegramDialog(string id, string name, string username, string kind, int unreadCount, int topMessageId)
|
||||
public TelegramDialog(
|
||||
string id,
|
||||
string name,
|
||||
string username,
|
||||
string kind,
|
||||
int unreadCount,
|
||||
int topMessageId)
|
||||
{
|
||||
Id = id;
|
||||
Name = name;
|
||||
|
||||
@@ -19,7 +19,13 @@ public sealed record TelegramMessage
|
||||
/// <param name="dateMs">Время сообщения, epoch-ms.</param>
|
||||
/// <param name="dialogName">Имя диалога (title/first_name) для PushMessage.channel_name.</param>
|
||||
/// <param name="dialogHandle">Username диалога для PushMessage.channel_handle.</param>
|
||||
public TelegramMessage(string dialogId, int id, string text, long dateMs, string dialogName, string dialogHandle)
|
||||
public TelegramMessage(
|
||||
string dialogId,
|
||||
int id,
|
||||
string text,
|
||||
long dateMs,
|
||||
string dialogName,
|
||||
string dialogHandle)
|
||||
{
|
||||
DialogId = dialogId;
|
||||
Id = id;
|
||||
|
||||
@@ -19,7 +19,13 @@ public sealed record TelegramSourceInfo
|
||||
/// <param name="kind">Тип канона контракта: channel|group|forum|chat (пусто — не определён).</param>
|
||||
/// <param name="participants">Число участников (full_chat); null — определить не удалось.</param>
|
||||
/// <param name="isForum">True — мегагруппа с темами (форум; core трактует kind как forum).</param>
|
||||
public TelegramSourceInfo(string id, string name, string username, string kind, int? participants, bool isForum)
|
||||
public TelegramSourceInfo(
|
||||
string id,
|
||||
string name,
|
||||
string username,
|
||||
string kind,
|
||||
int? participants,
|
||||
bool isForum)
|
||||
{
|
||||
Id = id;
|
||||
Name = name;
|
||||
|
||||
@@ -32,7 +32,10 @@ public static class TlMessageMapper
|
||||
/// <param name="dialog">Диалог из ответа getDialogs.</param>
|
||||
/// <param name="chats">Сущности чатов контейнера (по raw id).</param>
|
||||
/// <param name="users">Сущности пользователей контейнера (по raw id).</param>
|
||||
public static TelegramDialog? ToDialog(DialogBase dialog, IReadOnlyDictionary<long, ChatBase> chats, IReadOnlyDictionary<long, User> users)
|
||||
public static TelegramDialog? ToDialog(
|
||||
DialogBase dialog,
|
||||
IReadOnlyDictionary<long, ChatBase> chats,
|
||||
IReadOnlyDictionary<long, User> users)
|
||||
{
|
||||
if (dialog.Peer is null)
|
||||
{
|
||||
@@ -53,7 +56,10 @@ public static class TlMessageMapper
|
||||
/// <param name="message">Сообщение (MessageBase).</param>
|
||||
/// <param name="chats">Сущности чатов контейнера.</param>
|
||||
/// <param name="users">Сущности пользователей контейнера.</param>
|
||||
public static TelegramMessage? ToMessage(MessageBase message, IReadOnlyDictionary<long, ChatBase> chats, IReadOnlyDictionary<long, User> users)
|
||||
public static TelegramMessage? ToMessage(
|
||||
MessageBase message,
|
||||
IReadOnlyDictionary<long, ChatBase> chats,
|
||||
IReadOnlyDictionary<long, User> users)
|
||||
{
|
||||
if (message is not Message textMessage
|
||||
|| string.IsNullOrWhiteSpace(textMessage.message)
|
||||
@@ -103,7 +109,11 @@ public static class TlMessageMapper
|
||||
/// <param name="topicId">Id темы форума (для обычных источников null).</param>
|
||||
/// <param name="topicTitle">Название темы форума (для обычных источников null).</param>
|
||||
/// <param name="now">Текущее время (фолбэк даты сообщения без времени, как python `now`).</param>
|
||||
public static DiscoveryMessage? ToEvalMessage(MessageBase message, long? topicId, string? topicTitle, DateTimeOffset now)
|
||||
public static DiscoveryMessage? ToEvalMessage(
|
||||
MessageBase message,
|
||||
long? topicId,
|
||||
string? topicTitle,
|
||||
DateTimeOffset now)
|
||||
{
|
||||
if (message is not Message textMessage
|
||||
|| string.IsNullOrWhiteSpace(textMessage.message))
|
||||
@@ -136,7 +146,10 @@ public static class TlMessageMapper
|
||||
// signedId: Подписанный id диалога (фолбэк имени).
|
||||
// chat: Сущность чата/канала (или null).
|
||||
// user: Сущность пользователя (или null).
|
||||
private static (string Name, string Handle, string Kind) DescribePeer(string signedId, ChatBase? chat, UserBase? user)
|
||||
private static (string Name, string Handle, string Kind) DescribePeer(
|
||||
string signedId,
|
||||
ChatBase? chat,
|
||||
UserBase? user)
|
||||
{
|
||||
if (chat is not null)
|
||||
{
|
||||
|
||||
@@ -73,7 +73,10 @@ public sealed class WTelegramSessionClient : ISessionClient
|
||||
/// <param name="apiId">api_id приложения Telegram.</param>
|
||||
/// <param name="apiHash">api_hash приложения Telegram (же ключ внутреннего шифрования сессии).</param>
|
||||
/// <param name="storedSession">Сохранённые байты сессии (null — новая сессия).</param>
|
||||
public WTelegramSessionClient(int apiId, string apiHash, byte[]? storedSession)
|
||||
public WTelegramSessionClient(
|
||||
int apiId,
|
||||
string apiHash,
|
||||
byte[]? storedSession)
|
||||
{
|
||||
_apiId = apiId;
|
||||
_apiHash = apiHash;
|
||||
@@ -257,7 +260,10 @@ public sealed class WTelegramSessionClient : ISessionClient
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IReadOnlyList<TelegramMessage>> GetMessagesAsync(string dialogId, int limit, CancellationToken cancellationToken)
|
||||
public async Task<IReadOnlyList<TelegramMessage>> GetMessagesAsync(
|
||||
string dialogId,
|
||||
int limit,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
InputPeer peer = await ResolvePeerAsync(dialogId, cancellationToken).ConfigureAwait(false);
|
||||
Messages_MessagesBase result = await RunTlCallAsync(() => _client.Messages_GetHistory(peer, limit: limit), cancellationToken).ConfigureAwait(false);
|
||||
@@ -289,7 +295,10 @@ public sealed class WTelegramSessionClient : ISessionClient
|
||||
// --- Discovery (план Task 11; discovery_search/info/read/join/leave L622–873; Ruling 3/7) ---
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IReadOnlyList<TelegramDialog>> SearchAsync(string query, int limit, CancellationToken cancellationToken)
|
||||
public async Task<IReadOnlyList<TelegramDialog>> SearchAsync(
|
||||
string query,
|
||||
int limit,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
// contacts.SearchRequest(q, limit): результат — сущности chats/users (поиск каналов/групп/людей).
|
||||
Contacts_Found found = await RunTlCallAsync(() => _client.Contacts_Search(query, limit), cancellationToken).ConfigureAwait(false);
|
||||
@@ -347,7 +356,10 @@ public sealed class WTelegramSessionClient : ISessionClient
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<DiscoveryReadResult> ReadForEvalAsync(string dialogId, int limit, CancellationToken cancellationToken)
|
||||
public async Task<DiscoveryReadResult> ReadForEvalAsync(
|
||||
string dialogId,
|
||||
int limit,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
// discovery_read L718–760: limit ≤ 0 — пустой ok без сетевых вызовов (L730–732).
|
||||
if (limit <= 0)
|
||||
@@ -431,7 +443,11 @@ public sealed class WTelegramSessionClient : ISessionClient
|
||||
// rawId: Raw id канала.
|
||||
// unknown: Инфо по умолчанию (сущность недоступна).
|
||||
// cancellationToken: Отмена операции.
|
||||
private async Task<TelegramSourceInfo> GetChannelInfoAsync(string dialogId, long rawId, TelegramSourceInfo unknown, CancellationToken cancellationToken)
|
||||
private async Task<TelegramSourceInfo> GetChannelInfoAsync(
|
||||
string dialogId,
|
||||
long rawId,
|
||||
TelegramSourceInfo unknown,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
Channel? cached;
|
||||
lock (_entityCacheGate)
|
||||
@@ -465,7 +481,10 @@ public sealed class WTelegramSessionClient : ISessionClient
|
||||
// dialogId: Подписанный id.
|
||||
// rawId: Raw id канала.
|
||||
// cancellationToken: Отмена операции.
|
||||
private async Task<int?> TryFetchChannelParticipantsAsync(string dialogId, long rawId, CancellationToken cancellationToken)
|
||||
private async Task<int?> TryFetchChannelParticipantsAsync(
|
||||
string dialogId,
|
||||
long rawId,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -485,7 +504,11 @@ public sealed class WTelegramSessionClient : ISessionClient
|
||||
// rawId: Raw id группы (положительный).
|
||||
// unknown: Инфо по умолчанию.
|
||||
// cancellationToken: Отмена операции.
|
||||
private async Task<TelegramSourceInfo> GetChatInfoAsync(string dialogId, long rawId, TelegramSourceInfo unknown, CancellationToken cancellationToken)
|
||||
private async Task<TelegramSourceInfo> GetChatInfoAsync(
|
||||
string dialogId,
|
||||
long rawId,
|
||||
TelegramSourceInfo unknown,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
Chat? cached;
|
||||
lock (_entityCacheGate)
|
||||
@@ -537,7 +560,10 @@ public sealed class WTelegramSessionClient : ISessionClient
|
||||
// dialogId: Подписанный id.
|
||||
// group: Entity группы.
|
||||
// participants: Число участников (null — определить не удалось).
|
||||
private static TelegramSourceInfo DescribeGroup(string dialogId, Chat group, int? participants)
|
||||
private static TelegramSourceInfo DescribeGroup(
|
||||
string dialogId,
|
||||
Chat group,
|
||||
int? participants)
|
||||
=> new(
|
||||
dialogId,
|
||||
DisplayName(dialogId, group),
|
||||
@@ -550,7 +576,10 @@ public sealed class WTelegramSessionClient : ISessionClient
|
||||
// dialogId: Подписанный id.
|
||||
// rawId: Raw id пользователя.
|
||||
// unknown: Инфо по умолчанию (сущность неизвестна — как entity-not-found прототипа).
|
||||
private TelegramSourceInfo GetUserInfo(string dialogId, long rawId, TelegramSourceInfo unknown)
|
||||
private TelegramSourceInfo GetUserInfo(
|
||||
string dialogId,
|
||||
long rawId,
|
||||
TelegramSourceInfo unknown)
|
||||
{
|
||||
User? user;
|
||||
lock (_entityCacheGate)
|
||||
@@ -578,7 +607,10 @@ public sealed class WTelegramSessionClient : ISessionClient
|
||||
// limit: Размер выборки (раскладывается по темам).
|
||||
// cancellationToken: Отмена операции.
|
||||
// Возвращает: Плоский список сообщений тем (пуст — темы не прочитались; фолбэк на ленту делает вызывающий).
|
||||
private async Task<IReadOnlyList<DiscoveryMessage>> ReadForumTopicsAsync(InputPeer peer, int limit, CancellationToken cancellationToken)
|
||||
private async Task<IReadOnlyList<DiscoveryMessage>> ReadForumTopicsAsync(
|
||||
InputPeer peer,
|
||||
int limit,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var outMessages = new List<DiscoveryMessage>();
|
||||
try
|
||||
@@ -659,7 +691,10 @@ public sealed class WTelegramSessionClient : ISessionClient
|
||||
// dialogId: Подписанный id.
|
||||
// channel: Entity канала из ответа полного чата.
|
||||
// participants: Число участников (full_chat) либо null.
|
||||
private static TelegramSourceInfo DescribeChannel(string dialogId, Channel channel, int? participants)
|
||||
private static TelegramSourceInfo DescribeChannel(
|
||||
string dialogId,
|
||||
Channel channel,
|
||||
int? participants)
|
||||
=> new(
|
||||
dialogId,
|
||||
DisplayName(dialogId, channel),
|
||||
@@ -952,7 +987,10 @@ public sealed class WTelegramSessionClient : ISessionClient
|
||||
// dialogId: Подписанный id канала («-100…»).
|
||||
// rawId: Raw id канала.
|
||||
// cancellationToken: Отмена операции.
|
||||
private async Task<InputChannel> ResolveInputChannelAsync(string dialogId, long rawId, CancellationToken cancellationToken)
|
||||
private async Task<InputChannel> ResolveInputChannelAsync(
|
||||
string dialogId,
|
||||
long rawId,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
lock (_entityCacheGate)
|
||||
{
|
||||
@@ -976,7 +1014,10 @@ public sealed class WTelegramSessionClient : ISessionClient
|
||||
// isChannel: Признак канала («-100…»).
|
||||
// isUser: Признак личного чата («+…»).
|
||||
// rawId: Raw id (канала/пользователя).
|
||||
private bool TryImportPeerFromCollector(bool isChannel, bool isUser, long rawId)
|
||||
private bool TryImportPeerFromCollector(
|
||||
bool isChannel,
|
||||
bool isUser,
|
||||
long rawId)
|
||||
{
|
||||
if (!isChannel && !isUser)
|
||||
{
|
||||
@@ -1022,7 +1063,11 @@ public sealed class WTelegramSessionClient : ISessionClient
|
||||
// isChat: Признак базовой группы («-…»).
|
||||
// isUser: Признак личного чата («+…»).
|
||||
// rawId: Raw id (канала/группы/пользователя).
|
||||
private InputPeer? BuildPeer(bool isChannel, bool isChat, bool isUser, long rawId)
|
||||
private InputPeer? BuildPeer(
|
||||
bool isChannel,
|
||||
bool isChat,
|
||||
bool isUser,
|
||||
long rawId)
|
||||
{
|
||||
if (isChat)
|
||||
{
|
||||
@@ -1050,7 +1095,12 @@ public sealed class WTelegramSessionClient : ISessionClient
|
||||
// isChat: True — базовая группа.
|
||||
// isUser: True — личный чат.
|
||||
// rawId: Raw id без префикса.
|
||||
private static bool TryParseSignedId(string dialogId, out bool isChannel, out bool isChat, out bool isUser, out long rawId)
|
||||
private static bool TryParseSignedId(
|
||||
string dialogId,
|
||||
out bool isChannel,
|
||||
out bool isChat,
|
||||
out bool isUser,
|
||||
out long rawId)
|
||||
{
|
||||
isChannel = false;
|
||||
isChat = false;
|
||||
|
||||
@@ -473,7 +473,10 @@ public sealed class TelegramServiceImpl : TelegramService.TelegramServiceBase
|
||||
// tenantId: Id тенанта.
|
||||
// entries: Актуальный каталог диалогов.
|
||||
// cancellationToken: Отмена операции.
|
||||
private async Task SyncCatalogSilentlyAsync(string tenantId, IReadOnlyList<DialogEntry> entries, CancellationToken cancellationToken)
|
||||
private async Task SyncCatalogSilentlyAsync(
|
||||
string tenantId,
|
||||
IReadOnlyList<DialogEntry> entries,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user