public static class TelegramBotClientPollingExtensions { public static void StartReceiving( this ITelegramBotClient client, Func<Update, Task> updateHandler, Func<Exception, Task> exceptionHandler, // ApiRequestException, GeneralException, AS WELL AS exceptions from updateHandler - in that case stop receiving UpdateType[]? allowedUpdates = null, CancellationToken cancellationToken = default) { if (exceptionHandler == null) throw new ArgumentNullException(nameof(exceptionHandler)); Task.Run(async () => { try { await ReceiveAsync(client, updateHandler, exceptionHandler, allowedUpdates, cancellationToken); } catch (Exception ex) { await exceptionHandler(ex); } }); } public static async Task ReceiveAsync( this ITelegramBotClient client, Func<Update, Task> updateHandler, Func<Exception, Task>? exceptionHandler = null, // ApiRequestException, GeneralException UpdateType[]? allowedUpdates = null, CancellationToken cancellationToken = default) { int messageOffset = 0; var emptyUpdates = new Update[0]; while (!cancellationToken.IsCancellationRequested) { int timeout = (int)client.Timeout.TotalSeconds; var updates = emptyUpdates; try { updates = await client.GetUpdatesAsync( messageOffset, timeout: timeout, allowedUpdates: allowedUpdates, cancellationToken: cancellationToken ).ConfigureAwait(false); } catch (OperationCanceledException) { // Ignore } catch (Exception ex) { if (exceptionHandler != null) { await exceptionHandler(ex).ConfigureAwait(false); } } foreach (var update in updates) { await updateHandler(update).ConfigureAwait(false); messageOffset = update.Id + 1; } } } } #if NETCOREAPP3_0 public static class TBD_YieldExtensions { public static async IAsyncEnumerable<Update> YieldUpdatesAsync( this ITelegramBotClient client, Func<Exception, Task>? exceptionHandler = null, // ApiRequestException, GeneralException UpdateType[]? allowedUpdates = null, CancellationToken cancellationToken = default) { int messageOffset = 0; var emptyUpdates = new Update[0]; while (!cancellationToken.IsCancellationRequested) { int timeout = (int)client.Timeout.TotalSeconds; var updates = emptyUpdates; try { updates = await client.GetUpdatesAsync( messageOffset, timeout: timeout, allowedUpdates: allowedUpdates, cancellationToken: cancellationToken ).ConfigureAwait(false); } catch (OperationCanceledException) { // Ignore } catch (Exception ex) { if (exceptionHandler != null) { await exceptionHandler(ex).ConfigureAwait(false); } } foreach (var update in updates) { yield return update; messageOffset = update.Id + 1; } } } public static async IAsyncEnumerable<Update> YieldQueuedUpdatesAsync( this ITelegramBotClient client, Func<Exception, Task>? exceptionHandler = null, // ApiRequestException, GeneralException UpdateType[]? allowedUpdates = null, CancellationToken cancellationToken = default) { yield return new Update(); } } #endif