public static void StartReceiving(
        this ITelegramBotClient botClient,
        IUpdateHandler updateHandler,
        ReceiverOptions?receiverOptions     = default,
        CancellationToken cancellationToken = default)
    {
        if (botClient is null)
        {
            throw new ArgumentNullException(nameof(botClient));
        }
        if (updateHandler is null)
        {
            throw new ArgumentNullException(nameof(updateHandler));
        }

        // ReSharper disable once MethodSupportsCancellation
        Task.Run(async() =>
        {
            try
            {
                await ReceiveAsync(
                    botClient: botClient,
                    updateHandler: updateHandler,
                    receiverOptions: receiverOptions,
                    cancellationToken: cancellationToken
                    );
            }
            catch (OperationCanceledException)
            {
                // ignored
            }
            catch (Exception ex)
            {
                try
                {
                    await updateHandler.HandleErrorAsync(
                        botClient: botClient,
                        exception: ex,
                        cancellationToken: cancellationToken
                        );
                }
                catch (OperationCanceledException)
                {
                    // ignored
                }
            }
        });
    }
    /// <inheritdoc />
    public async Task ReceiveAsync(
        IUpdateHandler updateHandler,
        CancellationToken cancellationToken = default)
    {
        if (updateHandler is null)
        {
            throw new ArgumentNullException(nameof(updateHandler));
        }

        var allowedUpdates = _receiverOptions?.AllowedUpdates;
        var limit          = _receiverOptions?.Limit ?? default;
        var messageOffset  = _receiverOptions?.Offset ?? 0;
        var emptyUpdates   = EmptyUpdates;

        if (_receiverOptions?.ThrowPendingUpdates is true)
        {
            try
            {
                messageOffset = await _botClient.ThrowOutPendingUpdatesAsync(
                    cancellationToken : cancellationToken
                    );
            }
            catch (OperationCanceledException)
            {
                // ignored
            }
        }

        while (!cancellationToken.IsCancellationRequested)
        {
            var timeout = (int)_botClient.Timeout.TotalSeconds;
            var updates = emptyUpdates;
            try
            {
                var request = new GetUpdatesRequest
                {
                    Limit          = limit,
                    Offset         = messageOffset,
                    Timeout        = timeout,
                    AllowedUpdates = allowedUpdates,
                };
                updates = await _botClient.MakeRequestAsync(
                    request : request,
                    cancellationToken :
                    cancellationToken
                    ).ConfigureAwait(false);
            }
            catch (OperationCanceledException)
            {
                // Ignore
            }
            catch (Exception exception)
            {
                try
                {
                    await updateHandler.HandleErrorAsync(
                        botClient : _botClient,
                        exception : exception,
                        cancellationToken : cancellationToken
                        ).ConfigureAwait(false);
                }
                catch (OperationCanceledException)
                {
                    // ignored
                }
            }

            foreach (var update in updates)
            {
                try
                {
                    await updateHandler.HandleUpdateAsync(
                        botClient : _botClient,
                        update : update,
                        cancellationToken : cancellationToken
                        ).ConfigureAwait(false);

                    messageOffset = update.Id + 1;
                }
                catch (OperationCanceledException)
                {
                    // ignored
                }
            }
        }
    }